想法思路
猫眼TOP100榜单的结构非常简单,如果使用现在已经掌握的知识分分钟就能写完。这里我用了没用过的requests库和正则表达式来完成这个爬虫。不过从电影角度来看,私以为这个榜单不如豆瓣榜单,举个例子,忠犬八公和上帝之城分别排89和90。
Requests库
官方提供了一个requests库的快速上手页面,其实如果熟悉urllib库的话,只要做个简单的对应转换就能很快的上手,毕竟访问的过程其实就那么几步。不过我觉得requests库更人性化一点,而且proxy用起来也更简单,所以我估计以后要经常使用这个库了。
正则表达式
我这里使用的正则式是:
pattern = re.compile(
'.*?board-index.*?>(.*?)'
'.*?![]()
(.*?)'
'.*?class="star">(.*?)'
'.*?class="releasetime">(.*?)'
'.*?class="score">(.*?)(.*?)'
'.*? ', re.S)
这是我比较推荐的写法,逻辑清晰也容易写。简单解释下:
- 关于正则表达式的文档。
-
.*?
这里表示的任意长度的任意字符,()
里就是要抓取的部分,(.*?)
就是会抓取括号包含的所有内容。 - 每一个
''
表示换行,一般一行写一个抓取一个对象,也就是一对()
。所以写的时候一般是每行以.*?
开头,然后写一些要抓取对象两端的内容,之后用(.*?)
把对象抓取出来。 - 其实简单理解一下就能领悟了。
这样的正则的写法其实抓取出来的内容会有一些小瑕疵,但只要通过strip(),或者replace(),或者简单的索引比如[:-1]、[3:]就能很好的处理了。
本代码里,在解析的时候,一开始老是抓不到img的url,后来我发现返回的content的内容和用浏览器审查元素的内容不一样(我不知道为什么?)但要以content的内容为准抓取。这里,如果你写的正则式为'.*?class="borad-img" src="(.*?)"'
, 没关系,你对正则的理解没错,错的是解析器。
其他值得一提的:
- 这里因为抓取对象的数量是一定的,100个,每页10个,同时每个页面的URL也是有规律的,所以我直接用for循环生成了10个URL,抓了十次,注意sleep的使用,以免被当成机器人。
- 在生成json文件时,会有编码的问题,参考我的代码的写法就行。
其他就没什么了,这个项目还是很简单的。
代码
maoyan.py
configure.py请参考拙作:爬取糗事百科的内容和图片并展示。
import requests
import re
import json
import time
from random import choice
import configure
url = "http://maoyan.com/board/4"
header = {'user-agent': choice(configure.FakeUserAgents)}
movielist = []
def OnePageSpider(url = url):
try:
response = requests.get(url, headers=header)
content = None
if response.status_code == requests.codes.ok:
content = response.text
except RequestException as e:
print (e)
return
pattern = re.compile(
'.*?board-index.*?>(.*?)'
'.*?![]()
(.*?)'
'.*?class="star">(.*?)'
'.*?class="releasetime">(.*?)'
'.*?class="score">(.*?)(.*?)'
'.*? ', re.S)
items = pattern.findall(content)
for item in items:
movie = {}
movie['id'] = item[0]
movie['image'] = item[1]
movie['name'] = item[2]
movie['star'] = item[3].strip()[3:] #去除空格和\n符
movie['release_time'] = item[4][5:]
movie['score'] = item[5] + item[6]
movielist.append(movie)
if __name__ == '__main__':
OnePageSpider()
# 这里取巧了,抓取下一页也是可以的。
for i in range(10, 100, 10):
OnePageSpider(url + "?offset={0:d}".format(i))
time.sleep(0.5)
# 这里有个编码问题,像我这么写可以解决
with open('top100.json', 'w', encoding = 'utf-8') as file:
for movie in movielist:
file.write(json.dumps(movie, ensure_ascii = False) + '\n')
输出的json文件部分
{"id": "1", "image": "http://p1.meituan.net/movie/20803f59291c47e1e116c11963ce019e68711.jpg@160w_220h_1e_1c", "name": "霸王别姬", "star": "张国荣,张丰毅,巩俐", "release_time": "1993-01-01(中国香港)", "score": "9.6"}
{"id": "2", "image": "http://p0.meituan.net/movie/__40191813__4767047.jpg@160w_220h_1e_1c", "name": "肖申克的救赎", "star": "蒂姆·罗宾斯,摩根·弗里曼,鲍勃·冈顿", "release_time": "1994-10-14(美国)", "score": "9.5"}
{"id": "3", "image": "http://p0.meituan.net/movie/23/6009725.jpg@160w_220h_1e_1c", "name": "罗马假日", "star": "格利高利·派克,奥黛丽·赫本,埃迪·艾伯特", "release_time": "1953-09-02(美国)", "score": "9.1"}
{"id": "4", "image": "http://p0.meituan.net/movie/fc9d78dd2ce84d20e53b6d1ae2eea4fb1515304.jpg@160w_220h_1e_1c", "name": "这个杀手不太冷", "star": "让·雷诺,加里·奥德曼,娜塔莉·波特曼", "release_time": "1994-09-14(法国)", "score": "9.5"}
{"id": "5", "image": "http://p0.meituan.net/movie/92/8212889.jpg@160w_220h_1e_1c", "name": "教父", "star": "马龙·白兰度,阿尔·帕西诺,詹姆斯·凯恩", "release_time": "1972-03-24(美国)", "score": "9.3"}
{"id": "6", "image": "http://p0.meituan.net/movie/11/324629.jpg@160w_220h_1e_1c", "name": "泰坦尼克号", "star": "莱昂纳多·迪卡普里奥,凯特·温丝莱特,比利·赞恩", "release_time": "1998-04-03", "score": "9.5"}
........
........
{"id": "95", "image": "http://p0.meituan.net/movie/11/391659.jpg@160w_220h_1e_1c", "name": "海洋", "star": "雅克·贝汉,姜文,兰斯洛特·贝汉", "release_time": "2011-08-12", "score": "9.0"}
{"id": "96", "image": "http://p0.meituan.net/movie/f95f056d08fdd3a6ce7a01cb81a0a6f725771.jpg@160w_220h_1e_1c", "name": "黄金三镖客", "star": "克林特·伊斯特伍德,李·范·克里夫,伊莱·瓦拉赫", "release_time": "1966-12-23(意大利)", "score": "8.9"}
{"id": "97", "image": "http://p1.meituan.net/movie/36a893c53a13f9bb934071b86ae3b5c492427.jpg@160w_220h_1e_1c", "name": "爱·回家", "star": "俞承豪,金艺芬,童孝熙", "release_time": "2002-04-05(韩国)", "score": "9.0"}
{"id": "98", "image": "http://p0.meituan.net/movie/52/3420293.jpg@160w_220h_1e_1c", "name": "我爱你", "star": "宋在河,李顺才,尹秀晶", "release_time": "2011-02-17(韩国)", "score": "9.0"}
{"id": "99", "image": "http://p1.meituan.net/movie/__44335138__8470779.jpg@160w_220h_1e_1c", "name": "迁徙的鸟", "star": "雅克·贝汉,菲利普·拉波洛", "release_time": "2001-12-12(法国)", "score": "9.1"}
{"id": "100", "image": "http://p0.meituan.net/movie/5102b3f7261caa09c1c9b1212f09cc1f461902.png@160w_220h_1e_1c", "name": "英雄本色", "star": "狄龙,张国荣,周润发", "release_time": "2017-11-17", "score": "9.2"}