Python爬虫--高性能的异步爬虫(五)

本文章所涉及的案例仅供学习研究,如若侵犯到贵公司权益请联系2328409226@qq.com第一时间进行删除;各位朋友切忌用于一切非法途径,否则后果自行承担!

文章知识点

  1. 单线程、多线程
  2. 线程池
  3. 单协程、多协程
  4. headers中Refere的作用
  5. 异步模块aiohttp使用

本章节学习内容来自Python爬虫7天速成(2020全新合集)无私分享 Python


一、异步爬虫概述

高性能异步爬虫 :在爬虫中使用异步实现高性能的数据爬取操作

传统爬取数据的操作是顺序操作,下面看一个实例

  • 代码
    在这里插入图片描述
    在这里插入图片描述

分析上述代码可知 for循环中的get方法会阻塞程序,只有请求到的数据获取后,才可以进行下一条url中对应的数据

上述可知,使用异步会提高爬虫程序的数据获取效率

  • 异步爬虫的方式
  • 多线程,多进程
    好处:可以为相关阻塞的操作单独开启线程或进程,阻塞操作就可以异步进行
    弊端:无法无限制的开启多线程或者多进程
  • 线程池、进程池(适当的使用)
    好处:我们可以降低系统对进程或者线程创建和销毁的一个频率,从而很好的降低系统的开销
    弊端:池中线程或进程的数量是有上限的。

二、线程池的基本使用

  • 单线程串行方式使用
import time
# 单线程串行方式运行

def get_page(str):
	print("正在下载:",str)
	time.sleep(2)
	print("下载成功:",str)
name_list = ['xiaozi','aa','bb','cc']

start_time = time.time()

for i in range(len(name_list)):
	get_page(name_list[i])

end_time = time.time()

print('%d second' % (end_time - start_time))

在这里插入图片描述

  • 线程池的使用
import time
# 导入线程池模块对应的类
from multiprocessing.dummy import Pool
# 使用线程池方式执行
# Pool一定是应用在阻塞操作中的  get_page

start_time = time.time()
def get_page(str):
	print("正在下载:",str)
	time.sleep(2)
	print("下载成功:",str)
name_list = ['xiaozi','aa','bb','cc']

# 实例化一个线程池对象
pool = Pool(4)  # 4个线程对象
# 将列表中每一个列表元素传递给get_page进行处理
# pool.map的返回值就是方法get_page()的返回值
pool.map(get_page,name_list)

end_time = time.time()
print(end_time-start_time)

在这里插入图片描述


三、异步爬取线程池案例使用⭐⭐

本案例仅供学习研究,如若侵犯到贵公司权益请联系2328409226@qq.com第一时间进行删除;各位朋友切忌用于一切非法途径,否则后果自行承担!
在这里插入图片描述

以上视频是我们需要爬取的具体视频,键盘上F12查看并且分析相关的detail_url和name,

  • 信息分析
    在这里插入图片描述
    在这里插入图片描述

在这里插入图片描述

到此你可能认为使用xpath进行地址获取下载即可,但是这样就错了,你使用etree进行解析出来的是空值,因为这个页面的有些数据就是动态加载出来的,如下进行验证:

在这里插入图片描述

到此为止,我们发现数据是动态加载出来的,因此我们就需要找出真正要下载的地址链接在哪里?
在此感谢这两位博主提供的思路:

  1. python爬虫-线程池案例
  2. [python]生活板块最热视频爬取

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

  • 地址信息对比
  • 报错404:
    https://video.pearvideo.com/mp4/adshort/20210927/1632790695959-15774345_adpkg-ad_hd.mp4
  • 正确的路径:
    https://video.pearvideo.com/mp4/adshort/20210927/cont-1742572-15774345_adpkg-ad_hd.mp4

此外多次实验发现获取报错404地址的网址有一部分数字是随机产生的,

在这里插入图片描述

  • 真实信息地址
    在这里插入图片描述

在这里插入图片描述

  • 宝藏老师|数学老师的浪漫:用函数讲述自己的爱情故事:
    https://www.pearvideo.com/videoStatus.jsp?contId=1742617&mrd=0.6446715186101781
  • 小伙肿瘤医院旁开共享厨房,宣传5元吃饱亏本运营:
    https://www.pearvideo.com/videoStatus.jsp?contId=1742572&mrd=0.5091336020577668

通过以上两个视频的地址不难发现它们网址都有共同的特点包含contId,我们再回到原始的视频网页数据查看:

在这里插入图片描述
在这里插入图片描述

后来由于个人水平问题这个属性值解析出错,因此换了思路:

在这里插入图片描述

  • 解析地址
    在这里插入图片描述
https://www.pearvideo.com/videoStatus.jsp?contId=1742572&mrd=0.8749545784196235
https://www.pearvideo.com/videoStatus.jsp?contId=1742572&mrd=0.5510063831062151
https://www.pearvideo.com/videoStatus.jsp?contId=1742572&mrd=0.5091336020577668

3.1 代码

  • 源代码
import requests
from lxml import etree
import random
import json
from multiprocessing.dummy import Pool

# 需求:安去li视频的视频数据
headers = {
   
    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.72 Safari/537.36'
}

# 原则:线程池处理的是阻塞且耗时的操作

# 对下述url发起请求解析出视频详情页的url和视频的名称
url = "https://www.pearvideo.com/"

page_text = requests.get(url=url, headers=headers).text

tree = etree.HTML(page_text)
# xpath返回的是列表  ['video_1742557']

all_addresses = tree.xpath("//div[@id='vervideoTlist']//a[@class='vervideo-lilink actplay']/@href")
# print(all_addresses)
# ['video_1742557', 'video_1742534', 'video_1742545', 'video_1733739', 'video_1718659']
all_names = tree.xpath('//div[@id="vervideoTlist"]//div[@class="vervideo-name"]/text()')
# print(all_names)

urls = []
for i in range(len(all_addresses)):
    
    video_url = 'https://www.pearvideo.com/' + all_addresses[i]
    mp4_name 
  • 6
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

胜天半月子

打不打商的无所谓,能帮到你就好

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值