线程和进程(三)

Oyst3r 于 2023-01-09 发布

相信看完上节内容的小伙伴会感觉那么写出来的代码是一坨答辩,十分欠妥的,这节就来在此基础上继续优化一下

概念

给一张图片,看一看大概的用法,具体可以看下面代码写的例子

使用 Queue 的多线程爬虫

这个 Queue 模块就是为了解决线程间通信的问题,而且 Python 中的Queue模块中提供了同步的、线程安全的队列类,包括 FIFO(先入先出)队列 Queue、LIFO(后入先出)队列 LifoQueue 和优先级队列 PriorityQueue

用直白点的话说就是可以把这个 Queue 看成一个容器,诶呀其实就像栈一样,把它看成一个暂时存放数据的容器,而且这个容器会封装了很多功能,就比如说要是只开四个线程,那就是用一个少一个,而这个就可以轮回开,有点类似于线程池那意思了,然后的话这个功能本身就是很安全的,不需要加锁,是个线程安全的操作,下面给出我的实现代码

import craw
import threading
import time
import queue


def queue_craw(url_queue):
    while True:
            url = url_queue.get()
            craw.crawler(url)
            if url_queue.empty():
                print("here")
                break


if __name__ == "__main__":
    url_queue = queue.Queue()
    threads = []
    start = time.time()
    for url in craw.urls:
        url_queue.put(url)

    for i in range(3):
        t = threading.Thread(target=queue_craw,args=(url_queue,),name=f'craw{i}')
        t.start()
        threads.append(t)

    for thread in threads:
        thread.join()

    end =time.time()
    print('url_queue花费时间',end-start)

这其实也算是一个生产者与消费者的模型,可以看作 url 在不断的生产,然后解析 url 就算是在不断的消费,当然在后面也可以继续写比如把得到的数据写入文本文件,这里就不再阐述,它就和一条链子一样串下去就行,这里主要想说明的问题就是它很自动化,会正确的让三个线程分配这 23 个页面,就是更加灵活了,不会存在像上节写的那样一下创建 23 个线程的呆板问题

同样的这个结果所展现的速度也是相当快的,其实就相当于是三个线程一直去接受 url 去解析

当然后面也会再说一个线程池的技术,那个就更方便了,实际开发中也是经常选择用线程池的,敬请期待吧!!!