Python 爬取大量数据如何并发抓取与性能优化

Python 并发抓取与性能优化

在进行网络爬虫开发时,爬取大量数据可能非常耗时。尤其是在处理许多网页或 API 请求时,逐个请求速度会非常慢。为了解决这个问题,我们可以通过并发抓取提高爬取效率。同时,通过性能优化来进一步减少耗时和资源占用,使爬虫更高效。本篇文章将带大家了解 Python 中常用的并发抓取方法,并介绍如何进行性能优化。

在这里插入图片描述

1. 并发抓取的基本概念

并发抓取指的是同时发出多个请求的技术,而不是顺序地等待每个请求完成。这可以极大地加速爬取过程,因为大部分时间网络请求处于等待响应状态,而并发可以利用这段时间去请求其他数据。

Python 支持多种并发模型,常见的有以下几种:

  1. 多线程:多个线程可以共享同一内存空间,非常适合 IO 密集型任务。
  2. 多进程:每个进程拥有独立的内存空间,适合 CPU 密集型任务。
  3. 异步 IO:基于协程的并发模型,能最大限度利用 IO 空闲时间,适合网络请求密集的爬虫任务。

2. 使用多线程进行并发抓取

多线程是 Python 中实现并发的最简单方法之一。使用多线程可以同时进行多个网络请求,减少爬取时间。Python 提供了 threadingconcurrent.futures.ThreadPoolExecutor 等工具。

示例:使用 ThreadPoolExecutor 进行多线程爬取

假设我们要爬取一组 URL 列表并获取其内容:

import requests
from concurrent.futures import ThreadPoolExecutor# 待爬取的 URL 列表
urls = ["https://example.com/page1","https://example.com/page2","https://example.com/page3",# 其他 URL
]# 定义抓取函数
def fetch_url(url):response = requests.get(url)print(f"抓取 {url} 状态码:{response.status_code}")return response.content# 使用线程池进行并发抓取
with ThreadPoolExecutor(max_workers=5) as executor:results = list(executor.map(fetch_url, urls))

在上面的代码中,我们定义了一个 fetch_url 函数用于抓取页面,然后使用 ThreadPoolExecutor 来创建一个线程池,并发抓取多个页面内容。

多线程的优缺点

  • 优点:实现简单,适合 IO 密集型任务(如网络请求)。
  • 缺点:Python 的 GIL(全局解释器锁)限制了 CPU 的充分利用,不适合 CPU 密集型任务。

3. 使用多进程进行并发抓取

在 CPU 密集型任务(如处理复杂数据或图像)中,多线程因 GIL 限制无法充分利用 CPU。此时,可以使用多进程模型,每个进程独立运行,互不干扰。

示例:使用 ProcessPoolExecutor 进行多进程爬取

import requests
from concurrent.futures import ProcessPoolExecutordef fetch_url(url):response = requests.get(url)print(f"抓取 {url} 状态码:{response.status_code}")return response.contenturls = ["https://example.com/page1","https://example.com/page2","https://example.com/page3",
]# 使用进程池进行并发抓取
with ProcessPoolExecutor(max_workers=5) as executor:results = list(executor.map(fetch_url, urls))

这里我们使用了 ProcessPoolExecutor,实现了多进程并发爬取。每个进程都有独立的内存空间,不会受 GIL 的影响。

多进程的优缺点

  • 优点:可以绕过 GIL,适合 CPU 密集型任务。
  • 缺点:每个进程都有独立内存,可能消耗较多系统资源,适合数据量不大的并发任务。

4. 使用异步 IO 进行并发抓取

在网络爬虫中,异步 IO 是最适合的并发方式。异步 IO 不会创建多个线程或进程,而是基于事件循环,让单线程在等待响应时继续处理其他请求,极大提高了效率。

Python 的 asyncioaiohttp 库是实现异步爬虫的利器。

示例:使用 aiohttp 进行异步抓取

