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).text

    srcUrl = 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).text

    srcUrl = 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线程应该还会快一些),感觉上来讲协程最快

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

使用vs2022将.net8的应用程序发布为一个单独文件

在使用.NetCore3.1时&#xff0c;可以通过设置以下工程配置文本来将项目发布为一个单独的应用程序文件&#xff1a; <Project Sdk"Microsoft.NET.Sdk.WindowsDesktop"><PropertyGroup><TargetFramework>netcoreapp3.1</TargetFramework><…

Jmeter性能测试: 基于JDK 21 安装 Jmeter 5.6.3

目录 一、实验 1.环境 2.JDK下载 3.Jmeter下载 4.Windows安装JDK 21 5.Windows安装Jmeter 5.6.3 6.Linux安装JDK 21 7.Linux安装Jmeter 5.6.3 二、问题 1. Linux 的profile、bashrc、bash_profile文件有哪些区别 一、实验 1.环境 &#xff08;1&#xff09;主机 表…

C语言之指针的地址和指向的内容总结(八十四)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

计算机网络:体系结构知识点汇总

文章目录 一、计算机网络概述1.1概念及功能1.2组成和分类1.3性能指标 二、体系结构与参考模型2.1分层结构、协议、接口、服务2.2OSI参考模型2.3TCP/IP参考模型 一、计算机网络概述 1.1概念及功能 计算机网络就是通过各个节点&#xff0c;这个节点包括终端的电脑&#xff0c;手…

opencv#32 可分离滤波

滤波的可分离性 就是将一个线性滤波变成多个线性滤波&#xff0c;这里面具体所指的是变成x方向的线性滤波和y方向的线性滤波。无论先做x方向的滤波还是y方向滤波&#xff0c;两者的叠加结果是一致的&#xff0c;这个性质取决于滤波操作是并行的&#xff0c;也就是每一个图像在滤…

研发日记,Matlab/Simulink避坑指南(六)——字节分割Bug

文章目录 前言 背景介绍 问题描述 分析排查 解决方案 总结归纳 前言 见《研发日记&#xff0c;Matlab/Simulink避坑指南&#xff08;一&#xff09;——Data Store Memory模块执行时序Bug》 见《研发日记&#xff0c;Matlab/Simulink避坑指南(二)——非对称数据溢出Bug》…

文旅项目包括什么?

文旅项目是指与文化和旅游相结合的项目&#xff0c;旨在通过提供丰富的文化体验和旅游服务来吸引游客&#xff0c;促进地方经济发展。 文旅项目通常包括多个方面&#xff0c;以下是对每块内容的详细介绍&#xff1a; 文化旅游景区&#xff1a;这类项目以展示人类文化和历史遗产…

单片机学习笔记---独立按键控制LED显示二进制

这节我们来实现独立按键的第三个功能&#xff0c;独立按键控制LED显示二进制 新创建一个工程文件&#xff0c;然后上来我们就要把基本框架写好&#xff0c;这是基本的习惯 老规矩&#xff0c;然后把Delay 1ms的代码复制过来 复制过来后改造一下&#xff1a; 把1ms删掉&#x…

近20k stars,GSYVideoPlayer一款优秀的视频播放器

近20k stars&#xff0c;GSYVideoPlayer一款优秀的视频播放器 引言 在现代社会中&#xff0c;视频已经成为人们获取信息和娱乐的重要形式。为了提供更好的观看体验&#xff0c;开发一款优秀的视频播放器变得至关重要。而GSYVideoPlayer作为一款功能强大、稳定可靠的视频播放器…

03 SB实战 -微头条之首页门户模块(跳转某页面自动展示所有信息+根据hid查询文章全文并用乐观锁修改阅读量)

1.1 自动展示所有信息 需求描述: 进入新闻首页portal/findAllType, 自动返回所有栏目名称和id 接口描述 url地址&#xff1a;portal/findAllTypes 请求方式&#xff1a;get 请求参数&#xff1a;无 响应数据&#xff1a; 成功 {"code":"200","mes…

