崔庆才老师爬虫的学习笔记。

一、爬取实战

1、目标站点分析

我们需要抓取的目标站点为http://maoyan.com/board/4 ,打开之后便可以查看到榜单信息。排名第一的电影是霸王别姬,页面中显示的有效信息有影片名称、主演、上映时间、上映地区、评分、图片等信息。

将网页滚动到最下方,可以发现有分页的列表,直接点击第2页,观察页面的URL和内容发生了怎样的变化,可以发现页面的URL变成http://maoyan.com/board/4?offset=10 ,比之前的URL多了一个参数,那就是offset=10,而目前显示的结果是排行11~20名的电影,初步推断这是一个偏移量的参数。再点击下一页,发现页面的URL变成了http://maoyan.com/board/4?offset=20 ,参数offset变成了20,而显示的结果是排行21~30的电影。

由此可以总结出规律,offset代表偏移量值,如果偏移量为n,则显示的电影序号就是n+1到n+10,每页显示10个。所以,如果想获取TOP100电影,只需要分开请求10次,而10次的offset参数分别设置为0、10、20、…90即可,这样获取不同的页面之后,再用正则表达式提取出相关信息,就可以得到TOP100的所有电影信息了。

2、流程框架

(1)抓取单页内容: 利用requests请求目标站点得到单个网页的HTML代码,返回结果。

(2)正则表达式分析: 根据HTML代码分析得到电影名称、主演、上映时间、评分、图片链接等信息。

(3)保存至文件: 通过文件的形式将结果保存,每一部电影一个结果一行Json字符串。

(4)开启循环及多线程: 对多项内容遍历,开启多线程提高抓取速度。

3、爬虫实战

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
import requests
import re
import json
from multiprocessing import Pool

headers = {'User-Agent': 'Mozilla/5.0Safari/537.36'} #设定自己的headers

def get_one_page(url):
response = requests.get(url,headers=headers) #添加头部信息,不然会被禁
if response.status_code == 200:
return response.text
return None

def parse_one_page(html):
#匹配过程保证起始符和终止符存在
pattern = re.compile('<dd>.*?board-index.*?>(\d+)</i>.*?data-src="(.*?)".*?name"><a.*?>(.*?)</a>.*?star">(.*?)</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].strip()[3:],
'time':item[4].strip()[5:],
'score':item[5]+item[6]
}

def write_to_file(content):
with open('猫眼电影TOP100.txt','a',encoding='utf-8') as f:
f.write(json.dumps(content,ensure_ascii=False) + '\n')
f.close

def main(offset):
url = 'http://maoyan.com/board/4?offset' + str(offset) #url设置偏移量
html = get_one_page(url)
#print(html)
items = parse_one_page(html)
for item in items:
print(item)
write_to_file(item)

if __name__ == '__main__':
for i in range(10):
main(offset=i * 10)
#pool = Pool() # 使用进程池,提高抓取效率(使用多进程需要屏蔽for循环)
#pool.map(main,[i*10 for i in range(10)])

持续更新…

× 多少都行~
打赏二维码