import asyncio
import aiohttp# 待爬取的 URL 列表
urls = ["https://example.com/page1","https://example.com/page2","https://example.com/page3",
]# 定义异步抓取函数
async def fetch_url(session, url):async with session.get(url) as response:print(f"抓取 {url} 状态码:{response.status}")return await response.text()# 主函数:管理异步抓取流程
async def main():async with aiohttp.ClientSession() as session:tasks = [fetch_url(session, url) for url in urls]results = await asyncio.gather(*tasks)# 运行异步任务
asyncio.run(main())

异步 IO 的优缺点

  • 优点:不受 GIL 影响,占用资源少,适合高并发的 IO 密集型任务。
  • 缺点:代码较复杂,学习成本稍高,不适合 CPU 密集型任务。

5. 爬虫性能优化方法

在实现并发后,我们还可以通过以下几种方法进一步优化爬虫性能。

方法 1:减少 HTTP 请求次数

每次 HTTP 请求都会产生网络开销,因此减少请求次数可以有效提升性能。例如:

  • 缓存:对重复请求的页面进行缓存,避免多次请求。
  • 批量请求:将多个请求合并在一个请求中返回(如果服务器支持批量请求)。

方法 2:合理设置请求间隔和重试机制

过于频繁的请求会导致 IP 被封,因此在爬虫中设置合理的请求间隔非常重要。可以使用 time.sleep() 或带有间隔参数的工具库进行设置。

另外,对于出现错误的请求,可以设置重试机制。以下代码示例展示了如何设置请求间隔和重试机制:

import requests
import time
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.util.retry import Retry# 定义重试策略
retry_strategy = Retry(total=3,backoff_factor=1,status_forcelist=[429, 500, 502, 503, 504]
)
adapter = HTTPAdapter(max_retries=retry_strategy)# 创建带有重试机制的会话
session = requests.Session()
session.mount("https://", adapter)urls = ["https://example.com/page1", "https://example.com/page2"]# 遍历 URL,设置请求间隔
for url in urls:response = session.get(url)print(f"抓取 {url} 状态码:{response.status_code}")time.sleep(1)  # 设置 1 秒的间隔

方法 3:优化数据解析与存储

在爬虫抓取数据后,通常还需进行数据解析和存储。这两者的性能优化也有助于提高爬虫的整体效率。

  • 数据解析:解析 HTML 或 JSON 时,尽量使用高效的解析库(如 lxml 解析 HTML)。
  • 数据存储:如果要存储大量数据,可以选择高效的数据库(如 MySQL、MongoDB 等),并批量写入以提高性能。

方法 4:限速和分布式抓取

  • 限速:可以通过限速来控制每秒的请求数,防止对目标网站产生过大压力。
  • 分布式爬取:对于大型数据抓取任务,可以采用分布式爬取,将任务分配到多个服务器上,以提高抓取速度。

可以使用 scrapy 的分布式功能或者 Redis 来实现分布式爬虫。

方法 5:使用代理池

如果目标网站限制了每个 IP 的请求次数,可以使用代理池,从多个 IP 发起请求以防止被封禁。

import requests
from itertools import cycle# 代理池
proxies = ["http://proxy1.com", "http://proxy2.com", "http://proxy3.com"]
proxy_pool = cycle(proxies)# 发起请求并使用代理池
for url in urls:proxy = next(proxy_pool)response = requests.get(url, proxies={"http": proxy, "https": proxy})print(f"使用代理 {proxy} 抓取 {url} 状态码:{response.status_code}")

6. 结合 Scrapy 框架进行并发爬取

对于复杂的抓取任务

,Python 的 Scrapy 框架提供了更强大、稳定的并发抓取和数据管理能力。Scrapy 内置了并发请求、延迟、代理和管道等功能。

示例:使用 Scrapy 实现并发爬取

Scrapy 的 CONCURRENT_REQUESTSDOWNLOAD_DELAY 配置可以控制并发度和请求间隔。

