在上一节中,当要爬取某个网页时,会输入“正在爬取”的提示信息,等网页的内容爬取下来后会休眠1s,这样做的目的是降低了请求的频率,以免 IP 被禁。
当整个网页爬取下来以后,需要调用 parse_page() 方法解析网页。这里依然使用 lxml 库进行解析,所以在前面使用 from lxml import etree 导入库。
一、解析网页
parse_page() 方法
def parse_page(self, html):
html_obj = etree.HTML(html)
# 模糊查询
node_list = text.xpath("//div[recommend-article(@id, 'qiushi_tag')]")
for node in node_list:
# 用户名
username = node.xpath("./li").xpath('./div')[0].xpath('./div')[0].xpath('.//span').text
# 图片链接
image = node.xpath("./li").xpath(".//@src")
# 取出标题
title = node.xpath("./li").xpath('./div')[0].xpath("./a").text
# 点赞数
like = node.xpath("./li").xpath('./div')[0].xpath('./div')[0].xpath('./div')[0].xpath(".//span")[0].text
# 评论数
comments = node.xpath("./li").xpath('./div')[0].xpath('./div')[0].xpath('./div')[0].xpath(".//span")[3].text
items = {
"username": username,
"title": title,
"image": image,
"zan": like,
"comments": comments
}
self.count += 1
self.data_queue.put(items)
按照 XPath 规则依次筛选出用户名、图片链接、段子标题、点赞数、评论数,将这些信息以字典的形式进行保存,并放在上述创建的数据队列中。
二、使用协程完成采集和解析网页内容
start_work() 方法
def start_work(self):
job_list = []
for page in range(1, 14):
# 创建一个协程任务对象
url = self.base_url + str(page) + "/"
job = gevent.spawn(self.send_request, url)
# 保存所有的协程任务
job_list.append(job)
# joinall() 接受一个列表,将列表中的所有协程任务添加到任务队列里执行
gevent.joinall(job_list)
local_file = open("duanzi.txt", "wb+")
while not self.data_queue.empty():
content = self.data_queue.get()
result = str(content).encode("utf-8")
local_file.write(result + b"\n")
local_file.close()
print(self.count)