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的时候,会将本次…...
Python|GIF 解析与构建(5):手搓截屏和帧率控制
目录 Python|GIF 解析与构建(5):手搓截屏和帧率控制 一、引言 二、技术实现:手搓截屏模块 2.1 核心原理 2.2 代码解析:ScreenshotData类 2.2.1 截图函数:capture_screen 三、技术实现&…...
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以? 在 Golang 的面试中,map 类型的使用是一个常见的考点,其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...
Keil 中设置 STM32 Flash 和 RAM 地址详解
文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...
tree 树组件大数据卡顿问题优化
问题背景 项目中有用到树组件用来做文件目录,但是由于这个树组件的节点越来越多,导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多,导致的浏览器卡顿,这里很明显就需要用到虚拟列表的技术&…...
初探Service服务发现机制
1.Service简介 Service是将运行在一组Pod上的应用程序发布为网络服务的抽象方法。 主要功能:服务发现和负载均衡。 Service类型的包括ClusterIP类型、NodePort类型、LoadBalancer类型、ExternalName类型 2.Endpoints简介 Endpoints是一种Kubernetes资源…...
JavaScript 数据类型详解
JavaScript 数据类型详解 JavaScript 数据类型分为 原始类型(Primitive) 和 对象类型(Object) 两大类,共 8 种(ES11): 一、原始类型(7种) 1. undefined 定…...
windows系统MySQL安装文档
概览:本文讨论了MySQL的安装、使用过程中涉及的解压、配置、初始化、注册服务、启动、修改密码、登录、退出以及卸载等相关内容,为学习者提供全面的操作指导。关键要点包括: 解压 :下载完成后解压压缩包,得到MySQL 8.…...
tomcat指定使用的jdk版本
说明 有时候需要对tomcat配置指定的jdk版本号,此时,我们可以通过以下方式进行配置 设置方式 找到tomcat的bin目录中的setclasspath.bat。如果是linux系统则是setclasspath.sh set JAVA_HOMEC:\Program Files\Java\jdk8 set JRE_HOMEC:\Program Files…...
6️⃣Go 语言中的哈希、加密与序列化:通往区块链世界的钥匙
Go 语言中的哈希、加密与序列化:通往区块链世界的钥匙 一、前言:离区块链还有多远? 区块链听起来可能遥不可及,似乎是只有密码学专家和资深工程师才能涉足的领域。但事实上,构建一个区块链的核心并不复杂,尤其当你已经掌握了一门系统编程语言,比如 Go。 要真正理解区…...
企业大模型服务合规指南:深度解析备案与登记制度
伴随AI技术的爆炸式发展,尤其是大模型(LLM)在各行各业的深度应用和整合,企业利用AI技术提升效率、创新服务的步伐不断加快。无论是像DeepSeek这样的前沿技术提供者,还是积极拥抱AI转型的传统企业,在面向公众…...
