python爬虫--多任务异步协程, 快点,在快点......

多任务异步协程asyncio

特殊函数:
    - 就是async关键字修饰的一个函数的定义
    - 特殊之处:
        - 特殊函数被调用后会返回一个协程对象
        - 特殊函数调用后内部的程序语句没有被立即执行

- 协程
    - 对象。协程==特殊的函数。协程表示的就是一组特定的操作。

- 任务对象
    - 高级的协程(对协程的进一步的封装)
        - 任务对象==协程==特殊的函数
            - 任务对象==特殊的函数
    - 绑定回调:
        - task.add_done_callback(task)
            - 参数task:当前回调函数对应的任务对象
            - task.result():返回的就是任务对象对应的特殊函数的返回值

- 事件循环对象
    - 创建事件循环对象
    - 将任务对象注册到该对象中并且开启该对象
    - 作用:loop可以将其内部注册的所有的任务对象进行异步执行

- 挂起:就是交出cpu的使用权。

await:被用做在特殊函数的内部,在被阻塞的时候
wait:给每一个任务赋予一个可被挂起的权限

#【重点】在特殊函数内部的实现中,不可以出现不支持异步的模块(例如time,requests)代码,如果出现了,则会中断整个的异步效果!!!

asyncio的使用

import asyncio
import time
from time import sleep

# 特殊函数
async def get_request(url):
    print('正在下载: ',url)
    sleep(2)
    print('下载完毕: ',url)
    return 'page_text'

# 回调函数,普通函数
def parse(task):
    # 参数表示任务对象
    print('i am callback',task.result())

start = time.time()
# 调用特殊函数
func = get_request('www.xx.com')

# 创建任务对象
task = asyncio.ensure_future(func)

# 给任务对象绑定回调函数
task.add_done_callback(parse)

# 创建一个事件循环对象
loop = asyncio.get_event_loop()

# 让loop执行一个任务
loop.run_until_complete(task)

print("总耗时:",time.time()-start) #总耗时: 2.0017831325531006

多任务协程

import asyncio
import time

# 特殊函数
async def get_request(url):
    print('正在下载',url)
    # time.sleep(2) 不支持异步的模块 会中断整个的异步效果
    await asyncio.sleep(2)
    print('下载完成',url)
    return 'page_text'

def parse(task):
    print(task.result())

start = time.time()
urls = ['www.xxx1.com','www.xxx2.com','www.xxx3.com']

tasks = []  #存放多任务
for url in urls:
    # 调用特殊函数
    func = get_request(url)

    # 创建任务对象
    task = asyncio.ensure_future(func)

    # 给任务对象绑定回调函数
    task.add_done_callback(parse)
    tasks.append(task)

# 创建事件循环对象
loop = asyncio.get_event_loop()

# 执行任务
loop.run_until_complete(asyncio.wait(tasks))
print('总耗时:',time.time()-start) #2.0015313625335693

aiohttp的使用

- requests一定是不支持异步
- aiohttp是一个支持异步的网络请求模块
    - 环境安装
    - 编码流程:
        - 大致的架构:
             with aiohttp.ClientSession() as s:
                #s.get(url,headers,params,proxy="http://ip:port")
                with s.get(url) as response:
                    #response.read()二进制(.content)
                    page_text = response.text()
                    return page_text

    - 补充细节
         - 在每一个with前加上async
         - 需要在每一个阻塞操作前加上await
                async with aiohttp.ClientSession() as s:
                    #s.get(url,headers,params,proxy="http://ip:port")
                    async with await s.get(url) as response:
                        #response.read()二进制(.content)
                        page_text = await response.text()
                        return page_text

异步协程爬虫案例

