爬虫——多线程糗事百科案例

来源:互联网 发布:淘宝客招募网站 编辑:程序博客网 时间:2024/06/08 19:05

Queue(队列对象)

Queue是python中的标准库,可以直接import Queue引用;队列是线程间最常用的交换数据的形式

python下多线程的思考

对于资源,加锁是个重要的环节。因为python原生的list,dict等,都是not thread safe的。而Queue,是线程安全的,因此在满足使用条件下,建议使用队列

  1. 初始化: class Queue.Queue(maxsize) FIFO 先进先出

  2. 包中的常用方法:

    • Queue.qsize() 返回队列的大小

    • Queue.empty() 如果队列为空,返回True,反之False

    • Queue.full() 如果队列满了,返回True,反之False

    • Queue.full 与 maxsize 大小对应

    • Queue.get([block[, timeout]])获取队列,timeout等待时间

  3. 创建一个“队列”对象

    • import Queue
    • myqueue = Queue.Queue(maxsize = 10)
  4. 将一个值放入队列中

    • myqueue.put(10)
  5. 将一个值从队列中取出

    • myqueue.get()

多线程示意图

多线程糗事百科案例代码:

# coding=utf-8import requestsfrom lxml import etreefrom queue import Queueimport threadingclass QiuBai:    def __init__(self):        self.temp_url = "https://www.qiushibaike.com/8hr/page/{}/"        self.headers = {            "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36"}        self.url_queue = Queue()  #放url的队列        self.html_str_queue = Queue()  #放响应的队列        self.content_list_queue = Queue() #放提取的数据的队列    def get_url_list(self):  # 获取url列表        for i in range(1,14):            self.url_queue.put(self.temp_url.format(i))    def parse_url(self):  # 发送请求,获取html字符串        while True:            url = self.url_queue.get()            print(url)            r = requests.get(url, headers=self.headers)            self.html_str_queue.put(r.content.decode())            self.url_queue.task_done()    def get_content_list(self):        while True:            html_str = self.html_str_queue.get()            html = etree.HTML(html_str)            div_list = html.xpath("//div[@id='content-left']/div")            content_list = []            for div in div_list:                item = {}                item["author_name"] = div.xpath(".//h2/text()")[0] if len(div.xpath(".//h2/text()")) > 0 else None                item["content"] = div.xpath(".//div[@class='content']/span/text()")                item["img_list"] = div.xpath(".//div[@class='thumb']/a/img/@src")                content_list.append(item)            self.content_list_queue.put(content_list)            self.html_str_queue.task_done()    def save_content_list(self):  # save        while True:            content_list = self.content_list_queue.get()            for content in content_list:                # print(content)                pass            self.content_list_queue.task_done()    def run(self):  # 实现主要逻辑        thread_list = []        # 1.url_list        t_url = threading.Thread(target=self.get_url_list)        thread_list.append(t_url)        # 2.发送请求,获取数据        for i in range(3):            t_parse = threading.Thread(target=self.parse_url)            thread_list.append(t_parse)        # 3.提取数据        for i in range(2):            t_content_list = threading.Thread(target=self.get_content_list)            thread_list.append(t_content_list)        # 4.保存        t_save = threading.Thread(target=self.save_content_list)        thread_list.append(t_save)        for t in thread_list:            t.setDaemon(True) #设置为守护线程,守护线程:这个线程不重要,主线程结束,子线程结束            t.start()        for q in [self.url_queue,self.content_list_queue,self.html_str_queue]:            q.join()  #让主线程等待着,知道队列计数为0的时候,join失效        print("主线程结束")if __name__ == '__main__':    qiubai = QiuBai()    qiubai.run()


原创粉丝点击