当前位置: 首页 > news >正文

python爬虫6—高性能异步爬虫

如果有多个URL等待我们爬取,我们通常是一次只能爬取一个,爬取效率低,异步爬虫可以提高爬取效率,可以一次多多个URL同时同时发起请求

异步爬虫方式:
一、多线程、多进程(不建议):可以为爬取阻塞(多个URL等待爬取)单独开启线程或进程,多个爬取URL异步执行(不能开启无限多个)
二、线程池、进程池:可以降低系统对进程或者线程创建和消除的频率,从而降低系统的开销,池中进程或线程的数量是有上限的
一、单线程串行爬取

用时间延时模拟爬取每个网址的耗时时间
单线程爬取一次只能爬取一个,以下面为例,一次爬取一个,爬取4个需要8秒

import time# 模拟爬取每个网址耗时
def get_page(url):time.sleep(2)# 开始时间
start_time = time.time()
# URL
url_list = ['url1', 'url2', 'url3', 'url4']
for url in url_list:get_page(url)
# 结束时间
end_time = time.time()
# 输出总耗时
print(end_time-start_time)

二、多线程并行爬取

一次可以对多个URL同时进行爬取,以下面为例,开启4个进程,则可以对4个URL同时发起请求,总时间为2秒

import time
from multiprocessing.dummy import Pool# 模拟爬取每个网址耗时
def get_page(url):time.sleep(2)url_list = ['url1', 'url2', 'url3', 'url4']
# 开始时间
start_time = time.time()
# 实例化线程对象,4表示开启了4个进程
pool = Pool(4)
# 讲列表中url_list每一个列表元素传递给get_page进行处理
pool.map(get_page, url_list)
# 结束时间
end_time = time.time()
print(end_time-start_time)

三、单线程+异步协程

event_loop:事件循环,相当于一个无限循环,可以把一些函数注册到这个循环上,当满足某些条件的时候,函数就会被循环执行
coroutine:协程对象,我们可以将协程对象注册到事件循环中,它会被事件循环调用。我们可以使用async关键字来定义一个方法,这个方法在调用时不会立即被执行,而是返回一个协程对象。
task:任务,它是对协程对象的进一步封装,包含了任务的各个状态。
future:代表将来执行或还没有执行的任务,实际上和 task没有本质区别。async定义一个协程。
await用来挂起阻塞方法的执行。

import asyncioasync def request(url):print('模拟请求')# 调用async修饰的函数之后返回一个协程对象
c = request('url')
# 创建一个事件循环对象
loop = asyncio.new_event_loop()
# 将协程对象注册到loop中.然后启动loop
loop.run_until_complete(c)
print(c)
# <coroutine object request at 0x000001F5BDDA8040>

 task的使用

import asyncioasync def request(url):print('模拟请求')# 调用async修饰的函数之后返回一个协程对象
c = request('https://www.baidu.com')
# 创建一个事件循环对象
loop = asyncio.new_event_loop()
# 基于loop创建一个task对象
task = loop.create_task(c)
# 注册循环之前的输出
print(task)
loop.run_until_complete(task)
# 注册循环之后的输出
print(task)
''' 输出如下
<Task pending name='Task-1' coro=<request() running at E:\Code\pythonProject\main.py:4>>
模拟请求
<Task finished name='Task-1' coro=<request() done, defined at E:\Code\pythonProject\main.py:4> result=None>
'''

 

 future的使用

import asyncioasync def request(url):print('模拟请求')# 调用async修饰的函数之后返回一个协程对象
c = request('https://www.baidu.com')
# 创建一个事件循环对象
loop = asyncio.new_event_loop()
# 基于loop创建一个task对象
task = asyncio.ensure_future(c, loop=loop)
print(task)
loop.run_until_complete(task)
print(task)
'''
<Task pending name='Task-1' coro=<request() running at E:\Code\pythonProject\main.py:3>>
模拟请求
<Task finished name='Task-1' coro=<request() done, defined at E:\Code\pythonProject\main.py:3> result=None>
'''

1、绑定回调

import asyncioasync def request(url):print('模拟请求')return urldef callback_func(task):# result返回的是任务对象中封装的携程对象对应函数的返回值,即上面返回的urlprint(task.result())# async修饰的函数,调用之后返回的一个协程对象
c = request('url')loop = asyncio.new_event_loop()
task = asyncio.ensure_future(c, loop=loop)
# 将回调函数绑定到任务对象中
task.add_done_callback(callback_func) # task
loop.run_until_complete(task)
'''
模拟请求
url
'''

2、多任务协成

在异步协成中,如果出现了同步模块相关的代码,那么就无法实现异步,如下面的time.sleep(2),下面代码没起到异步作用,爬取三个网站需要6秒左右