最新多功能PHP图床源码 /兰空图床Lsky Pro开源版v2.1/ 单纯的图床程序源码

源码介绍&#xff1a; Lsky Pro 是一个用于在线上传、管理图片的图床程序&#xff0c;中文名&#xff1a;兰空图床&#xff0c;你可以将它作为自己的云上相册&#xff0c;亦可以当作你的写作贴图库。 该程序的最初版本诞生于2017年10月&#xff0c;由ThinkPHP 5框架精心打造而…

20240127使用ffmpeg合并音轨和视频通道为mp4

20240127使用ffmpeg合并音轨和视频通道为mp4 2024/1/27 11:11 百度&#xff1a;ffmpeg 合并 音频和视频 mp4 ffmpeg -i 视频文件名.mp4 -i 音频文件名.mp3 -c:v copy -c:a aac -strict experimental 输出文件名.mp4ffmpeg -i "videoplayback (1).mp4" -i videoplay…

vue项目中使用Element多个Form表单同时验证

一、项目需求 在项目中一个页面中需要实现多个Form表单&#xff0c;并在页面提交时需要对多个Form表单进行校验&#xff0c;多个表单都校验成功时才能提交。 二、实现效果 三、多个表单验证 注意项&#xff1a;多个form表单&#xff0c;每个表单上都设置单独的model和ref&am…

Python tkinter (6) Listbox

Python的标准Tk GUI工具包的接口 tkinter系列文章 python tkinter窗口简单实现 Python tkinter (1) —— Label标签 Python tkinter (2) —— Button标签 Python tkinter (3) —— Entry标签 Python tkinter (4) —— Text控件 GUI 目录 Listbox 创建listbox 添加元素…

51-16 FusionAD 用于自动驾驶预测与规划任务的多模态融合论文精读

今天要分享的是基于BEV的多模态、多任务、端到端自动驾驶模型FusionAD&#xff0c;其专注于自动驾驶预测和规划任务。这项工作首次发表于2023年8月2日&#xff0c;性能超越了2023 CVPR最佳论文UniAD模型。论文题目是FusionAD: Multi-modality Fusion for Prediction and Planni…

【Java 数据结构】LinkedList与链表

LinkedList与链表 1. ArrayList的缺陷2. 链表2.1 链表的概念及结构2.2 链表的实现 3. LinkedList的模拟实现4.LinkedList的使用4.1 什么是LinkedList4.2LinkedList的使用 5. ArrayList和LinkedList的区别 1. ArrayList的缺陷 上节课已经熟悉了ArrayList的使用&#xff0c;并且…

vue3+elementPlus pc和小程序ai聊天文生图

websocket封装可以看上一篇文章 //pc端 <template><div class"common-layout theme-white"><el-container><el-aside><div class"title-box"><span>AI Chat</span></div><div class"chat-list&…

VMware安装RHEL-磁盘划分和分区

本文探讨了在VMware虚拟机上安装RHEL时遇到的磁盘划分和分区问题。文章详细介绍了磁盘划分过程中可能出现的问题&#xff0c;特别是在选择磁盘类型时可能导致找不到磁盘的情况。通过清晰的步骤和解决方法&#xff0c;读者可以更好地理解如何正确进行磁盘划分以及如何解决磁盘无…

银行数据仓库体系实践(3)--数据架构

狭义的数据仓库数据架构用来特指数据分布&#xff0c;广义的数据仓库数据架构还包括数据模型、数据标准和数据治理。即包含相对静态部分如元数据、业务对象数据模型、主数据、共享数据&#xff0c;也包含相对动态部分如数据流转、ETL、整合、访问应用和数据全生命周期管控治理。…

AWS 专题学习 P12 (CloudWatch、CloudTrail、AWS Config)

文章目录 专题总览1. CloudWatch1.1 Amazon CloudWatch Metrics1.2 CloudWatch Metric Streams1.3 CloudWatch LogsCloudWatch Logs - SourcesCloudWatch Logs Metric Filter & InsightsCloudWatch Logs – S3 ExportCloudWatch Logs SubscriptionsCloudWatch Logs Aggrega…