python 多线程+队列的简单应用

在实际处理需求的过程中,博主比较偏爱使用多线程threading + 队列queue的方式 去开发代码。

(本文注重的是搭建模板框架,仅供参考)

举例:

以豆瓣电影的排行为例,写个简单的demo。
豆瓣链接:https://movie.douban.com/top250?start=0&filter=

在这里插入图片描述
一共也就10页!

直接上代码:

import json
import urllib3
import threading
from queue import Queue
from loguru import logger

urllib3.disable_warnings()


class CrawlDoubanMovie(object):
    def __init__(self):
        self.max_times = 5
        self.queue_req = Queue()

    # 创建塞入任务
    def create_tasks(self):
        for i in range(1, 11):
            task_info = {"page_num": i}
            self.queue_req.put(json.dumps(task_info, ensure_ascii=False))
        logger.info(f"本次任务数量:{self.queue_req.qsize()}")

    # 请求解析操作
    def get_content_from_web(self, page):
        pass

    # 解析任务
    def parse_task(self, task_info):
        page_num = task_info["page_num"]
        logger.info(f"正在访问豆瓣电影第【{page_num}】页!")

        if "retry_times" not in task_info.keys():
            task_info["retry_times"] = 0

        if task_info["retry_times"] > self.max_times:
            logger.error(f"current task crawl failed, page_num:{page_num}")
            return
        else:
            try:
                self.get_content_from_web(page_num)
            except Exception as exc:
                retry_task = {"page_num": page_num}
                self.queue_req.put(json.dumps(retry_task, ensure_ascii=False))
                logger.error(f"抓取失败, 重新放入队列中! page_num:{page_num}")
            else:
                logger.info(f"抓取成功,返回内容! page_num:{page_num}")
                pass

    def main_run(self):
        while True:
            task_info = self.queue_req.get()
            if task_info is None:
                self.queue_req.task_done()
                break
            else:
                self.parse_task(json.loads(task_info))
                self.queue_req.task_done()


if __name__ == "__main__":
    threading_num = 6
    crawl = CrawlDoubanMovie()
    crawl.create_tasks()
    for i in range(threading_num):
        t = threading.Thread(target=crawl.main_run)
        t.daemon = True
        t.start()
    crawl.queue_req.join()

模块和函数之间非常的清晰明了,

  • create_tasks() 就负责初始化创建任务
  • get_content_from_web()负责请求和解析数据
  • parse_task() 负责解析任务,这里面还包括了错误重试并重新放入队列中。
  • main_run()主函数 启动程序

搭配了多线程提升很多,也用到了队列。

运行效果图:

在这里插入图片描述
不仅使用方式简单实用,而且速度也是相当的快。

  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在爬虫中,多线程和队列是非常常见的技术应用。下面是它们在爬虫中的应用示例: 1. 多线程:使用多线可以提高爬取数据的效率,同时可以并发处理多个请求。例如,可以将爬虫程序分为多个线程,每个线程负责处理一个请求,这样可以同时发送多个请求并同时处理响应。 2. 队列:使用队列可以实现任务的调度和管理。例如,可以将待爬取的URL放入队列中,然后创建多个爬虫线程从队列中获取URL,并进行相应的爬取操作。这样可以有效地控制任务的执行顺序,避免资源竞争和重复爬取。 综合应用示例: ```python import threading import queue import requests # 创建队列 url_queue = queue.Queue() # 定义爬虫函数 def crawler(): while not url_queue.empty(): url = url_queue.get() # 发送请求并处理响应 response = requests.get(url) # 其他处理操作... # 添加待爬取的URL到队列 url_queue.put('http://example.com/page1') url_queue.put('http://example.com/page2') url_queue.put('http://example.com/page3') # 创建多个爬虫线程 num_threads = 3 threads = [] for _ in range(num_threads): t = threading.Thread(target=crawler) threads.append(t) # 启动线程 for t in threads: t.start() # 等待所有线程执行完毕 for t in threads: t.join() # 所有任务完成 print("All tasks finished.") ``` 这个示例展示了如何使用多线程和队列来进行爬虫任务的并发处理和调度。通过将待爬取的URL放入队列中,然后创建多个爬虫线程从队列中获取URL并进行相应的爬取操作,可以实现高效的爬取任务处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值