import asyncio
import timeasync def request(url):print('模拟请求')# 在异步协成中,如果出现了同步模块相关的代码,那么就无法实现异步time.sleep(2)return urlstart = time.time()
urls = ['aaa', 'bbb', 'ccc']
# 任务列表:存放多个任务对象
stasks = []# 将任务对象列表注册到事件循环当中
loop = asyncio.new_event_loop()
for url in urls:c = request(url)task = asyncio.ensure_future(c, loop=loop)stasks.append(task)# 需要将任务列表封装到wait中
loop.run_until_complete(asyncio.wait(stasks))
print(time.time() - start)
'''
模拟请求
模拟请求
模拟请求
6.002672433853149
'''

 这里就需要使用asyncio.sleep,当在asyncio中遇到阻塞操作必须进行手动挂起,使用await挂起,如下方法起到了异步左右,爬取三个URL只需要2秒左右

import asyncio
import timeasync def request(url):print('模拟请求')# 当在asyncio中遇到阻塞操作必须进行手动挂起await asyncio.sleep(2)return urlstart = time.time()
urls = ['aaa', 'bbb', 'ccc']
# 任务列表:存放多个任务对象
stasks = []# 将任务对象列表注册到事件循环当中
loop = asyncio.new_event_loop()
for url in urls:c = request(url)task = asyncio.ensure_future(c, loop=loop)stasks.append(task)# 需要将任务列表封装到wait中
loop.run_until_complete(asyncio.wait(stasks))
print(time.time() - start)
'''
模拟请求
模拟请求
模拟请求
2.0162434577941895
'''

requests.get请求是基于同步的,那么就无法实现异步,耗时较长

async def request(url):# requests.get请求是基于同步的,那么就无法实现异步response = requests.get(url=url)

必须使用基于异步的网络请求模块进行请求发送
aiohttp:基于异步网络请求的模块
pip install aiohttp

import aiohttpasync def request(url):async with aiohttp.ClientSession() as session:  # 返回session对象# 将get改为post为post请求# 参数:headers,params/data,proxy='http://ip:portasync with await session.get(url) as response:   # 返回response对象# text()返回字符串形式的响应数据# read()返回二进制形式的响应数据# json()返回的是json对象# 注意:在获取响应数据操作之前一定要使用await进行手动挂起page_text = await response.text()

 

 

 

相关文章:

python爬虫6—高性能异步爬虫

如果有多个URL等待我们爬取&#xff0c;我们通常是一次只能爬取一个&#xff0c;爬取效率低&#xff0c;异步爬虫可以提高爬取效率&#xff0c;可以一次多多个URL同时同时发起请求 异步爬虫方式&#xff1a; 一、多线程、多进程&#xff08;不建议&#xff09;&#xff1a;可以…...

日历功能——C语言

实现日历功能&#xff0c;输入年份月份&#xff0c;输出日历 #include<stdio.h>int leap_year(int year) {if(year % 4 0 && year % 100 ! 0 || year % 400 0){return 1;}else{return 0;} }int determine_year_month_day(int *day,int month,int year) {if(mo…...

GPIO中断

1.EXTI简介 EXTI是External Interrupt的缩写&#xff0c;指外部中断。在嵌入式系统中&#xff0c;外部中断是一种用于处理外部事件的机制。当外部事件发生时&#xff08;比如按下按钮、传感器信号变化等&#xff09;&#xff0c;外部中断可以立即打断正在执行的程序&#xff0…...

springboot完成一个线上图片存放地址+实现前后端上传图片+回显

1.路径 注意路径 2.代码&#xff1a;&#xff08;那个imagePath没什么用&#xff0c;懒的删了&#xff09;&#xff0c;注意你的本地文件夹要有图片&#xff0c;才可以在线上地址中打开查看 package com.xxx.common.config;import org.springframework.beans.factory.annotat…...

编程思维与生活琐事的内在关联及其应用价值

随着科技的日益普及和信息化时代的到来&#xff0c;编程作为一种现代技能&#xff0c;其影响已不再局限于专业领域&#xff0c;而是逐步渗透到人们的日常生活之中。探讨编程与生活琐事之间的关系&#xff0c;有助于我们更好地理解如何将技术智慧应用于日常管理&#xff0c;提升…...

OSPF排错

目录 实验拓扑图 实验要求 实验排错 故障一 故障现象 故障分析 故障解决 故障二 故障现象 故障分析 故障解决 故障三 故障现象 故障分析 故障解决 故障四 故障现象 故障分析 故障解决 故障五 故障现象 故障分析 故障解决 故障六 故障现象 故障分析 …...

day07-CSS高级