在 Scrapy 的配置文件 settings.py 中设置:

# 最大并发数
CONCURRENT_REQUESTS = 16
# 下载延迟,防止频繁请求被封
DOWNLOAD_DELAY = 0.5

然后在 Scrapy 的 Spider 中定义抓取逻辑,即可实现高效的并发爬取。

总结

本文介绍了 Python 中常用的几种并发模型及其优缺点,并提供了实际的示例代码。在抓取任务中,合理选择并发方式(如多线程、多进程或异步 IO),并结合性能优化策略(如限速、重试、代理池和缓存)可以显著提高爬虫的效率。

通过合理配置和性能优化,即使在高并发抓取需求下,也可以有效降低资源消耗并加快爬取速度,完成大规模数据的抓取任务。

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

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

相关文章

Centos开机自启动脚本示例

本文建议创建一个sh文件管理自启动的各项内容,再将sh文件设置开机启动 在/root/autoshell下创建一个autostart.sh,内容如下 #!/bin/bash # description:开机自启脚本# 启动mongodb sh /root/software/mongodb-linux-x86_64-rhel70-4.0.6/bin/mongod --c…

猫头虎分享: AI设计利器 Recraft详解与基础使用教程

🦁猫头虎分享:AI设计利器 Recraft——全面解析与教程 大家好,我是猫头虎!今天为大家带来一款非常炙手可热的 AI 设计工具 —— Recraft 的深度介绍与详细教程。这款工具自推出以来,就迅速获得了全球设计师的青睐。那么…

Spring AI : 让ChatGPT成为你构建应用的核心亮点

