多线程和多进程:
优点:可以为阻塞操作提供异步执行
缺点:无法无限制的创建线程

进程池和线程池:
好处:可以系统对进程和线程的创建和销毁的频率,从而降低系统的开销
缺点:线程池和进程池是固定的。有上限。

线程池的基本使用
# 导入进程池的pool
from multiprocessing.dummy import Pool
# 实例化线程对象
pool = Pool(4)
#  map func iterator  chunksize
pool.map(get_page,name_list)

 





协程:
单线程+异步协程(推介)
evelent_loop: 事件循环,相当于一个无限循环,可以把一些函数注册到这个循环中

coroutine:协程对象,我们可以把协程对象注册到事件循环中

task:任务,他是对协程对象的进一步封装,包含了任务的每个状态

future;代表将来执行或还没有执行的任务,task和future没有本质区别

async: 定义一个协程
await:永安里挂起阻塞方法的执行

import asyncio
#  提供了async await 两个关键字

async def requests1(url):
    print('正在请求的url',url)

    print('请求成功',url)
# async 修饰的函数,调用之后返回的是一个协程对象
c = requests1('http://www.baidu.com')

print(c)


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

# 将协程对象注册到loop中,然后启动loop  c 是协程对象

loop.run_until_complete(c)





# task 的使用

loop = asyncio.get_event_loop()
task = loop.create_task(c)  # 将协程对象 传入loop ,loop创建一个task对象

print(task) # 打印任务对象,正在执行,协程状态

# 将任务对象注册到loop

loop.run_until_complete(task)
print(task) # 打印任务对象,表示任务已经完成




# future

loop = asyncio.get_event_loop()

# 创建future对象

task = asyncio.ensure_future(c) # 任务对象
print(task)
loop.run_until_complete(task) # 注册

print(task)

 

绑定回调函数
 1 import asyncio
 2 #  提供了async await 两个关键字
 3 
 4 async def requests1(url):
 5     print('正在请求的url',url)
 6 
 7     print('请求成功',url)
 8     return  url
 9 # async 修饰的函数,调用之后返回的是一个协程对象
10 c = requests1('http://www.baidu.com')
11 
12 print(c)
13 
14 
15 
16 # 绑定回调
17 
18 def callback_func(task):
19     print(task.result()) # task.result() 返回任务对象的返回值
20 
21 loop = asyncio.get_event_loop()
22 task = asyncio.ensure_future(c)
23 # 当任务对象执行成功之后,执行回调函数 , 将回调函数绑定到任务对象
24 task.add_done_callback(callback_func) # 默认将任务对象作为参数传递给回调函数
25 loop.run_until_complete(task)

 

 


多任务异步协程实现

import asyncio
import time

async  def request(url):
    print('正在下载:',url)
    time.sleep(3)
    print("下载完成",url)


urls = [
    'https://www.baidu.com',
    'https://www.sougou.com',
    'https://www.xinlang.com',
]
start = time.time()
# 任务列表,需要粗放多个任务对象
tasks = []
for url in urls:
    c = request(url) # 协程对象
    task = asyncio.ensure_future(c) # 任务对象
    tasks.append(task)

loop = asyncio.get_event_loop() # 事件循环
loop.run_until_complete(asyncio.wait(tasks)) # 注册

print(time.time()-start) # 9秒, 没有节省时间

原因出在哪里?
time.sleep(3)
在异步协程中,如果出现同步模块相关的代码,那么就无法实现异步。
解决
asyncio.sleep(3)

当在asyncio中遇到阻塞操作必须进行手动挂起
await



import asyncio
import time

async  def request(url):
    print('正在下载:',url)
    # time.sleep(3)
    await  asyncio.sleep(3)
    print("下载完成",url)


urls = [
    'https://www.baidu.com',
    'https://www.sougou.com',
    'https://www.xinlang.com',
]
start = time.time()
# 任务列表,需要粗放多个任务对象
tasks = []
for url in urls:
    c = request(url) # 协程对象
    task = asyncio.ensure_future(c) # 任务对象
    tasks.append(task)

loop = asyncio.get_event_loop() # 事件循环
loop.run_until_complete(asyncio.wait(tasks)) # 注册

print(time.time()-start) # 3.003420114517212秒,

 

 


aiohttp+多任务异步协程

import asyncio
import aiohttp
import requests
import time


urls = [
    'https://www.baidu.com',
    'https://www.sougou.com',
    'https://www.bilibili.com/',
    'https://www.bilibili.com/',
    'https://www.bilibili.com/',
    'https://www.bilibili.com/',
    'https://www.bilibili.com/',
    'https://www.bilibili.com/',
    'https://www.bilibili.com/',
]

async  def get_page(url):
    print("正在下载", url)
    res = requests.get(url)  # 基于同步代码 , 必须使用基于异步的网络请求模块
    print(res.status_code)


    print("下载外币",url)
start = time.time()

tasks = []

for url in urls:
    c = get_page(url)
    task = asyncio.ensure_future(c)
    tasks.append(task)


loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(tasks))

print(time.time()-start) #2.431379795074463

 





aiohttp:
pip install aiohttp
使用该模块的clientsesession

import asyncio
import aiohttp
import requests
import time


urls = [
    'https://www.baidu.com',
    'https://www.sougou.com',
    'https://www.bilibili.com/',
    'https://www.bilibili.com/',
    'https://www.bilibili.com/',
    'https://www.bilibili.com/',
    'https://www.bilibili.com/',
    'https://www.bilibili.com/',
    'https://www.bilibili.com/',
]

async  def get_page(url):
    print("正在下载", url)
    # res = requests.get(url)  # 基于同步代码 , 必须使用基于异步的网络请求模块
    # print(res.status_code)
    async with  aiohttp.ClientSession() as session:
       async with  await session.get(url) as res :
           #         text() 返回字符串数据
           #         read() 返回二进制数据
           #         json() 返回json对象
           # 注意获取响应数据之前,一定要使用await手动挂起
            page_text = await  res.text(encoding='utf8')

            print(page_text)

    print("下载外币",url)
start = time.time()

tasks = []

for url in urls:
    c = get_page(url)
    task = asyncio.ensure_future(c)
    tasks.append(task)


loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(tasks))

print(time.time()-start) # 1.3533799648284912

#  RuntimeWarning: coroutine 'ClientResponse.text' was never awaited
#   self._context.run(self._callback, *self._args)

# 注意获取响应数据之前,一定要使用await手动挂起

  other

aiohttp
get ,post

ua伪装
get
headers paramas

post
headers data , proxy 代理ip不是字典,而是字符串http://ip:port