Python异步爬虫实现原理与知识总结

 更新时间:2021年05月13日 08:31:14   作者:amcomputer  
之前有很多小伙伴想看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函数缺省值与引用学习笔记分享

    python函数缺省值与引用学习笔记分享

    有关一个在函数参数设置缺省值与引用的问题,这个问题是大多数Pythoner可能会忽视的问题,作个笔记,以备后阅,同时供需要的朋友参考
    2013-02-02
  • python重要函数eval多种用法解析

    python重要函数eval多种用法解析

    这篇文章主要介绍了python重要函数eval多种用法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-01-01
  • python os.path模块使用方法介绍

    python os.path模块使用方法介绍

    os.path 模块是系统路径操作模块,但实际的原理可以把它认为是处理包含斜杠("/")和反斜杠("\")字符串的模块,其中,斜杠("/")是 linux 系统下的路径分隔符,和反斜杠("\")是 windows 系统下的路径分隔符
    2022-08-08
  • 关于Python函数对象的名称空间和作用域

    关于Python函数对象的名称空间和作用域

    这篇文章主要介绍了关于Python函数对象的名称空间和作用域,数据的名称是储存到栈区,而数据的内容是储存到堆区,当我们要去使用数据的内容时,我们可以通过数据的名称来直接去表示数据的内容,需要的朋友可以参考下
    2023-04-04
  • python 实现return返回多个值

    python 实现return返回多个值

    今天小编就为大家分享一篇python 实现return返回多个值,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-11-11
  • python实现web邮箱扫描的示例(附源码)

    python实现web邮箱扫描的示例(附源码)

    这篇文章主要介绍了python实现web邮箱扫描的示例(附源码),帮助大家更好的理解和学习使用python,感兴趣的朋友可以了解下
    2021-03-03
  • python 实现Requests发送带cookies的请求

    python 实现Requests发送带cookies的请求

    这篇文章主要介绍了python 实现Requests发送带cookies请求的方法,帮助大家更好的理解和使用python,感兴趣的朋友可以了解下
    2021-02-02
  • python3环境搭建过程(利用Anaconda+pycharm)完整版

    python3环境搭建过程(利用Anaconda+pycharm)完整版

    这篇文章主要介绍了python3环境搭建过程(利用Anaconda+pycharm)完整版,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-08-08
  • python k-近邻算法实例分享

    python k-近邻算法实例分享

    这个算法主要工作是测量不同特征值之间的距离,有个这个距离,就可以进行分类了。简称kNN。
    2014-06-06
  • python模块之StringIO使用示例

    python模块之StringIO使用示例

    这篇文章主要介绍了python模块之StringIO使用示例,本文直接给出示例代码,需要的朋友可以参考下
    2015-04-04

最新评论