Python爬虫多线程实战:基于Queue队列的并发抓取详解

小林子
小林子
发布时间:2026-10-13 | 2人浏览过
原创

本文详解Python爬虫中多线程的使用,重点介绍如何利用标准库Queue解决线程间数据共享与交换的安全性问题。通过糗百图片抓取的实战案例,展示如何构建URL队列、启动多线程并发请求,并控制线程数量以优化抓取速度,确保数据一致性与程序稳定性。

Python Queue模块基础与多线程数据共享

Queue模块简介

Queue是Python的标准库之一,通常被称为队列模块。开发者可以直接使用import语句进行引用。需要注意的是,在Python 2.x版本中,该模块名为Queue(首字母大写),而在Python 3.x及更高版本中,直接引用queue即可。

在Python多线程编程中,多个线程默认共享内存数据。当多个线程同时读写或交换数据时,若缺乏同步机制,极易引发数据竞争,导致数据不安全或状态不一致。Queue模块的出现正是为了解决这一问题,它提供了线程安全的队列操作,能够完美处理多线程环境下的数据交换,确保数据传递的安全性和一致性。

多线程并发抓取实战:糗百图片示例


#多线程实战栗子(糗百)
#用一个队列Queue对象,
#先产生所有url,put进队列;
#开启多线程,把queue队列作为参数传入
#主函数中读取url
import requests
from queue import Queue
import re,os,threading,time
# 构造所有ip地址并添加进queue队列
headers = {
  'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36'
}
urlQueue = Queue()
[urlQueue.put('http://www.qiumeimei.com/image/page/{}'.format(i)) for i in range(1,14)]
def get_image(urlQueue):
  while True:
    try:
      # 不阻塞的读取队列数据
      url = urlQueue.get_nowait()
      # i = urlQueue.qsize()
    except Exception as e:
      break
    print('Current Thread Name %s, Url: %s ' % (threading.currentThread().name, url))
    try:
      res = requests.get(url, headers=headers)
      url_infos = re.findall('data-lazy-src="(.*?)"', res.text, re.S)
      for url_info in url_infos:
        if os.path.exists(img_path + url_info[-20:]):
          print('图片已存在')
        else:
          image = requests.get(url_info, headers=headers)
          with open(img_path + url_info[-20:], 'wb') as fp:
            time.sleep(1)
            fp.write(image.content)
          print('正在下载:' + url_info)
    except Exception as e:
      print(e)
if __name__ == '__main__':
  startTime = time.time()
  # 定义图片存储路径
  img_path = './img/'
  if not os.path.exists(img_path):
    os.mkdir(img_path)
  threads = []
  # 可以调节线程数, 进而控制抓取速度
  threadNum = 4
  for i in range(0, threadNum):
    t = threading.Thread(target=get_image, args=(urlQueue,))
    threads.append(t)
  for t in threads:
    t.start()
  for t in threads:
    # 多线程多join的情况下,依次执行各线程的join方法, 这样可以确保主线程最后退出, 且各个线程间没有阻塞
    t.join()
  endTime = time.time()
  print('Done, Time cost: %s ' % (endTime - startTime))

核心要点总结

上述内容详细介绍了Python爬虫中多线程结合Queue队列的使用方法与原理。希望这篇详解能帮助大家更好地掌握并发抓取技术。如果在使用过程中有任何疑问,欢迎留言交流,小编会及时回复。感谢大家对本站的支持!若觉得本文对您有帮助,欢迎转载,请注明出处,谢谢!

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表