CodeArt-编码艺术

Python初上手:多线程爬取豆瓣top250

字数统计: 519阅读时长: 2 min
2019/09/22 Share

一、思路

分析豆瓣Top250页面可得知页面URL规律如下

1
2
3
4
第二页:
https://movie.douban.com/top250?start=25&filter=
第三页:
https://movie.douban.com/top250?start=50&filter=

主要依靠start参数,默认每页25条,所以start是25从0开始到9的倍数 {0,25,50…},filter参数可忽略

那么获取信息的主要思路就是循环拼接url,get获取到页面HTML,解析出需要的数据即可。假如顺序执行,代码很容易实现,用“世界上最好的语言”也能搞定,为何还要用Python呢,要来就来点不一样的,多线程来抓取。那么此处的思路则为:

1.循环拼接页面url

2.根据线程数量配置,新建线程或等待进行中的线程,启动线程进行抓取,解析

3.结束(最后写库还是输出随君意)

二、实现

使用 requests 模块来发起请求

使用 lxml.etree 模块来解析HTML内容

使用 threading 模块来处理多线程

完整代码如下:

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
from lxml import etree
import threading

class Douban(object):
# 基础url
base_url = 'https://movie.douban.com/top250?start='
# 请求头
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36"}
# 最大线程数量>=1
max_thread = 3

"""docstring for Douban"""
def __init__(self):
super(Douban, self).__init__()

#调度
def schedule(self,i):
# 使用动态变量名,动态的配置线程
for x in range(1,self.max_thread+1):
if 't'+str(x) not in dir():
locals()['t'+str(x)] = threading.Thread(target=self.get,name=i)
locals()['t'+str(x)].start()
break

#开始获取
def get(self):
i=threading.current_thread().name
url = self.base_url+str(i)
res = requests.get(url,headers=self.headers)
if res.status_code==200:
self.block(res.text)

def block(self,res):
html = etree.HTML(res)
lis = html.xpath('//ol[@class="grid_view"]/li')
for li in lis:
title=li.xpath('div/div[2]/div/a/span[1]/text()')
info = li.xpath('div/div[2]/div[2]/p/text()')
print(title)
# print(info)


douban = Douban()
for i in range(0,250,25):
douban.schedule(i)
CATALOG
  1. 1. 一、思路
  2. 2. 二、实现