01-定位 作用&#xff1a;灵活的改变盒子在网页中的位置 实现&#xff1a; 1.定位模式&#xff1a;position 2.边偏移&#xff1a;设置盒子的位置 left right top bottom 相对定位 position: relative 特点&#xff1a; 不脱标&#xff0c;占用自己原来位置 显示模…...

05 MP之ActiveRecord模式+SimpleQuery

1. ActiveRecord ActiveRecord(活动记录&#xff0c;简称AR)&#xff0c;是一种领域模型模式&#xff0c;特点是一个模型类对应关系型数据库中的一个表&#xff0c;而模型类的一个实例对应表中的一行记录。 其目标是通过围绕一个数据对象, 进行全部的CRUD操作。 1.1 让实体类…...

git diff查看比对两次不同时间点提交的异同

git diff查看比对两次不同时间点提交的异同 用 git diff命令&#xff1a; git diff commit-id-1 commit-id-2 不同commit-id在不同的时间点提交产生&#xff0c;因为也可以认为git diff是比对两个不同时间点的代码异同。 git diff比较不同commit版本的代码文件异同_git diff c…...

基于muduo网络库开发服务器程序和CMake构建项目 笔记

跟着施磊老师做C项目&#xff0c;施磊老师_腾讯课堂 (qq.com) 一、基于muduo网络库开发服务器程序 组合TcpServer对象创建EventLoop事件循环对象的指针明确TcpServer构造函数需要什么参数,输出ChatServer的构造函数在当前服务器类的构造函数当中,注册处理连接的回调函数和处理…...

前端支持下载模板、导入数据、导出数据(excel格式)

前言 xlsx是由SheetJS开发的一个处理excel文件的npm库,适用于前端开发者实现下载模板、导入导出excel文件等需求&#xff0c;演示的项目的技术栈为vue3 elementPlus 一. 引入xlsx 安装xlsx npm install xlsx引入xlsx import * as XLSX from xlsx;二. 下载模板 const han…...

编译Faiss-gpu【InterMKL】C++ 按步骤操作 基本不会有问题的 python原理相同。

编译Faiss-gpu C++ 基本介绍 使用Faiss版本【1.7.4】 该项目依赖于BLAS 组件 OpenBLAS 和 IntelMKL BLAS 【官方支持】 IntelMKL 会比 OpenBLAS 快的多。 【来自官方结论】 本机环境 Cuda :11.1 Cuda-Driver: 515 InterMKL: 2021.2.0 Faiss :1.7.4 注意:faiss仅…...

conn.execute的用法详解

conn.execute的用法详解 大家好&#xff0c;我是免费搭建查券返利机器人赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01;今天&#xff0c;我们将深入研究数据库连接中conn.execute的用法&#xff0c;解析它的功能、…...

GetBuffer() 与 ReleaseBuffer() 使用详解

GetBuffer() 与 ReleaseBuffer() 使用详解 大家好&#xff0c;我是免费搭建查券返利机器人赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01;今天&#xff0c;我们将深入研究在编程中常用的GetBuffer()与ReleaseBuff…...

Flink CEP(基本概念)

Flink CEP 在Flink的学习过程中&#xff0c;我们已经掌握了从基本原理和核心层的DataStream API到底层的处理函数&#xff0c;再到应用层的Table API和SQL的各种手段&#xff0c;可以应对实际应用开发的各种需求。然而&#xff0c;在实际应用中&#xff0c;还有一类更为复…...

[AIGC] Spring Gateway与 nacos 简介

文章目录 Spring Gateway简介主要特性优点总结 Nacos简介主要特性优点总结 Spring Gateway 简介 Spring Gateway是一个基于Spring Framework的工具&#xff0c;用于构建和管理微服务架构中的网关。它提供了一种简单而灵活的方式来路由和过滤请求&#xff0c;以及在微服务之间…...

2024-2-3-复习作业

1> 要求&#xff1a; 效果图&#xff1a; 2> 要求&#xff1a; 效果图&#xff1a; 3> 要求&#xff1a; 效果图&#xff1a; 源代码&#xff1a; #include <stdio.h> #include <stdlib.h> typedef int datatype; typedef struct Node {datatype data…...

【如何快速上手Vue.js框架——详细介绍】

如何快速上手Vue.js框架——详细介绍 1. 介绍2. 理解Vue.js的核心概念3. 搭建开发环境4. 创建第一个项目5. 学习基础6. 进阶概念7. 最佳实践和模式8. 构建和部署9. 持续学习10. 实际操作 1. 介绍 要快速上手Vue.js框架&#xff0c;可以按照以下步骤进行学习和实践&#xff1a;…...

1Panel应用推荐:青龙定时任务管理平台

1Panel&#xff08;github.com/1Panel-dev/1Panel&#xff09;是一款现代化、开源的Linux服务器运维管理面板&#xff0c;它致力于通过开源的方式&#xff0c;帮助用户简化建站与运维管理流程。为了方便广大用户快捷安装部署相关软件应用&#xff0c;1Panel特别开通应用商店&am…...

BUUCTF-Real-[struts2]s2-013

struts2的标签中 <s:a> 和 <s:url> 都有一个 includeParams 属性&#xff0c;可以设置成如下值none - URL中不包含任何参数&#xff08;默认&#xff09; get - 仅包含URL中的GET参数 all - 在URL中包含GET和POST参数 当includeParamsall的时候&#xff0c;会将本次…...

内存分配函数malloc kmalloc vmalloc

内存分配函数malloc kmalloc vmalloc malloc实现步骤: 1)请求大小调整:首先,malloc 需要调整用户请求的大小,以适应内部数据结构(例如,可能需要存储额外的元数据)。通常,这包括对齐调整,确保分配的内存地址满足特定硬件要求(如对齐到8字节或16字节边界)。 2)空闲…...

