一个Python爬虫的诞生

本文以正则表达式和urllib库完成一个小小的爬虫来爬取网站,这里选择来爬取的网站是豆瓣top250的内容https://movie.douban.com/top250, 并将爬取的内容保存到本地txt文件。

  • 正则表达式
  • urllib2

开始之前,要知道这个爬虫的原理是
1, 先”爬”,先抓取页面
2,”取”,提取页面中我们需要的信息
3,将爬取到的信息进行保存


1,获取页面

这里用urllib2获取页面信息:

import urllib2

url = "https://movie.douban.com/top250"
request = urllib2.Request(url)
response = urllib2.urlopen(request)
mypage = response.read().decode("utf-8")
print mypage

然后就可以看到我们要爬取的网页代码已经抓取下来了。

2,提取信息

接着,提取我们需要的信息
这里写图片描述

这里我们选择电影名字,评分,评价人数和一句话评论。

我们使用谷歌的开发者工具查看(F12)
这里写图片描述

用正则表达式来匹配我们需要的信息:

result = re.findall('<div class="info">.*?<span class="title">(.*?)</span>.*?span class="rating_num" property="v:average">(.*?)</span>.*?<span>(.*?)</span>.*?<span class="inq">(.*?)</span>', myhtml, re.S)

关于正则表达式:

1).*?
是一个固定的搭配,.和*代表可以匹配任意无限多个字符,加上?表示使用非贪婪模式进行匹配,也就是我们会尽可能短地做匹配,以后我们还会大量用到
.*? 的搭配。

2)(.?)代表一个分组,在这个正则表达式中我们匹配了五个分组,在后面的遍历item中,item[0]就代表第一个(.?)所指代的内容,item[1]就代表第二个(.*?)所指代的内容,以此类推。

3)re.S 标志代表在匹配时为点任意匹配模式,点 . 也可以代表换行符。

接着我们用函数的形式包装一下信息,并加上计时的功能,将爬取的信息保存到本地

# -*- coding:utf-8 -*-
import time
import urllib2
import re
import sys
reload(sys)
sys.setdefaultencoding("utf-8")

#参数是网址输入,返回一个decode的页面,可直接用于正则表达式找出关键字
def code_page(url):
    request = urllib2.Request(url)
    response = urllib2.urlopen(request)
    mypage = response.read().decode("utf-8")
    return mypage

def get_html():
    load_result = []
    url_top = 'https://movie.douban.com/top250'
    myhtml = code_page(url_top)

    result = re.findall('<div class="info">.*?<span class="title">(.*?)</span>.*?'
                            '<span class="rating_num" property="v:average">(.*?)</span>'
                            '.*?<span>(.*?)</span>.*?<span class="inq">(.*?)</span>', myhtml, re.S)
    for i in result:
        load_result.append(i)
    return load_result

#返回电影名字
def get_name():
    movie_name = []
    load_result = get_html()
    for i in load_result:
        movie_name.append(i[0])
    #print('top %d, movie name : %s, link:%s' % (movie_num,movie_name,movie_html))
    return movie_name
#评分
def get_star():
    movie_star = []
    load_result = get_html()
    for i in load_result:
        movie_star.append(i[1])
    return movie_star

#评论人数
def get_num():
    comment_num = []
    load_result = get_html()
    for i in load_result:
        comment_num.append(i[2])
    return comment_num

#一句话影评
def get_comment():
    comment = []
    load_result = get_html()
    for i in load_result:
        comment.append(i[3])
    return comment

#写入文件
def data_write():
    f = file("豆瓣top250.txt", "w")
    top_num = 1
    for name, star, comment_num, comment in zip(get_name(), get_star(), get_num(), get_comment()):
        f.write('TOP_%d  ' % (top_num))
        f.write(name + ' ' + star + ' ' + comment_num + ' ' + '"' + comment + '"')
        f.write('\n------------------------------------------------------------\n')
        print('第%d 个写入完成!' % (top_num))
        top_num += 1
    print('完成!')
    f.close()

if __name__ == '__main__':
    #计时
    time_start = time.time()
    data_write()
    time_end = time.time()
    print('finished:%d s' % (time_end-time_start))

这里写图片描述

这个页面只提供了前25的电影,我们观察一下剩下网页的URL规则
这里写图片描述

start=25就是从第26名开始的网页,于是:

for i in range(10):
    url_top = 'https://movie.douban.com/top250?start=' + str(i * 25) + '&filter='

完整代码:

# -*- coding:utf-8 -*-
import time
import urllib2
import re
import sys
reload(sys)
sys.setdefaultencoding("utf-8")

#参数是网址输入,返回一个decode的页面,可直接用于正则表达式找出关键字
def code_page(url):
    request = urllib2.Request(url)
    response = urllib2.urlopen(request)
    mypage = response.read().decode("utf-8")
    return mypage

def get_html():
    load_result = []
    for i in range(10):
        url_top = 'https://movie.douban.com/top250?start=' + str(i * 25) + '&filter='
        myhtml = code_page(url_top)

        result = re.findall('<div class="info">.*?<span class="title">(.*?)</span>.*?'
                            '<span class="rating_num" property="v:average">(.*?)</span>'
                            '.*?<span>(.*?)</span>.*?<span class="inq">(.*?)</span>', myhtml, re.S)
        for i in result:
            load_result.append(i)
    return load_result

#返回电影名字
def get_name():
    movie_name = []
    load_result = get_html()
    for i in load_result:
        movie_name.append(i[0])
    #print('top %d, movie name : %s, link:%s' % (movie_num,movie_name,movie_html))
    return movie_name
#评分
def get_star():
    movie_star = []
    load_result = get_html()
    for i in load_result:
        movie_star.append(i[1])
    return movie_star

#评论人数
def get_num():
    comment_num = []
    load_result = get_html()
    for i in load_result:
        comment_num.append(i[2])
    return comment_num

#一句话影评
def get_comment():
    comment = []
    load_result = get_html()
    for i in load_result:
        comment.append(i[3])
    return comment

#写入文件
def data_write():
    f = file("豆瓣top250.txt", "w")
    top_num = 1
    for name, star, comment_num, comment in zip(get_name(), get_star(), get_num(), get_comment()):
        f.write('TOP_%d  ' % (top_num))
        f.write(name + ' ' + star + ' ' + comment_num + ' ' + '"' + comment + '"')
        f.write('\n------------------------------------------------------------\n')
        print('第%d 个写入完成!' % (top_num))
        top_num += 1
    print('完成!')
    f.close()

if __name__ == '__main__':
    #计时
    time_start = time.time()
    data_write()
    time_end = time.time()
    print('finished:%d s' % (time_end-time_start))

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值