【爬虫】多线程爬取图片

news2025/1/12 9:43:26

多线程爬虫

  • 多线程爬虫概述
    • 1.1 多线程的优势
    • 1.2 多线程的挑战
  • 设计多线程爬虫
    • 1.1 项目设计
    • 1.2 项目流程
    • 1.3注意事项
  • 总结

多线程爬虫概述

  在当今信息爆炸的时代,网络爬虫(Web Scraper)已成为获取和分析网络数据的重要工具。而多线程爬虫,作为一种提高数据采集效率的技术,更是在处理大规模数据时显得尤为重要。本文将介绍多线程爬虫的基本概念、设计原则以及如何应用于图片爬取任务。
  多线程爬虫是一种利用多线程技术来提高爬虫效率的网络爬虫。与传统的单线程爬虫相比,多线程爬虫可以同时执行多个任务,显著提高数据采集的速度。

1.1 多线程的优势

①多线程允许同时执行多个HTTP请求,减少了等待时间。
②更充分地利用服务器和网络资源。
③某个线程的失败不会影响其他线程的执行。

1.2 多线程的挑战

① 需要合理管理线程间的共享资源。
② 确保代码在多线程环境下依然能够正确执行。
③ 过多的线程可能导致资源竞争和上下文切换开销增大。

设计多线程爬虫

1.1 项目设计

① 设计合理的并发级别,保证合理运用网站资源,但又不会出发反爬虫机制。
② 使用线程池进行线程管理,提高资源的利用率。
③ 使用任务队列来存储待爬取的URL,线程从队列中获取任务进行处理。
④ 确保对网络请求和数据处理过程中可能出现的异常进行捕获和处理。
⑤ 生产者和消费者模式分离。

  生产者

class Procuder(threading.Thread):
	"""
	生产者
	爬取页面,获取图片地址加入到图片队列中
	"""

	def __init__(self, name, page_queue, img_queue, *args, **kwargs):
		super(Procuder, self).__init__(*args, **kwargs)
		self.name = name
		self.page_queue = page_queue
		self.img_queue = img_queue

	def run(self):
		while True:
			if self.page_queue.empty():
				print(self.name + '任务完成~')
				break
			# 1.获取每一页的url
			page_url = self.page_queue.get()

			# 2.爬取页面的数据
			self.spider_page(page_url)

			# 3.休眠0.5秒
			time.sleep(0.5)

	def spider_page(self, url):
		"""
		爬取每一页
		:param url: 每一页的地址
		:return:
		"""
		response = requests.get(url, headers=HEADERS)
		text_raw = response.text

		# 1.使用etree
		html_raw = etree.HTML(text_raw)

		# 2.使用xpath解析数据
		# 注意:过滤掉gif标签图片
		imgs = html_raw.xpath('//div[@class="page-content text-center"]//img[@class!="gif"]')

		# 3.获取图片的实际连接并下载到本地
		for img in imgs:
			# 3.1 图片的实际地址
			img_url = img.get('data-original')

			# 3.2 图片名称替换特殊符号
			alt = re.sub(r'[\??\.,。!!\*]', '', img.get('alt'))

			# 3.3 提取图片的后缀,组装成文件的名字
			img_name = alt + os.path.splitext(img_url)[-1]

			# 3.4 把爬取到【图片地址+图片名称】以【元组】的形式加入到队列图片队列中
			self.img_queue.put((img_url, img_name))

  消费者

class Consumer(threading.Thread):
	"""
	消费者
	获取图片的地址下载到本地
	"""

	def __init__(self, name, page_queue, img_queue, *args, **kwargs):
		super(Consumer, self).__init__(*args, **kwargs)
		self.name = name
		self.page_queue = page_queue
		self.img_queue = img_queue

	def run(self):
		while True:

			if self.img_queue.empty() and self.page_queue.empty():
				print(self.name + '任务完成~')
				break

			# 1.解包,获取图片的地址 + 图片的名称
			img_url, img_name = self.img_queue.get()

			# 2.使用urlretrieve()函数下载图片到本地
			request.urlretrieve(img_url, './imgs/%s' % img_name)

			print(img_name + "下载完成")

