异步爬虫之多任务异步协程

一、前提条件
(1)如果想要使用该模式进行异步的数据爬取必须:
将等待即将爬取的页面url单独的抽取存储到一个列表中
(2)通常情况下的玩法:
使用requests将等待爬取的页面的url获取
将url写入列表,使用多任务异步协程爬取列表中的页面数据

#特殊函数内部:不可以出现不支持异步模块,requests不支持异步
#每个阻塞操作前要加await,保证异步执行操作的过程中可以保证阻塞操作执行完毕
async  def get_content(url):
    #使用aiohttp进行网络请求
    async with aiohttp.ClientSession() as session: #实例化一个请求对象叫session,with帮助省略close操作
        #session.get(url,headers,params,proxy)
        #session.post(url,headers,data,proxy)
        #proxy = "http://ip:port
        async with await session.get(url=url,headers=headers) as response: #调用get发送请求,返回一个响应对象
            #text()返回字符串形式的响应数据,返回bytes类型的响应数据
            page_text = await response.text()
            return page_text

#定义一个任务对象的回调函数
#注意:回调函数必须要有一个参数,该参数表示就是该函数的绑定者
#多任务的异步爬虫中数据解析或者持久化存储操作需要写在任务对象的回调函数中
def parse(task):
    #resul():返回的就是特殊函数的返回值
    page_text = task.result()
    # print("i am task callback!特殊函数的返回值为:",page_text)
    tree = etree.HTML(page_text)
    title = tree.xpath('//a[@id="cb_post_title_url"]/span/text()')[0]
    print("标题:",title)
if __name__ == '__main__':
    start = time.time()
    urls = [
        # "https://www.baidu.com/",
        "https://www.cnblogs.com/c-x-a/p/10208179.html",
        "https://www.cnblogs.com/c-x-a/p/10453432.html"
    ]
    #定义一个任务列表
    tasks = []
    for url in urls:
        #创建三个协程对象
        c = get_content(url)
        #创建三个任务对象
        task = asyncio.ensure_future(c)
        task.add_done_callback(parse)#绑定回调
        tasks.append(task)
    # 创建一个事件循环对象
    loop = asyncio.get_event_loop()
    #将任务列表中的多个任务注册到事件循环中
    # loop.run_until_complete(tasks)
    loop.run_until_complete(asyncio.wait(tasks))#wait表示挂起的意思,asynico.wait()将任务列表中每一个任务对象进行挂起
    #挂起:让当前任务对象交出cpu使用权
    print("总耗时:",time.time()-start)

 

posted @ 2021-04-29 11:29  Eliphaz  阅读(138)  评论(0编辑  收藏  举报