9.异步爬虫

异步爬虫可以理解为非只单线程爬虫

我们下面做个例子,之前我们通过单线程爬取过梨视频 https://blog.csdn.net/potato123232/article/details/135672504

在保存视频的时候会慢一些,为了提升效率,我们使用异步爬虫爬取

目录

1  线程池

2  单线程+异步协程

2.1  aiohttp的基本使用

2.2  爬取梨视频

3  单线程,协程,多线程的运行速度比较


1  线程池

线程池的基本用法在这里有提到 python并发任务-CSDN博客

多线程应仅用于耗时的部分,如果我们为了省事去将所有部分都封装为一个函数就容易出错

  • 走单线程可以成功爬取10个视频,当我将所有过程封装为一个函数时,使用多线程爬取会报错。在JS中的异步也会有这种问题,就像是请求还没请求完,后面加载就加载上了
import requests
from lxml import etree
import random
import re
from multiprocessing.dummy import Pool# 保存根页面
url = 'https://www.pearvideo.com/popular'
headers={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36'}
response = requests.get(url=url,headers=headers)
response.encoding = response.apparent_encoding
with open('./test.html','w',encoding='utf-8') as f:f.write(response.text)
print(response)# 获取所有细节页面url
detail_htmls = []
tree = etree.HTML(response.text)
for i in range(1,len(tree.xpath('//*[@id="popularList"]/li'))+1):detail_htmls.append({'url':'https://www.pearvideo.com/' + tree.xpath('//*[@id="popularList"]/li[{}]/a/@href'.format(i))[0],'title':tree.xpath('//*[@id="popularList"]/li['+ str(i) +']/div[2]/a/h2/text()')[0]})# print(detail_htmls)
p = re.compile(r'.*\/(.*?)-\d')video_detail_list = []
for i in detail_htmls:contId = i['url'].split('_')[-1]mrd = round(random.random(), 16)headers['Host'] = 'www.pearvideo.com'headers['Referer'] = i['url']response = requests.get(url='https://www.pearvideo.com/videoStatus.jsp?contId=' + str(contId) + '&mrd=' + str(mrd),headers=headers).textsrcUrl = eval(response).get('videoInfo').get('videos').get('srcUrl')need_change_part = p.findall(srcUrl)[0]true_video_url = srcUrl.split(need_change_part)[0] + 'cont-' + contId + srcUrl.split(need_change_part)[1]video_name = re.sub(r'[\\/:*?"<>|]', '', i['title'])video_detail_list.append({"name":video_name,"url":true_video_url})print(video_detail_list)
def get_video(item):response = requests.get(item['url'])with open('./result/' + str(item['name']) + '.mp4', 'wb') as fp:fp.write(response.content)print(item['url'] + '下载成功')pool = Pool(4)
pool.map(get_video,video_detail_list)

耗时的部分只有保存,所以我们保存的部分剥离出来,这样就能成功爬取10个视频

2  单线程+异步协程

2.1  aiohttp的基本使用

我们先做个简单的服务,这三个服务无论请求哪一个都会等待两秒,然后返回一个字符串

之后我们尝试只用asyncio发起异步请求

从耗时来看这段代码并没有发起异步请求

这个时候我们可以使用aiohttp进行异步请求

  • 这个能看懂就行了,如果到了一定要使用的时候,看看别人怎么写的抄一抄就完了
  • 如果不加最后打印之前的await,那么就有可能会打印不出来东西,由于请求是异步的,他会跳过请求而执行下面,就像js中的定时器
  • response.text()是返回字符串类型的响应,read()是返回二进制类型的响应,json()返回的是json对象类型的响应
  • 除了发get请求还可以发post请求,参数与requests.get(),requests.post()基本一致(get用的params一致,post用的data一致,请求头headers一致,aiohttp的代理参数名为proxy,proxy参数值为字符串)

2.2  爬取梨视频

异步保存文件可以借助 aiofiles

import requests
from lxml import etree
import random
import re
import aiohttp
import asyncio
import aiofiles# 保存根页面
url = 'https://www.pearvideo.com/popular'
headers={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36'}
response = requests.get(url=url,headers=headers)
response.encoding = response.apparent_encoding
with open('./test.html','w',encoding='utf-8') as f:f.write(response.text)
print(response)# 获取所有细节页面url
detail_htmls = []
tree = etree.HTML(response.text)
for i in range(1,len(tree.xpath('//*[@id="popularList"]/li'))+1):detail_htmls.append({'url':'https://www.pearvideo.com/' + tree.xpath('//*[@id="popularList"]/li[{}]/a/@href'.format(i))[0],'title':tree.xpath('//*[@id="popularList"]/li['+ str(i) +']/div[2]/a/h2/text()')[0]})# print(detail_htmls)
p = re.compile(r'.*\/(.*?)-\d')video_detail_list = []
for i in detail_htmls:contId = i['url'].split('_')[-1]mrd = round(random.random(), 16)headers['Host'] = 'www.pearvideo.com'headers['Referer'] = i['url']response = requests.get(url='https://www.pearvideo.com/videoStatus.jsp?contId=' + str(contId) + '&mrd=' + str(mrd),headers=headers).textsrcUrl = eval(response).get('videoInfo').get('videos').get('srcUrl')need_change_part = p.findall(srcUrl)[0]true_video_url = srcUrl.split(need_change_part)[0] + 'cont-' + contId + srcUrl.split(need_change_part)[1]video_name = re.sub(r'[\\/:*?"<>|]', '', i['title'])video_detail_list.append({"name":video_name,"url":true_video_url})print(video_detail_list)async def test(item):async with aiohttp.ClientSession() as session:async with await session.get(item['url']) as response:async with aiofiles.open('./result/' + str(item['name']) + '.mp4', 'wb') as fp:await fp.write(await response.read())print(item['url'] + '下载成功')future_list = []
for something1 in video_detail_list:a = test(something1)future = asyncio.ensure_future(a)future_list.append(future)loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(future_list))

可以爬取成功,每个视频都可以点开看

但是代码在pycharm的返回值并不是0

3  单线程,协程,多线程的运行速度比较

就梨视频的例子来说,单线程最慢,多线程第二(因为我只用4线程,如果10线程应该还会快一些),感觉上来讲协程最快

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

类和对象 第五部分第三小节:递增运算符重载

作用&#xff1a;通过重载递增运算符&#xff0c;实现自己的整型数据递增 代码案例 1.重载前置运算符 #include <iostream> #include <string> using namespace std;class MyInteger {friend ostream& operator<<(ostream& out, const MyInteger&…

简盒工具箱iapp源码

一款工具箱兼做软件库。 新增远程更新功能 修复了部分失效功能 修复了偶尔会卡在启动页的情况 源码下载&#xff1a;https://download.csdn.net/download/m0_66047725/88776737 更多资源下载&#xff1a;关注我。

Open CASCADE学习|读取STEP文件并显示

STEP文件是基于ISO 10303标准创建的三维模型数据交换文件&#xff0c;也称为产品模型数据交换标准&#xff08;Standard Exchange of Product data model&#xff09;。这种文件格式旨在提供一个不依赖具体系统的中性机制&#xff0c;实现产品数据的交换和共享。 STEP文件是一…

C#实现带光标的截图

1&#xff0c;目的&#xff1a; 可通过热键实现带光标与不带光标两种模式的截图。 2&#xff0c;知识点&#xff1a; 快捷键的注册与注销。 [DllImport("user32.dll", SetLastError true)] public static extern bool RegisterHotKey(IntPtr hWnd, int id, KeyMo…

【算法与数据结构】139、LeetCode单词拆分

文章目录 一、题目二、解法三、完整代码 所有的LeetCode题解索引&#xff0c;可以看这篇文章——【算法和数据结构】LeetCode题解。 一、题目 二、解法 思路分析&#xff1a;本题可以看做一个动态规划问题。其中&#xff0c;字符串s是背包&#xff0c;而字典中的单词就是物品。…

Dubbo框架注册中心-Zookeeper搭建

Dubbo 是阿里巴巴公司开源的高性能、轻量级的Java RPC框架&#xff0c;致力于提供高性能。 Dubbo官网 本篇开始dubbo的第一篇&#xff0c;注册中心 ZooKeeper 环境搭建。 环境前置&#xff1a;由于Zookeeper是基于Java环境&#xff0c;必须安装有JDK。查看命令 java -version。…

服务端开发小记01——Tomcat

Tomcat Tomcat简介Tomcat在Linux下的安装Tomcat验证Tomcat常用命令&#xff08;Linux下&#xff09; Tomcat简介 Tomcat是一个Web容器&#xff0c;JavaEE程序可以在此运行。Tomcat是一个中间件&#xff0c;在B/S架构中&#xff0c;浏览器发出的http请求经过tpmcat中间件&#…

降压模块LM2596S的操作使用

一、技术参数 二、使用说明 1.引脚说明&#xff1a; IN输入正极 IN-输入负极 OUT输出正极 OUT-输出负极 2.输入电压范围&#xff1a;直流3.2V 至 46V (输入的电压必须比要输出的电压高1.5V以上。不能升压) 3.输出电压范围&#xff1a;直流 1.25V至 35V 电压连续可调&#…

SBDD的节点选择(Node selection)和树的扩展(Tree expansion)的操作是怎么进行的?

Node selection: 1&#xff09;选择规则&#xff1a; “focus atom”是从生成的原子中选出的&#xff0c;如果一个原子没有“capped”&#xff0c;那么它就可以被选为“focus atom”。 一个原子被“capped”是因为它的化合价约束&#xff08;valency constraint&#xff09;…

内网安全:NTLM-Relay

目录 NTLM认证过程以及攻击面 NTLM Relay攻击 NTLM攻击总结 实验环境说明 域横向移动&#xff1a;NTLM中继攻击 攻击条件 实战一&#xff1a;NTLM中继攻击-CS转发上线MSF 原理示意图 一. CS代理转发 二. MSF架设路由 三. 适用smb_relay模块进行中继攻击 域横向移动…

【李宏毅机器学习】Transformer 内容补充

视频来源&#xff1a;10.【李宏毅机器学习2021】自注意力机制 (Self-attention) (上)_哔哩哔哩_bilibili 发现一个奇怪的地方&#xff0c;如果直接看ML/DL的课程的话&#xff0c;有很多都是不完整的。开始思考是不是要科学上网。 本文用作Transformer - Attention is all you…

ASP.NET Core基础之用扩展方法封装服务配置

阅读本文你的收获 了解C#中的扩展方法机制学会在ASP.NET Core 中&#xff0c;用扩展方法封装服务配置&#xff0c;使得代码更加简洁 一、什么是扩展方法 扩展方法使能够向现有类型添加方法&#xff0c;而无需创建新的派生类型、重新编译或以其他方式修改原始类型。 扩展方法…

Python笔记12-多线程、网络编程、正则表达式

文章目录 多线程网络编程正则表达式 多线程 现代操作系统比如Mac OS X&#xff0c;UNIX&#xff0c;Linux&#xff0c;Windows等&#xff0c;都是支持“多任务”的操作系统。 进程&#xff1a; 就是一个程序&#xff0c;运行在系统之上&#xff0c;那么便称之这个程序为一个运…

CTF CRYPTO 密码学-7

题目名称&#xff1a;敲击 题目描述&#xff1a; 让我们回到最开始的地方 0110011001101100011000010110011101111011011000110110010100110011011001010011010100110000001100100110001100101101001101000011100001100011001110010010110100110100011001000011010100110000…

微搭低代码从入门到精通01应用介绍

目录 1 学习路线图2 应用介绍3 编辑器介绍总结 低代码的概念于2014年由 Forrester 首次正式提出。其将低代码定义为&#xff1a;能够以“最少的手写代码”和设置快速开发应用、配置和部署业务应用程序。 不同应用厂商的解法不一样&#xff0c;Gartner评估了400多款低代码/无代码…

Spark Exchange节点和Partitioning

​Exchange 在explain时&#xff0c;常看到Exchange节点&#xff0c;这个节点其实就是发生了数据交换 此图片来自于网络截取 BroadcastExchangeExec 主要是用来广播的 ShuffleExchangeExec 里面决定了数据分布的方式和采用哪种shuffle 在这里可以看到好几种不同的分区器 shuf…

Android 13.0 SystemUI下拉状态栏定制二 锁屏页面横竖屏时钟都居中功能实现二

1.前言 在13.0的系统rom定制化开发中,在关于systemui的锁屏页面功能定制中,由于在平板横屏锁屏功能中,时钟显示的很大,并且是在左旁边居中显示的, 由于需要和竖屏显示一样,所以就需要用到小时钟显示,然后同样需要居中,所以就来分析下相关的源码,来实现具体的功能 如图…

Spring 事务原理二

该说些什么呢&#xff1f;一连几天&#xff0c;我都沉溺在孤芳自赏的思维中无法自拔。不知道自己为什么会有这种令人不齿的表现&#xff0c;更不知道这颗定时炸弹何时会将人炸的粉身碎骨。好在儒派宗师曾老夫子“吾日三省吾身”的名言警醒了我。遂潜心自省&#xff0c;溯源头以…

条件变量、线程池以及线程的GDB调试学习笔记

目录 一、条件变量 二、线程池概念和实现 三、线程的GDB调试 一、条件变量 应用场景&#xff1a;生产者消费者问题&#xff0c;是线程同步的一种手段。 必要性&#xff1a;为了实现等待某个资源&#xff0c;让线程休眠&#xff0c;提高运行效率 使用步骤&#xff1a; 初始…

深入理解C语言(3):自定义类型详解

文章主题&#xff1a;结构体类型详解&#x1f30f;所属专栏&#xff1a;深入理解C语言&#x1f4d4;作者简介&#xff1a;更新有关深入理解C语言知识的博主一枚&#xff0c;记录分享自己对C语言的深入解读。&#x1f606;个人主页&#xff1a;[₽]的个人主页&#x1f3c4;&…