基本思路
- 了解豆瓣图书网页结构
- 导入相关模块包gevent、request、BeautifulSoup、csv
- 使用monkey.patch_all()方法变成协作式运行
- 利用request获取网页响应内容
- 利用BeautifulSoup解析网页内容,并提取所需的标签内容
- 创建队列对象,利用队列相应的方法,创建多任务执行
- 保存为CSV文件格式
- 私信小编01即可获取Python学习资料
爬取豆瓣图书
利用多协程和队列,来爬取豆瓣图书Top250(书名,作者,评分)并存储csv 豆瓣图书:https://book.douban.com/top250?start=0
爬虫主程序
import csv
from gevent.queue import Queue
import requests
import time
from bs4 import BeautifulSoup
import gevent
from gevent import monkey
# monkey.patch_all()能把程序变成协作式运行,就是可以帮助程序实现异步,注意需放在最前面
monkey.patch_all()
# 计算开始时间
start_time = time.time()
# 伪装请求头
header = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) '
'Chrome/78.0.3904.108 Safari/537.36'}
url_list = [] # 用于存放URL链接
# 使用for循环生产不同的链接,并存放在url_list
for i in range(0, 250, 25):
link = 'https://book.douban.com/top250?start=' + str(i)
url_list.append(link)
# 创建队列对象,并赋值给work
work = Queue()
# 用put_nowait()函数可以把网址都放进队列里。
for url in url_list:
work.put_nowait(url)
# 创建一个新的csv文件用于存放需要提前的数据
book = open('book_info.csv', 'w', newline='', encoding='utf-8')
# 创建列名
column_title = ['书名', '作者', '评分', '链接']
writer = csv.writer(book)
# 写入字段的列名
writer.writerow(column_title)
# 创建一个新的列表,然后把相应信息存放到列表中
book_info = []
# 构建一个获取书籍信息的函数
def get_info():
# 判断队列是否为空并作为循环的条件
while not work.empty():
# 获取url
url = work.get_nowait()
# 获取网页的响应内容
res = requests.get(url, headers=header)
# 使用BeautifulSoup进行解析提取数据
soup = BeautifulSoup(res.text, 'html.parser')
book_title = soup.find_all('div', class_='pl2')
book_writer = soup.find_all('p', class_="pl")
book_rating_nums = soup.find_all('span', class_="rating_nums")
# 赋予book_info为全局变量
global book_info
for j in range(len(book_title)):
a = book_title[j].a['title'] # 书名
b = book_writer[j].text.strip() # 作者
c = book_rating_nums[j].text.strip() # 评分
d = book_title[j].a['href'] # 书籍链接
# 写入到CSV文件中
writer.writerow([a, b, c, d])
# 添加到book_info列表
book_info.append([a, b, c, d])
# 查看链接、队列大小、网页响应状态
print(url, work.qsize(), res.status_code)
# 创建空任务列表
task_list = []
# 相当于创建3个任务
for k in range(3):
# 用gevent.spawn()函数创建执行crawler()函数的任务
task = gevent.spawn(get_info)
# 往任务列表添加任务
task_list.append(task)
# 用gevent.joinall方法,执行任务列表里的所有任务,就是让爬虫开始爬取网站
gevent.joinall(task_list)
# print(book_info)
# 统计执行结束时间
end = time.time()
print(end - start_time)
# 关闭文件
book.close()
https://book.douban.com/top250?start=0 7 200
https://book.douban.com/top250?start=25 6 200
https://book.douban.com/top250?start=50 5 200
https://book.douban.com/top250?start=125 4 200
https://book.douban.com/top250?start=100 3 200
https://book.douban.com/top250?start=75 2 200
https://book.douban.com/top250?start=150 1 200
https://book.douban.com/top250?start=200 0 200
https://book.douban.com/top250?start=175 0 200
https://book.douban.com/top250?start=225 0 200
2.852992057800293
运行结果
?