本文以正则表达式和urllib库完成一个小小的爬虫来爬取网站,这里选择来爬取的网站是豆瓣top250的内容https://movie.douban.com/top250, 并将爬取的内容保存到本地txt文件。
正则表达式urllib2开始之前,要知道这个爬虫的原理是 1, 先”爬”,先抓取页面 2,”取”,提取页面中我们需要的信息 3,将爬取到的信息进行保存
这里用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然后就可以看到我们要爬取的网页代码已经抓取下来了。
接着,提取我们需要的信息
这里我们选择电影名字,评分,评价人数和一句话评论。
我们使用谷歌的开发者工具查看(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))。
