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等待我们爬取,我们通常是一次只能爬取一个,爬取效率低,异步爬虫可以提高爬取效率,可以一次多多个URL同时同时发起请求 异步爬虫方式: 一、多线程、多进程(不建议):可以…...

日历功能——C语言
实现日历功能,输入年份月份,输出日历 #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的缩写,指外部中断。在嵌入式系统中,外部中断是一种用于处理外部事件的机制。当外部事件发生时(比如按下按钮、传感器信号变化等),外部中断可以立即打断正在执行的程序࿰…...

springboot完成一个线上图片存放地址+实现前后端上传图片+回显
1.路径 注意路径 2.代码:(那个imagePath没什么用,懒的删了),注意你的本地文件夹要有图片,才可以在线上地址中打开查看 package com.xxx.common.config;import org.springframework.beans.factory.annotat…...
编程思维与生活琐事的内在关联及其应用价值
随着科技的日益普及和信息化时代的到来,编程作为一种现代技能,其影响已不再局限于专业领域,而是逐步渗透到人们的日常生活之中。探讨编程与生活琐事之间的关系,有助于我们更好地理解如何将技术智慧应用于日常管理,提升…...

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

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

05 MP之ActiveRecord模式+SimpleQuery
1. ActiveRecord ActiveRecord(活动记录,简称AR),是一种领域模型模式,特点是一个模型类对应关系型数据库中的一个表,而模型类的一个实例对应表中的一行记录。 其目标是通过围绕一个数据对象, 进行全部的CRUD操作。 1.1 让实体类…...
git diff查看比对两次不同时间点提交的异同
git diff查看比对两次不同时间点提交的异同 用 git diff命令: git diff commit-id-1 commit-id-2 不同commit-id在不同的时间点提交产生,因为也可以认为git diff是比对两个不同时间点的代码异同。 git diff比较不同commit版本的代码文件异同_git diff c…...

基于muduo网络库开发服务器程序和CMake构建项目 笔记
跟着施磊老师做C项目,施磊老师_腾讯课堂 (qq.com) 一、基于muduo网络库开发服务器程序 组合TcpServer对象创建EventLoop事件循环对象的指针明确TcpServer构造函数需要什么参数,输出ChatServer的构造函数在当前服务器类的构造函数当中,注册处理连接的回调函数和处理…...
前端支持下载模板、导入数据、导出数据(excel格式)
前言 xlsx是由SheetJS开发的一个处理excel文件的npm库,适用于前端开发者实现下载模板、导入导出excel文件等需求,演示的项目的技术栈为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的用法详解 大家好,我是免费搭建查券返利机器人赚佣金就用微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿!今天,我们将深入研究数据库连接中conn.execute的用法,解析它的功能、…...
GetBuffer() 与 ReleaseBuffer() 使用详解
GetBuffer() 与 ReleaseBuffer() 使用详解 大家好,我是免费搭建查券返利机器人赚佣金就用微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿!今天,我们将深入研究在编程中常用的GetBuffer()与ReleaseBuff…...

Flink CEP(基本概念)
Flink CEP 在Flink的学习过程中,我们已经掌握了从基本原理和核心层的DataStream API到底层的处理函数,再到应用层的Table API和SQL的各种手段,可以应对实际应用开发的各种需求。然而,在实际应用中,还有一类更为复…...
[AIGC] Spring Gateway与 nacos 简介
文章目录 Spring Gateway简介主要特性优点总结 Nacos简介主要特性优点总结 Spring Gateway 简介 Spring Gateway是一个基于Spring Framework的工具,用于构建和管理微服务架构中的网关。它提供了一种简单而灵活的方式来路由和过滤请求,以及在微服务之间…...

2024-2-3-复习作业
1> 要求: 效果图: 2> 要求: 效果图: 3> 要求: 效果图: 源代码: #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框架,可以按照以下步骤进行学习和实践:…...