本文是一篇介绍spring ai的文章,主要介绍了生成文本内容,以及读取图片中内容两个能力。 之所以介绍这两个能力,是因为 大模型目前最适合做的事情有两个: 1) 非结构化数据的结构化(图片转文字,…

Qt(openCV的应用)

1. OpenCV简介 OpenCV(Open Source Computer Vision Library)是一个开源的计算机视觉库,它提供了丰富的图像处理和计算机视觉功能。该库由英特尔公司发起,并在 BSD 许可证下发布,因此它是免费的,且开放源代…

Excel快速转换文档word工具

【注意事项:】 1、目前支持Win10/11 x64操作系统,已亲测可正常运行。 2、工具解压后在 \excel_docx\excel\目录中提供了转换前的标准模板“testcase.xlsx”,测试童鞋在使用Zentao、JIRA等测试工具导出excel(.xlsx后缀&#xff0…

uniapp 集成 uview

注意:HBuildX新建项目时必须选择vue2版本,vue3会不支持uview 下载安装方式: uview安装网站:uView2.0重磅发布,利剑出鞘,一统江湖 - DCloud 插件市场 配置: 1.安装sass插件 // 安装sass npm i …

想要搭建陪玩系统小程序,这几点不容忽视,陪玩系统源码框架

随着互联网经济的持续稳定发展,游戏市场的“封印”逐渐被打开,搭建陪玩平台成为一个新的热点。提起陪玩系统相信大家也不陌生,漫漫单排路如果有一个大神能带自己躺赢那是再好不过了,于是陪玩系统运营而生。想要搭建陪玩平台&#…

【论文笔记】Dense Connector for MLLMs

🍎个人主页:小嗷犬的个人主页 🍊个人网站:小嗷犬的技术小站 🥭个人信条:为天地立心,为生民立命,为往圣继绝学,为万世开太平。 基本信息 标题: Dense Connector for MLLM…

[论文阅读]A Survey of Embodied Learning for Object-Centric Robotic Manipulation

Abstract --以对象为中心的机器人操纵的Embodied learning是体现人工智能中一个快速发展且具有挑战性的领域。它对于推进下一代智能机器人至关重要,最近引起了人们的极大兴趣。与数据驱动的机器学习方法不同,具身学习侧重于通过与环境的物理交互和感知反…

vscode的一些使用心得

问题1:/home目录空间有限 连接wsl或者remote的时候,会在另一端下载一个.vscode-server,vscode的插件都会安装进去,导致空间增加很多,可以选择更换这个文件的位置 参考:https://blog.csdn.net/weixin_4389…

Vue前端开发之自定义动画样式

在上一小节中,我们介绍了动画的实现源于6个类别样式,它们的名称默认前缀是一个“v”字母或者指定的名称,如“sc”,其实,也可以不使用这些固定的类别样式,开发者可以自定义任意的类别样式,供动画…

【709】基于SSM+vue的“萌宠小知识”网站设计与实现

摘 要 如今社会上各行各业,都喜欢用自己行业的专属软件工作,互联网发展到这个时候,人们已经发现离不开了互联网。新技术的产生,往往能解决一些老技术的弊端问题。因为传统萌宠小知识信息管理难度大,容错率低&#xff…

《机器学习by周志华》学习笔记-神经网络-05RBF径向基函数网络

1、背景 1988年,Broomhead和Lowe用径向基函数(Radialbasis function, RBF)提出分层网络的设计方法,从而将神经网络的设计与数值分析和线性适应滤波相挂钩。 2、概念 RBF(Radial Basis Function,径向基函数)网络是一种单隐层前馈神经网络,即该网络只有3层,输入层、隐含…

11.1组会汇报-基于区块链的安全多方计算研究现状与展望

基础知识 *1.背书,这个词源来自银行票据业务,是指票据转让时,原持有人在票据背面加盖自己的印鉴,证明该票据真实有效、如果有问题就可以找原持有人。 区块链中的背书就好理解了。可以简单的理解为验证交易并声明此交易合法&…

MSC“名实之辩”:精准鉴定只为精准治疗

前 言 MSC是一群来源广泛、能够体外增殖分化的异质性细胞。MSC具有免疫调节、促进组织修复等作用,应用于多种疾病的治疗。由于科学进程、习惯等原因,MSC具有多种名称。自先秦以来,就有“名实之辩”,今日我们就讲一讲MSC的名称与…

CST联合Isight进行天线DOE设计

本期我们转载一篇国外工程师Matthias MEIENHOFER,利用CST和Isight联合进行DOE设计的案例。 本文通过模拟设计一个双频带(GSM和WLAN)天线来研究天线的几何尺寸变化和性能的关系。如果我们改变天线里的某些宽度或长度参数,天线的性…

微信小程序寓言童话创作APP设计与实现

文章目录 项目介绍具体实现截图技术介绍mvc设计模式小程序框架以及目录结构介绍错误处理和异常处理java类核心代码部分展示详细视频演示源码获取 项目介绍 本文通过对现有寓言童话创作APP的调研和分析,取其精华去其糟粕,遵循软件工程方法进行系统分析、…

越来越多人不喜欢十六薪了

十六薪是个坑 大家好,我是青玉白露。 最近刷各种论坛,发现有个有意思的职场现象。 不少人开始对"十五薪"、“十六薪”敬而远之。 曾经让人眼红的福利,现在却成了让人望而却步的"坑"。这是咋回事呢? 乍一看,十五薪确实挺诱人。比如月薪3万,年收…

【命令执行waf绕过】

一、绕过空格 二、绕过黑名单 三、绕过长度限制 四、练习 发现了两个文件,cat读取,但是被过滤了: 用 I F S IFS IFS绕过读出index的源码,发现过滤了很多东西,黑名单过滤: 字符串拼接绕过: …

MongoDB笔记02-MongoDB基本常用命令

文章目录 一、前言二、数据库操作2.1 选择和创建数据库2.2 数据库的删除 3 集合操作3.1 集合的显式创建3.2 集合的隐式创建3.3 集合的删除 四、文档基本CRUD4.1 文档的插入4.1.1 单个文档插入4.1.2 批量插入 4.2 文档的基本查询4.2.1 查询所有4.2.2 投影查询(Projec…