1.2 项目流程

  多线程技术可以显著提高爬虫的效率,特别是在网络IO密集型任务中,如图片下载。当一个线程等待网络响应时,其他线程可以继续执行,这样可以充分利用网络资源和CPU资源,提高爬取速度。

  1. 初始化队列。
	# 1.页面的队列
	page_queue = Queue(100)

	# 2.表情图片的队列
	img_queue = Queue(1000)
  1. 爬取页面地址
	# 3.爬取页面的地址
	for x in range(1, 10):
		url = 'http://www.doutula.com/photo/list/?page=%d' % x

		#  存入到页面地址队列中
		page_queue.put(url)
  1. 生产者和消费者模式分离,多线程爬取图片
	for x in range(5):
		t = Procuder(name='生产线程-%d' % x, page_queue=page_queue, img_queue=img_queue)
		t.start()

	for x in range(5):
		t = Consumer(name='消费线程-%d' % x, page_queue=page_queue, img_queue=img_queue)
		t.start()

1.3注意事项

① 在进行网络爬虫操作时,必须遵守相关法律法规,尊重目标网站的robots.txt文件。
② 设置合理的用户代理,模拟正常用户访问。
③ 合理设置请求频率,避免给服务器带来过大压力。

总结

  多线程爬虫通过提高并发度,可以大幅提升数据采集的效率,尤其适用于图片等静态资源的爬取。然而,设计和实现多线程爬虫需要考虑线程安全、资源管理和异常处理等多个方面。在实践中,开发者应注重效率与规范的平衡,确保爬虫的合法合规运行。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1609504.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Codigger GT模块:GUI融合Terminal,重塑开发体验

在信息技术日新月异的今天,开发者与计算机系统进行交互的界面,其体验的优化与升级显得尤为关键。Codigger G&T正是应这一需求而生,它巧妙地将现代图形用户界面(GUI)的优势融入传统的Terminal中,为开发者…

算法训练营day16

一、二叉树的最大深度 递归解法 后序遍历(DFS) class Solution {public int maxDepth(TreeNode root) {if (root null) return 0;return Math.max(maxDepth(root.left), maxDepth(root.right)) 1;} }算法解析: 终止条件: 当 root 为空,…

openAI tts Java文本转语音完整前后端代码 html

Java后端代码 maven 仓库&#xff1a; <!--openAI 请求工具--> <dependency><groupId>com.unfbx</groupId><artifactId>chatgpt-java</artifactId><version>1.1.5</version> </dependency>maven 仓库官方 tts 使用案例…

Odoo讨论+聊天模块:一体化内部协作平台,赋能高效沟通与业务流程协作

Odoo讨论聊天模块&#xff1a;一体化内部协作平台&#xff0c;赋能高效沟通与业务流程协作 Odoo 讨论模块是一个集成了即时通讯、文件共享、业务关联、权限控制等功能于一体的内部协作工具&#xff0c;允许用户通过跨模块的聊天窗口或通过专用的“讨论”面板互相发送消息、分享…

利用redis和fastapi实现本地与平台策略进行交互

redis简介: 在pandas一文有详细使用方法(一文教会pandas-CSDN博客)&#xff0c;具体可视化软件有redisstudio等。它是一个由 Salvatore Sanfilippo 写的 key-value 存储系统&#xff0c;是跨平台的非关系型数据库。 Redis 是一个开源的使用 ANSI C 语言编写、遵守 BSD 协议、支…

Redis: 在项目中的应用

文章目录 一、Redis的共享session应用二、分布式缓存1、缓存2、缓存一致性问题解决方案&#xff08;缓存更新策略&#xff09;&#xff08;1&#xff09;作用&#xff08;2&#xff09;三种策略&#xff08;3&#xff09;主动更新策略&#xff08;数据库、缓存不一致解决方案&a…

DFS专题:电话号码的字母组合

DFS专题&#xff1a;电话号码的字母组合 题目链接: 17.电话号码的字母组合 参考题解&#xff1a; 代码随想录 题目描述 代码思路 将数字到字母的映射用字符串数组表示出来。然后利用回溯算法&#xff0c;解决n个for循环的问题&#xff0c;枚举出每一种符合要求的情况。 代…

C++友元命名空间数据类型内联重载缺省

1.友元 &#xff08;1&#xff09;全局函数作为友元 利用友元这个语法&#xff0c;我们可在函数里访问类里面定义的私有成员&#xff1b; 先定义了一个默认构造函数对类里面的成员进行初始化&#xff1b;goodgay是一个全局的函数&#xff0c;我们想要直接打印私有成员变量就…

订单到期关闭如何实现

在电商、支付等系统中&#xff0c;一般都是先创建订单&#xff08;支付单&#xff09;&#xff0c;再给用户一定的时间进行支付&#xff0c;如果没有按时支付的话&#xff0c;就需要把之前的订单&#xff08;支付单&#xff09;取消掉。这种类似的场景有很多&#xff0c;还有比…

仓库管理系统哪个好用?看仓储出入库系统如何智慧管理库存-亿发