1Panel应用推荐:青龙定时任务管理平台
1Panel(github.com/1Panel-dev/1Panel)是一款现代化、开源的Linux服务器运维管理面板,它致力于通过开源的方式,帮助用户简化建站与运维管理流程。为了方便广大用户快捷安装部署相关软件应用,1Panel特别开通应用商店&am…...

BUUCTF-Real-[struts2]s2-013
struts2的标签中 <s:a> 和 <s:url> 都有一个 includeParams 属性,可以设置成如下值none - URL中不包含任何参数(默认) get - 仅包含URL中的GET参数 all - 在URL中包含GET和POST参数 当includeParamsall的时候,会将本次…...

【题解-洛谷】B3622 枚举子集(递归实现指数型枚举)
题目:B3622 枚举子集(递归实现指数型枚举) 题目描述 今有 n n n 位同学,可以从中选出任意名同学参加合唱。 请输出所有可能的选择方案。 输入格式 仅一行,一个正整数 n n n。 输出格式 若干行,每行…...
使用 C/C++ 和 OpenCV 提取图像的感兴趣区域 (ROI)
使用 C/C 和 OpenCV 提取图像的感兴趣区域 (ROI) 在计算机视觉中,感兴趣区域 (Region of Interest, ROI) 是指从图像中选择的一个特定区域,我们希望对其进行进一步的处理或分析。例如,在人脸识别中,ROI 就是包含人脸的矩形框。Op…...

从上下文学习和微调看语言模型的泛化:一项对照研究
大型语言模型表现出令人兴奋的能力,但也可以从微调中表现出令人惊讶的狭窄泛化。例如,他们可能无法概括为简单的关系反转,或者无法根据训练信息进行简单的逻辑推理。这些未能从微调中概括出来的失败可能会阻碍这些模型的实际应用。另一方面&a…...
如何从零开始建设一个网站?
当你没有建站的基础和建站的知识,那么应该如何开展网站建设和网站管理。而今天的教程是不管你是为自己建站还是为他人建站都适合的。本教程会指导你如何进入建站,将建站的步骤给大家分解: 首先我们了解一下,建站需要那些步骤和流程…...
go中的接口返回设计思想
go中的接口返回设计思想 前言 在学习AI编码过程中,产生了类似以下结构的代码 : type MQClient interface {PublishMessage(queue string, message interface{}) error...... } ... type RabbitMQClient struct {conn *amqp.Connectionchannel *amqp.C…...

day029-Shell自动化编程-计算与while循环
文章目录 1. read 交互式初始化变量1.1 案例-安装不同的软件1.2 案例-比较大小 2. 计算2.1 bc2.2 awk2.3 expr2.4 let2.5 案例-计算内存的空闲率2.6 案例-检查域名过期时间和https整数过期时间 3. 循环3.1 循环控制语句3.2 for循环-c语言格式3.3 while循环3.3.1 案例-猜数字3.3…...
【nano与Vim】常用命令
使用nano编辑器 保存文件 : 按下CtrlO组合键,然后按Enter键确认文件名。 退出编辑器 : 按下CtrlX组合键。 使用vi或vim编辑器 保存文件 : 按Esc键退出插入模式,然后输入:w并按Enter键保存文件。 退出编辑器 …...

完美搭建appium自动化环境
🍅 点击文末小卡片,免费获取软件测试全套资料,资料在手,涨薪更快 桌面版appium提供可视化操作appium主要功能的使用方式,对于初学者非常适用。 如何在windows平台安装appium桌面版呢,大体分两个步骤&…...

CSS 平铺+自动换行效果
先上效果图 样式 <template><div class"activity-questions"><h1>活动题库</h1><div v-if"loading" class"loading">加载中...</div><div v-else><div v-if"questions.length 0" clas…...
【Qt】:设置新建类模板
完整的头文件模板 #ifndef %FILENAME%_H #define %FILENAME%_H/*** brief The %CLASSNAME% class* author %USER%* date %DATE%*/ class %CLASSNAME% { public:%CLASSNAME%();~%CLASSNAME%();// 禁止拷贝构造和赋值%CLASSNAME%(const %CLASSNAME%&) delete;%CLASSNAME%&a…...