多任务异步协程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

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

  1. Python爬虫进阶 | 异步协程

    一.背景 之前爬虫使用的是requests+多线程/多进程,后来随着前几天的深入了解,才发现,对于爬虫来说,真正的瓶颈并不是CPU的处理速度,而是对于网页抓取时候的往返时间,因为如果采用request ...

  2. 小爬爬4.协程基本用法&&多任务异步协程爬虫示例(大数据量)

    1.测试学习 (2)单线程: from time import sleep import time def request(url): print('正在请求:',url) sleep() print ...

  3. python tornado TCPserver异步协程实例

    项目所用知识点 tornado socket tcpserver 协程 异步 tornado tcpserver源码抛析 在tornado的tcpserver文件中,实现了TCPServer这个类,他 ...

  4. Python 简易的异步协程使用方法

    代码 import asyncio async def ex(id, n): print(id+" start") await asyncio.sleep(n/2) print(i ...

  5. python爬虫---单线程+多任务的异步协程,selenium爬虫模块的使用

    python爬虫---单线程+多任务的异步协程,selenium爬虫模块的使用 一丶单线程+多任务的异步协程 特殊函数 # 如果一个函数的定义被async修饰后,则该函数就是一个特殊的函数 async ...

  6. asyncio模块实现单线程-多任务的异步协程

    本篇介绍基于asyncio模块,实现单线程-多任务的异步协程 基本概念 协程函数 协程函数: 定义形式为 async def 的函数; aysnc 在Python3.5+版本新增了aysnc和awai ...

  7. 爬虫必知必会(4)_异步协程-selenium_模拟登陆

    一.单线程+多任务异步协程(推荐) 协程:对象.可以把协程当做是一个特殊的函数.如果一个函数的定义被async关键字所修饰.该特殊的函数被调用后函数内部的程序语句不会被立即执行,而是会返回一个协程对象 ...

  8. Python中异步协程的使用方法介绍

    1. 前言 在执行一些 IO 密集型任务的时候,程序常常会因为等待 IO 而阻塞.比如在网络爬虫中,如果我们使用 requests 库来进行请求的话,如果网站响应速度过慢,程序一直在等待网站响应,最后 ...

  9. 【Python3爬虫】使用异步协程编写爬虫

    一.基本概念 进程:进程是一个具有独立功能的程序关于某个数据集合的一次运行活动.进程是操作系统动态执行的基本单元. 线程:一个进程中包含若干线程,当然至少有一个线程,线程可以利用进程所拥有的资源.线程 ...

随机推荐

  1. 【SpringBoot | Redis】SpringBoot整合Redis

    SpringBoot整合Redis 1. pom.xml中引入Redis相关包 请注意,这里我们排除了lettuce驱动,采用了jedis驱动 <!-- redis的依赖 --> < ...

  2. Kibana创建索引成功,但一直不显示出来(Fielddata is disabled on text fields by default. Set fielddata=true........)

    现象 把EFK整个集群搭建完成后,通过Kibana操作界面创建索引(如图1),我创建了lile-zabbix*的索引,显示是创建成功了,但是只要我在重新刷新一次,已经创建的索引就“消失了”.后通过查看 ...

  3. Spring框架AOP学习总结(下)

    目录 1. AOP 的概述 2. Spring 基于AspectJ 进行 AOP 的开发入门(XML 的方式): 3.Spring 基于AspectJ 进行 AOP 的开发入门(注解的方式): 4.S ...

  4. 常见 MIME 类型列表(转)

    本文转自:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Complete_list_of_MI ...

  5. HTML、CSS基础知识

    前端基础 1. CSS 8 1.1. CSS叫做层叠样式表,用来设置页面中元素的样式.背景颜色.字体颜色.字体大小... 8 1.2. CSS负责结构.表现.行为中的表现 8 1.3. 编写的位置 8 ...

  6. 网站优化之使用Free marker静态化网站文章页

    博客做出来的时候就想要把一些栏目和文章页都静态化处理,当时没啥时间搞,就一直没去弄.但是最近的工作就是做网站,用cms快速搭出了几个网站,cms搭建网站是真的方便啊 如果没有需要二次开发实现的功能,那 ...

  7. SpringCloud Sleuth + Zipkin 实现链路追踪

    一.Sleuth介绍   为什么要使用微服务跟踪? 它解决了什么问题? 1.微服务的现状?   随着业务的发展,单体架构变为微服务架构,并且系统规模也变得越来越大,各微服务间的调用关系也变得越来越复杂 ...

  8. Spring Cloud Alibaba(五)RocketMQ 异步通信实现

    本文探讨如何使用 RocketMQ Binder 完成 Spring Cloud 应用消息的订阅和发布. 介绍 RocketMQ 是一款开源的分布式消息系统,基于高可用分布式集群技术,提供低延时的.高 ...

  9. 02 JavaScript数据类型、类型转换、注释

    JavaScript 数据类型 JavaScript 变量能够保存多种数据类型:数值.字符串值.数组.对象.undefined.null等等 var length = 7; // 数字 var las ...

  10. day20191102笔记

    当日所学默写笔记: 1.select id="唯一,必须写,对应的接口方法名称" resultType="必须写,返回的类型是对应持久化数据层的全限定类名或者是其别名&q ...