# 需求用多任务异步协程获取百度,搜狗,京东,淘宝的页面源码数据,并简单解析
import asyncio
import requests
import time
from lxml import etree
urls = ['https://www.baidu.com','http://www.taobao.com/','http://www.jd.com/','https://www.sogou.com/']
headers={
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36'
}
# 特殊函数
async def get_request(url):
    print('正在下载',url)
    page_text = requests.get(url,headers=headers).text
    print(url,'下载完成')
    return page_text

# 回调函数
def parse(task):
    page_text = task.result()
    tree = etree.HTML(page_text)
    div = tree.xpath('//div')
    print(div)

start = time.time()
tasks = []#存放多任务
for url in urls:
    func = get_request(url)
    task = asyncio.ensure_future(func)
    task.add_done_callback(parse)
    tasks.append(task)

# 创建事件要在循环外
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(tasks))

print('总耗时:',time.time()-start)

#根据结果发现执行并不是异步,原因是requests不是异步模块,所以整个程序不会异步执行

基于aiohttp的多任务协程的爬虫

# 需求用多任务异步协程获取百度,搜狗,京东,淘宝的页面源码数据,并简答解析
import asyncio
import requests
import time
import aiohttp
from lxml import etree
urls = ['https://www.baidu.com','http://www.taobao.com/','http://www.jd.com/','https://www.sogou.com/']
headers={
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36'
}
# 特殊函数
async def get_request(url):
    async with aiohttp.ClientSession() as s:
        # s.get(url,headers,params,proxy="http://ip:port")
        async with await s.get(url,headers=headers) as response:
            print('正在下载', url)
            # response.read()二进制(.content)
            page_text = await response.text()
            print(url, '下载完成')
            return page_text

# 回调函数
def parse(task):
    page_text = task.result()
    tree = etree.HTML(page_text)
    div = tree.xpath('//div')
    print(div)

start = time.time()
tasks = []#存放多任务
for url in urls:
    func = get_request(url)
    task = asyncio.ensure_future(func)
    task.add_done_callback(parse)
    tasks.append(task)

# 创建事件要在循环外
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(tasks))

print('总耗时:',time.time()-start) #总耗时: 3.0848371982574463

原文地址:https://www.cnblogs.com/tangjian219/p/12002525.html

时间: 2024-10-09 15:43:23

python爬虫--多任务异步协程, 快点,在快点......的相关文章

爬虫第四章 单线程+多任务异步协程

单线程+多任务异步协程: asyncio 事件循环 loop: 无限循环的对象,事件循环中最终需要将一些特殊的函数注册到该事件循环中 特殊的函数: 被ansyc关键字修饰的函数 协程: 本质上是一个对象,可以把协程对象注册到事件循环中, 任务对象:就是对协程对象进一步的封装. 绑定回调函数(即在执行完特殊函数之后执行这个回调函数):task.add_done_callback(func) - func(task) :task 参数表示的就是绑定的任务对象 - task.result() 返回的就

单线程实现了多任务异步协程

