声明:无意滋生事端,仅学习分享,如有侵权,将立即删除。
说明:糗事百科段子的爬取,采用了队列和多线程的方式,其中关键点是Queue.task_done()、Queue.join(),保证了线程的有序进行。
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
新版
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
import requests
from lxml import etree
from queue import Queue
from threading import Thread
from multiprocessing.dummy import Pool
import json
import time
class Qsbk(object):
"""
主要类,用来实现主要模型
"""
def __init__(self):
self.headers = {
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36",
}
self.start_url = "https://www.qiushibaike.com/text"
# 实例化三个队列,用来存放内容
# 这时线程是安全的
self.url_queue = Queue()
self.html_queue = Queue()
self.content_queue = Queue()
def get_total_url(self):
"""获取所有页面的url,并返回url_list"""
# 构造url列表,拼接第一个url和second个url
url_list = list()
url_list.append(self.start_url)
second_url = "https://www.qiushibaike.com/text/page/{}/"
for i in range(2, 14):
url = second_url.format(str(i))
url_list.append(url)
# 将url添加到队列中
for url in url_list:
self.url_queue.put(url)
def get_response_html(self):
"""获取响应的html"""
while self.url_queue.not_empty:
# 判断非空,为空的时候结束循环
# 从队列中取出一个url
url = self.url_queue.get()
print("parse url:",url)
# 获取response
response = requests.get(url, headers=self.headers,timeout=1)
# 将response变为字符串
response_str = response.content.decode()
# 将response_str变为etree.HTML对象
html = etree.HTML(response_str)
# 将lxml实例化的html添加到html_queue
self.html_queue.put(html)
"""
表明先前排队的任务已经完成,
由队列使用者在线程中使用。
对于用于获取任务的每个get(),随后对task_done()的调用告诉队列该处理任务完成了
如果join()当前处于阻塞状态,则将在处理完所有项目后恢复。
"""
# task_done的时候,队列计数减一
self.url_queue.task_done()
def get_content(self):