一个Python爬虫的诞生

来源:互联网 发布:淘宝2015交易额多少 编辑:程序博客网 时间:2024/04/29 20:57

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

  • 正则表达式
  • urllib2

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


1,获取页面

这里用urllib2获取页面信息:

import urllib2url = "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 timeimport urllib2import reimport sysreload(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 mypagedef 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 timeimport urllib2import reimport sysreload(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 mypagedef 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))

0 0