单线程+多任务异步协程: 意义:提升爬取数据的效率,我们也可以使用线程池, 异步爬虫方式: 多线程/多进程(电脑吃不消,没办法无节制开启)不建议 池:池中的线程或进程也是无法任意开启. 单线程+多任务异步协程(推荐)(500个协程,最优) 概念: 协程:本质就是一个对象,协程对象,怎么去获取?可以使用asynic该关键字去修饰一个函数定义,此时的函数就叫它特殊函数,当该特殊函数被调用之后,就可以返回一个协程对象,特殊之处不仅仅是返回一个协程对象,当函数内部实现的语句不会被立即执行(时间循环开启后

单线程多任务异步协程

目录  1. 概念讲解 2. 多任务异步协程理解 3.基于aiohttp模块异步网络请求实现数据爬取及数据解析 一.需要了解的概念 特殊函数:如果async修饰了一个函数的定义,那么该函数就变成了一个特殊函数, 特殊之处:特殊函数被调用后函数内部实现语句不会被立即执行 该函数调用之后会返回一个协程对象 协程对象:特殊函数调用后可以返回一个协程对象 协程 == 特殊函数 任务对象:对协程对象的进一步封装,就是一个高级协程对象 任务对象 == 协程对象 == 特殊的函数 绑定回调:task.add_

多任务异步协程,asyncio及aiohttp

要实现异步协程,需要满足几个条件: 1,创建协程对象,且协程内部操作需要支持异步. 2,创建任务对象,如需为协程执行结果进行进一步处理,则需要为任务对象绑定回调函数. 3,创建事件循环,并将任务启动. 1 import asyncio 2 import requests 3 from lxml import etree 4 import aiohttp 5 import os 6 7 headers = { 8 9 'User-Agent': 'Mozilla/5.0 (Windows NT 1

爬虫 + 数据分析 - 4 异步协程, selenium使用, 自动登录

一.单线程+异步协程 1.基本概念: event_loop:事件循环,相当于一个无限循环,我们可以把一些特殊函数注册(放置)到这个事件循环上, 当满足某些条件的时候,函数就会被循环执行.程序是按照设定的顺序从头执行到尾,运行的次数也是完全按照设定. 当在编写异步程序时,必然其中有部分程序的运行耗时是比较久的,需要先让出当前程序的控制权,让其在背后运行, 让另一部分的程序先运行起来.当背后运行的程序完成后,也需要及时通知主程序已经完成任务可以进行下一步操作, 但这个过程所需的时间是不确定的,需要主

06爬虫-异步协程

1. 前言(目的就是大大提升爬虫效率) 在执行IO密集型任务的时候,代码常常遇到IO操作而等待.例如我们在爬虫的时候,用到requests请求的时候,网页响应慢,一直等待着,那么爬虫的效率会大大的降低. 为了解决这类问题,本文就来探讨一下 Python 中异步协程来加速的方法,此种方法对于 IO 密集型任务非常有效.如将其应用到网络爬虫中,爬取效率甚至可以成百倍地提升. 注:本文协程使用 async/await 来实现,需要 Python 3.5 及以上版本. 2. 基本了解 在了解异步协程之前

单线程+异步协程

event_loop:事件循环,相当于一个无限循环(不清楚循环多少次),我们可以把一些特殊函数注册(放置)到这个事件循环上,当满足某些条件的时候,函数就会被循环执行.程序是按照设定的顺序从头执行到尾,运行的次数也是完全按照设定.当在编写异步程序时,必然其中有部分程序的运行耗时是比较久的,需要先让出当前程序的控制权,让其在背后(挂起)运行,让另一部分的程序先运行起来.当背后运行的程序完成后,也需要及时通知主程序已经完成任务可以进行下一步操作,但这个过程所需的时间是不确定的,需要主程序不断的监听状态

爬虫速度太慢?来试试用异步协程提速吧!

1. 前言 在执行一些 IO 密集型任务的时候,程序常常会因为等待 IO 而阻塞.比如在网络爬虫中,如果我们使用 requests 库来进行请求的话,如果网站响应速度过慢,程序一直在等待网站响应,最后导致其爬取效率是非常非常低的. 为了解决这类问题,本文就来探讨一下 Python 中异步协程来加速的方法,此种方法对于 IO 密集型任务非常有效.如将其应用到网络爬虫中,爬取效率甚至可以成百倍地提升. 注:本文协程使用 async/await 来实现,需要 Python 3.5 及以上版本. 2.

(zt)Lua的多任务机制——协程(coroutine)

原帖:http://blog.csdn.net/soloist/article/details/329381 并发是现实世界的本质特征,而聪明的计算机科学家用来模拟并发的技术手段便是多任务机制.大致上有这么两种多任务技术,一种是抢占式多任务(preemptive multitasking),它让操作系统来决定何时执行哪个任务.另外一种就是协作式多任务(cooperative multitasking),它把决定权交给任务,让它们在自己认为合适的时候自愿放弃执行.这两种多任务方式各有优缺点,前者固