Python异步爬虫原理如何理解?一文带你看懂
Admin 2021-08-23 群英技术资讯 841 次浏览
这篇文章主要介绍Python异步爬虫原理的内容,很多朋友Python爬虫比较感兴趣,因此分享Python异步爬虫给大家做个参考,感兴趣的朋友可以参考下,希望大家阅读完这篇文章能有所收获,接下来小编带着大家一起了解看看。
默认情况下,用get请求时,会出现阻塞,需要很多时间来等待,对于有很多请求url时,速度就很慢。因为需要一个url请求的完成,才能让下一个url继续访问。一种很自然的想法就是用异步机制来提高爬虫速度。通过构建线程池或者进程池完成异步爬虫,即使用多线程或者多进程来处理多个请求(在别的进程或者线程阻塞时)。
import time
#串形
def getPage(url):
print("开始爬取网站",url)
time.sleep(2)#阻塞
print("爬取完成!!!",url)
urls = ['url1','url2','url3','url4','url5']
beginTime = time.time()#开始计时
for url in urls:
getPage(url)
endTime= time.time()#结束计时
print("完成时间%d"%(endTime - beginTime))

下面通过模拟爬取网站来完成对多线程,多进程,协程的理解。
import time
#使用线程池对象
from multiprocessing.dummy import Pool
def getPage(url):
print("开始爬取网站",url)
time.sleep(2)#阻塞
print("爬取完成!!!",url)
urls = ['url1','url2','url3','url4','url5']
beginTime = time.time()#开始计时
#准备开启5个线程,并示例化对象
pool = Pool(5)
pool.map(getPage, urls)#urls是可迭代对象,里面每个参数都会给getPage方法处理
endTime= time.time()#结束计时
print("完成时间%d"%(endTime - beginTime))

完成时间只需要2s!!!!!!!!
线程池使用原则:适合处理耗时并且阻塞的操作
单线程+异步协程!!!!!!!!!!强烈推荐,目前流行的方式。
相关概念:

#%%
import time
#使用协程
import asyncio
async def getPage(url): #定义了一个协程对象,python中函数也是对象
print("开始爬取网站",url)
time.sleep(2)#阻塞
print("爬取完成!!!",url)
#async修饰的函数返回的对象
c = getPage(11)
#创建事件对象
loop_event = asyncio.get_event_loop()
#注册并启动looP
loop_event.run_until_complete(c)
#task对象使用,封装协程对象c
'''
loop_event = asyncio.get_event_loop()
task = loop_event.create_task(c)
loop_event.run_until_complete(task)
'''
#Future对象使用,封装协程对象c 用法和task差不多
'''
loop_event = asyncio.get_event_loop()
task = asyncio.ensure_future(c)
loop_event.run_until_complete(task)
'''
#绑定回调使用
async def getPage2(url): #定义了一个协程对象,python中函数也是对象
print("开始爬取网站",url)
time.sleep(2)#阻塞
print("爬取完成!!!",url)
return url
#async修饰的函数返回的对象
c2 = getPage2(2)
def callback_func(task):
print(task.result()) #task.result()返回任务对象中封装的协程对象对应函数的返回值
#绑定回调
loop_event = asyncio.get_event_loop()
task = asyncio.ensure_future(c2)
task.add_done_callback(callback_func) #真正绑定,
loop_event.run_until_complete(task)
输出:

import time
#使用多任务协程
import asyncio
urls = ['url1','url2','url3','url4','url5']
async def getPage(url): #定义了一个协程对象,python中函数也是对象
print("开始爬取网站",url)
#在异步协程中如果出现同步模块相关的代码,那么无法实现异步
#time.sleep(2)#阻塞
await asyncio.sleep(2)#遇到阻塞操作必须手动挂起
print("爬取完成!!!",url)
return url
beginTime = time.time()
#任务列表,有多个任务
tasks = []
for url in urls:
c = getPage(url)
task = asyncio.ensure_future(c)#创建任务对象
tasks.append(task)
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(tasks))#不能直接放task,需要封装进入asyncio,wait()方法中
endTime = time.time()
print("完成时间%d"%(endTime - beginTime))

此时不能用time.sleep(2),用了还是10秒
对于真正爬取过程中,如在getPage()方法中真正爬取数据时,即requests.get(url) ,它是基于同步方式实现。应该使用异步网络请求模块aiohttp
参考下面代码:
async def getPage(url): #定义了一个协程对象,python中函数也是对象
print("开始爬取网站",url)
#在异步协程中如果出现同步模块相关的代码,那么无法实现异步
#requests.get(url)#阻塞
async with aiohttp.ClintSession() as session:
async with await session.get(url) as response: #手动挂起
page_text = await response.text() #.text()返回字符串,read()返回二进制数据,注意不是content
print("爬取完成!!!",url)
return page_text

现在大家对于Python异步爬虫原理应该都有所了解了,上述示例有一定的借鉴价值,有需要的朋友可以参考学习,希望对大家学习Python爬虫有帮助,想要了解更多Python异步爬虫的内容,大家可以继续关注其他文章。
文本转载自脚本之家
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。
猜你喜欢
这篇文章主要为大家介绍了python神经网络使用Keras构建RNN网络训练,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪<BR>
这篇文章主要为大家详细介绍了python双向循环链表实例,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
本篇文章给大家带来了关于Python的相关知识,详细介绍了Python实现提取四种不同文本特征的方法,有字典文本特征提取、英文文本特征提取、中文文本特征提取和TF-IDF文本特征提取,感兴趣的可以了
这篇文章主要介绍了关于Pandas count()与values_count()的用法及区别,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
python 程序双击执行的小技巧?点击目录可跳转,使用 PyInstaller 打包程序,可以使用 pip 进行安装..
成为群英会员,开启智能安全云计算之旅
立即注册Copyright © QY Network Company Ltd. All Rights Reserved. 2003-2020 群英 版权所有
增值电信经营许可证 : B1.B2-20140078 粤ICP备09006778号 域名注册商资质 粤 D3.1-20240008