高性能异步爬虫
目的:在爬虫中使用异步实现高性能的数据爬取操作。
异步爬虫的方式:
1.多线程,多进程(不建议):
好处:可以为相关阻塞的操作单独开启线程或者进程,阻塞操作就可以异步执行。
弊端:无法无限制的开启多线程或者多进程。
2.线程池、进程池(适当的使用):
好处:我们可以降低系统对进程或者线程创建和销毁的一个频率,从而很好的降低系统的开销。
弊端:池中线程或进程的数量是有上限。3.单线程+异步协程(推荐):
event_loop:事件循环,相当于一个无限循环,我们可以把一些函数注册到这个事件循环上,
当满足某些条件的时候,函数就会被循环执行。coroutine:协程对象,我们可以将协程对象注册到事件循环中,它会被事件循环调用。 我们可以使用 async 关键字来定义一个方法,这个方法在调用时不会立即被执行,而是返回 一个协程对象。 task:任务,它是对协程对象的进一步封装,包含了任务的各个状态。 future:代表将来执行或还没有执行的任务,实际上和 task 没有本质区别。 async 定义一个协程. await 用来挂起阻塞方法的执行。
爬取百度视频案例
首先进入网址 百度视频,打开开发者工具,可以知道每个视频链接在li标签下
进入视频主页,打开开发者工具可以很容易找到视频对应的url,但是这个网页是动态加载的,用xpath解析就会获得一个空值。
我们可以通过抓包获得视频的url
from multiprocessing.dummy import Pool
import requests
from lxml import etree
import re
headers={
"User-Agent":
"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:89.0) Gecko/20100101 Firefox/89.0"
}
url='https://haokan.baidu.com/tab/recommend'
page_text=requests.get(url=url,headers=headers).text
tree=etree.HTML(page_text)
li_list=tree.xpath('//li[@class="recommend-item float-left"]/a')
url_list=[]
for li in li_list:
detail_url=li.xpath('.//@href')[0]
name=li.xpath('.//div/div/text()')[0]+'.mp4'
detail_text=requests.get(url=detail_url,headers=headers).text
video_url=re.findall('"url":"(.*?)?auth_key',detail_text)[0]
video_url= video_url.replace('\\', '')
dic={
'url':video_url,
'name':name
}
url_list.append(dic)
def get_video_data(dic):
get_video_url=dic['url']
get_video_name=dic['name']
print(get_video_name, " 正在下载")
response=requests.get(url=get_video_url,headers=headers).content
with open(get_video_name,'wb') as fp:
fp.write(response)
print(get_video_name," 下载完成")
pool=Pool(3)
pool.map(get_video_data,url_list)
pool.close()
pool.join()