企业中的仓库扮演着至关重要的角色&#xff0c;负责产品的存储和分发。作为物流的重要节点&#xff0c;仓库不仅需要确保产品安全存放&#xff0c;还要保证及时的配送服务。同时&#xff0c;仓库还需要完成货物信息记录、库存管理和品质管理等任务。因此&#xff0c;仓储管理的…

DFS专题:二叉树的最大深度

力扣题目&#xff1a;二叉树的最大深度 题目链接: 104.二叉树的最大深度 题目描述 代码思路 设置两个变量&#xff0c;max来记录最大值&#xff0c;sum来记录路径的节点数量。利用dfs对二叉树进行搜索&#xff0c;遇到节点&#xff0c;则sum1&#xff1b;遇到叶子节点&#…

数据恢复如何工作?电脑最佳数据恢复软件分析

数据丢失是数字世界不合适的部分&#xff0c;迟早会影响许多计算机用户。 如果您不小心 #delete 了重要的 #file&#xff0c;可能很难找回它并造成不必要的压力。 点击发推文 幸运的是&#xff0c;即使您没有备份已删除的文件&#xff0c;PC的数据恢复软件也可以帮助您恢复已…

昂科烧录器支持Nuvoton新唐科技的低功耗微控制器M482SIDAE

芯片烧录行业领导者-昂科技术近日发布最新的烧录软件更新及新增支持的芯片型号列表&#xff0c;其中Nuvoton新唐科技的低功耗微控制器M482SIDAE已经被昂科的通用烧录平台AP8000所支持。 M482SIDAE以Arm Cortex-M4F为核心&#xff0c;是带有DSP指令集的高效能低功耗微控制器。其…

WPF Extended.Wpf.Toolkit 加载界面

1、NuGet 中安装 Extended.Wpf.Toolkit 。 2、在MainWindow.xaml中添加xmlns:tk"http://schemas.xceed.com/wpf/xaml/toolkit" 。 MainWindow.xaml 代码如下。 <Window x:Class"WPF_Extended_Wpf_Toolkit_Loading.MainWindow" xmlns"ht…

apipost、postman等工具上传图片测试flask、fastapi的文件api接口

参考&#xff1a;https://blog.csdn.net/qq_15821487/article/details/119354129 https://www.cnblogs.com/wyxjava/p/16076176.html 选择from-data&#xff0c;下拉选择file上传文件发送即可

【动态规划 区间dp 位运算】3117. 划分数组得到最小的值之和

本文涉及知识点 动态规划 区间dp 位运算 LeetCode3117. 划分数组得到最小的值之和 给你两个数组 nums 和 andValues&#xff0c;长度分别为 n 和 m。 数组的 值 等于该数组的 最后一个 元素。 你需要将 nums 划分为 m 个 不相交的连续 子数组&#xff0c;对于第 ith 个子数组…

vscode设置conda默认python环境,简单有效

本地conda 可能安装了各种环境&#xff0c;默认的vscode总是base环境&#xff0c;这时你想要在vscode调试python代码&#xff0c;使用默认的环境没有安装对应的包就会遇到报错解决这个问题的方法很简单ctrlshiftp 调出命令面板 再输入 select interpreter , 选择 python 选择解…

在Spring Boot中使用POI完成一个excel报表导入数据到MySQL的功能

最近看了自己玩过的很多项目&#xff0c;忽然发现有一个在实际开发中我们经常用到的功能&#xff0c;但是我没有正儿八经的玩过这个功能&#xff0c;那就是在Spring Boot中实现一个excel报表的导入导出功能&#xff0c;这篇博客&#xff0c;主要是围绕excel报表数据导入进行&am…

一例Mozi僵尸网络的挖矿蠕虫分析(workminer)

概述 这是一个Linux平台的挖矿蠕虫&#xff0c;使用了go和C混合编译而成&#xff0c;主要通过爆破SSH口令进行传播&#xff0c;属于Mozi僵尸网络。其中GO代码负责SSH相关的爆破传播&#xff0c;以及对Config的处理&#xff0c;C代码则负责处理加入Mozi P2P网络&#xff0c;拉取…

c++11 标准模板(STL)本地化库 - 平面类别(std::collate) - 定义字典序比较和字符串的散列(二)

本地化库 本地环境设施包含字符分类和字符串校对、数值、货币及日期/时间格式化和分析&#xff0c;以及消息取得的国际化支持。本地环境设置控制流 I/O 、正则表达式库和 C 标准库的其他组件的行为。 平面类别 定义字典序比较和字符串的散列 std::collate 类 std::collate 封…