您的位置:首页 > 产品设计 > UI/UE

【爬虫学习1】正则表达式加Requests爬取猫眼电影排行

2017-09-28 16:21 459 查看
学习网易云课堂的网视频的课后总结

http://study.163.com/course/courseMain.htm?courseId=1003735019

-全部代码见于 :https://github.com/EmpGro/Maoyan100

Requests获取网页数据

正则表达式匹配数据
正则表达式学习参看这里

数据格式化

多页面爬取

保存为文件

Requests获取网页数据

运用Requests获得网页

import requests
##获取单个网页数据
def get_one_page(url):
response = requests.get(url)
return response.text

def main():
url = 'http://maoyan.com/board/4'
html = get_one_page(url)
print(html)
if __name__ == '__main__':
main()


加入异常处理和响应信息确认,将get_one_page()函数修改为

from requests.exceptions import RequestException
def get_one_page(url):
try:
response = requests.get(url)
if response.status_code == 200:
return response.text
return None
except RequestException:
return None


运行获得网页数据成功



正则表达式匹配数据

正则表达式学习参看这里

进入猫眼电影网->TOP100榜

按F12打开审查元素工具

观察源代码发现每部影片信息包含在一个dd标签内



展开结构得到如下内容

<dd>
<i class="board-index board-index-1">1</i>
<a href="/films/1203" title="霸王别姬" class="image-link" data-act="boarditem-click" data-val="{movieId:1203}">
<img src="//ms0.meituan.net/mywww/image/loading_2.e3d934bf.png" alt="" class="poster-default" />
<img data-src="http://p1.meituan.net/movie/20803f59291c47e1e116c11963ce019e68711.jpg@160w_220h_1e_1c" alt="霸王别姬" class="board-img" />
</a>
<div class="board-item-main">
<div class="board-item-content">
<div class="movie-item-info">
<p class="name"><a href="/films/1203" title="霸王别姬" data-act="boarditem-click" data-val="{movieId:1203}">霸王别姬</a></p>
<p class="star">
主演:张国荣,张丰毅,巩俐
</p>
<p class="releasetime">上映时间:1993-01-01(中国香港)</p>
</div>
<div class="movie-item-number score-num">
<p class="score"><i class="integer">9.</i><i class="fraction">6</i></p>
</div>
</div>
</div>
</dd>


于是构建正则表达式函数

import re
def parse_one_page(html):
'''进行正则函数匹配'''
pattern = re.compile('<dd>.*?board-index.*?>(\d+)</i>' #排名
+'.*?data-src="(.*?)".*?name"><a' #图片
+'.*?}">(.*?)</a>'  #名字
+'.*?star">\s*(.*?)\s*</p>' #主演
+'.*?releasetime">(.*?)</p'  #上映时间
+'.*?integer">(.*?)</i'  #排名个位
+'.*?fraction">(.*?)</i>.*?</dd>', re.S)  #排名小数点位
items = re.findall(pattern, html)
return items


主函数修改为

def main():
url = 'http://maoyan.com/board/4'
html = get_one_page(url)
print(parse_one_page(html))


获得输出



数据格式化

可以发现正则表达式给出的是元组列表

尝试对数据进行格式化处理

def parse_one_page(html):
'''进行正则函数匹配'''
pattern = re.compile('<dd>.*?board-index.*?>(\d+)</i>' #排名
+'.*?data-src="(.*?)".*?name"><a' #图片
+'.*?}">(.*?)</a>'  #名字
+'.*?star">\s*(.*?)\s*</p>' #主演
+'.*?releasetime">(.*?)</p'  #上映时间
+'.*?integer">(.*?)</i'  #排名个位
+'.*?fraction">(.*?)</i>.*?</dd>', re.S)  #排名小数点位
items = re.findall(pattern, html)
#格式化输出
for item in items:
yield {
'index': item[0],
'image': item[1],
'title': item[2],
'actor': item[3][3:],
'times': item[4][5:15],
'ranks': item[5]+item[6]
}


相应的主函数修改成

def main():
url = 'http://maoyan.com/board/4'
html = get_one_page(url)
for item in parse_one_page(html):
print(item)


运行得到



多页面爬取

下面将数据从1-10扩展到1-100

研究网址发现,从第2页开始网址变为

http://maoyan.com/board/4?offset=10

即第i面为

http://maoyan.com/board/4?offset=10*i i=range(10)

尝试offset=0情况,发现能进入第一页

于是构造并修改函数如下:

def one_page(offset):
url = 'http://maoyan.com/board/4?offset=' + str(offset)
html = get_one_page(url)
for item in parse_one_page(html):
print(item)

def main():
for i in range(10):
one_page(i*10)


获得输出



保存为文件

def write_to_file(content):
with open('result.txt', 'a', encoding='utf-8') as f:
f.write(json.dumps(content, ensure_ascii=False) + '\n')
f.close()
##让json输出中文而非Unicode码
##在open中加入encoding='utf-8'  dumps中加入ensure_ascii=False


one_page函数相应修改

def one_page(offset):
url = 'http://maoyan.com/board/4?offset=' + str(offset)
html = get_one_page(url)
for item in parse_one_page(html):
write_to_file(item)


打开results.txt即看到结果

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息