本文以正则表达式和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))
。