当前位置: 首页 > 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;会将本次…...

云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?

大家好&#xff0c;欢迎来到《云原生核心技术》系列的第七篇&#xff01; 在上一篇&#xff0c;我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在&#xff0c;我们就像一个拥有了一块崭新数字土地的农场主&#xff0c;是时…...

测试markdown--肇兴

day1&#xff1a; 1、去程&#xff1a;7:04 --11:32高铁 高铁右转上售票大厅2楼&#xff0c;穿过候车厅下一楼&#xff0c;上大巴车 &#xffe5;10/人 **2、到达&#xff1a;**12点多到达寨子&#xff0c;买门票&#xff0c;美团/抖音&#xff1a;&#xffe5;78人 3、中饭&a…...

数据链路层的主要功能是什么

数据链路层&#xff08;OSI模型第2层&#xff09;的核心功能是在相邻网络节点&#xff08;如交换机、主机&#xff09;间提供可靠的数据帧传输服务&#xff0c;主要职责包括&#xff1a; &#x1f511; 核心功能详解&#xff1a; 帧封装与解封装 封装&#xff1a; 将网络层下发…...

AspectJ 在 Android 中的完整使用指南

一、环境配置&#xff08;Gradle 7.0 适配&#xff09; 1. 项目级 build.gradle // 注意&#xff1a;沪江插件已停更&#xff0c;推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...

Angular微前端架构:Module Federation + ngx-build-plus (Webpack)

以下是一个完整的 Angular 微前端示例&#xff0c;其中使用的是 Module Federation 和 npx-build-plus 实现了主应用&#xff08;Shell&#xff09;与子应用&#xff08;Remote&#xff09;的集成。 &#x1f6e0;️ 项目结构 angular-mf/ ├── shell-app/ # 主应用&…...

QT3D学习笔记——圆台、圆锥

类名作用Qt3DWindow3D渲染窗口容器QEntity场景中的实体&#xff08;对象或容器&#xff09;QCamera控制观察视角QPointLight点光源QConeMesh圆锥几何网格QTransform控制实体的位置/旋转/缩放QPhongMaterialPhong光照材质&#xff08;定义颜色、反光等&#xff09;QFirstPersonC…...

纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join

纯 Java 项目&#xff08;非 SpringBoot&#xff09;集成 Mybatis-Plus 和 Mybatis-Plus-Join 1、依赖1.1、依赖版本1.2、pom.xml 2、代码2.1、SqlSession 构造器2.2、MybatisPlus代码生成器2.3、获取 config.yml 配置2.3.1、config.yml2.3.2、项目配置类 2.4、ftl 模板2.4.1、…...

go 里面的指针

指针 在 Go 中&#xff0c;指针&#xff08;pointer&#xff09;是一个变量的内存地址&#xff0c;就像 C 语言那样&#xff1a; a : 10 p : &a // p 是一个指向 a 的指针 fmt.Println(*p) // 输出 10&#xff0c;通过指针解引用• &a 表示获取变量 a 的地址 p 表示…...

Android写一个捕获全局异常的工具类

项目开发和实际运行过程中难免会遇到异常发生&#xff0c;系统提供了一个可以捕获全局异常的工具Uncaughtexceptionhandler&#xff0c;它是Thread的子类&#xff08;就是package java.lang;里线程的Thread&#xff09;。本文将利用它将设备信息、报错信息以及错误的发生时间都…...

el-amap-bezier-curve运用及线弧度设置

文章目录 简介示例线弧度属性主要弧度相关属性其他相关样式属性完整示例链接简介 ‌el-amap-bezier-curve 是 Vue-Amap 组件库中的一个组件,用于在 高德地图 上绘制贝塞尔曲线。‌ 基本用法属性path定义曲线的路径,可以是多个弧线段的组合。stroke-weight线条的宽度。stroke…...