Cursor实现用excel数据填充word模版的方法

cursor主页&#xff1a;https://www.cursor.com/ 任务目标&#xff1a;把excel格式的数据里的单元格&#xff0c;按照某一个固定模版填充到word中 文章目录 注意事项逐步生成程序1. 确定格式2. 调试程序 注意事项 直接给一个excel文件和最终呈现的word文件的示例&#xff0c;…...

cf2117E

原题链接&#xff1a;https://codeforces.com/contest/2117/problem/E 题目背景&#xff1a; 给定两个数组a,b&#xff0c;可以执行多次以下操作&#xff1a;选择 i (1 < i < n - 1)&#xff0c;并设置 或&#xff0c;也可以在执行上述操作前执行一次删除任意 和 。求…...

如何为服务器生成TLS证书

TLS&#xff08;Transport Layer Security&#xff09;证书是确保网络通信安全的重要手段&#xff0c;它通过加密技术保护传输的数据不被窃听和篡改。在服务器上配置TLS证书&#xff0c;可以使用户通过HTTPS协议安全地访问您的网站。本文将详细介绍如何在服务器上生成一个TLS证…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个生活电费的缴纳和查询小程序

一、项目初始化与配置 1. 创建项目 ohpm init harmony/utility-payment-app 2. 配置权限 // module.json5 {"requestPermissions": [{"name": "ohos.permission.INTERNET"},{"name": "ohos.permission.GET_NETWORK_INFO"…...

AI书签管理工具开发全记录(十九):嵌入资源处理

1.前言 &#x1f4dd; 在上一篇文章中&#xff0c;我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源&#xff0c;方便后续将资源打包到一个可执行文件中。 2.embed介绍 &#x1f3af; Go 1.16 引入了革命性的 embed 包&#xff0c;彻底改变了静态资源管理的…...

使用LangGraph和LangSmith构建多智能体人工智能系统

现在&#xff0c;通过组合几个较小的子智能体来创建一个强大的人工智能智能体正成为一种趋势。但这也带来了一些挑战&#xff0c;比如减少幻觉、管理对话流程、在测试期间留意智能体的工作方式、允许人工介入以及评估其性能。你需要进行大量的反复试验。 在这篇博客〔原作者&a…...

腾讯云V3签名

想要接入腾讯云的Api&#xff0c;必然先按其文档计算出所要求的签名。 之前也调用过腾讯云的接口&#xff0c;但总是卡在签名这一步&#xff0c;最后放弃选择SDK&#xff0c;这次终于自己代码实现。 可能腾讯云翻新了接口文档&#xff0c;现在阅读起来&#xff0c;清晰了很多&…...

Elastic 获得 AWS 教育 ISV 合作伙伴资质,进一步增强教育解决方案产品组合

作者&#xff1a;来自 Elastic Udayasimha Theepireddy (Uday), Brian Bergholm, Marianna Jonsdottir 通过搜索 AI 和云创新推动教育领域的数字化转型。 我们非常高兴地宣布&#xff0c;Elastic 已获得 AWS 教育 ISV 合作伙伴资质。这一重要认证表明&#xff0c;Elastic 作为 …...

如何配置一个sql server使得其它用户可以通过excel odbc获取数据

要让其他用户通过 Excel 使用 ODBC 连接到 SQL Server 获取数据&#xff0c;你需要完成以下配置步骤&#xff1a; ✅ 一、在 SQL Server 端配置&#xff08;服务器设置&#xff09; 1. 启用 TCP/IP 协议 打开 “SQL Server 配置管理器”。导航到&#xff1a;SQL Server 网络配…...