基于上节给出的代码实例,直接使用代码就可以工作,本节我们注解一下核心代码
# -*- encoding: utf-8 -*-
import asyncio
import aiohttp
async def main():
async with aiohttp.ClientSession() as session:
async with session.get('http://www.baidu.com') as resp:
print(resp.status)
res = await resp.text()
print(res[:100])
if __name__ == '__main__':
# 注意:
# python3.7+ 支持写法
# asyncio.run(main())
# python3.6及以下版本写法
event_loop = asyncio.get_event_loop()
result = event_loop.run_until_complete(asyncio.gather(main()))
event_loop.close()
1.先通过 event_loop = asyncio.get_event_loop() 创建了一个事件循环 2.通过 asyncio.gather 接受多个 future 或 coro 组成的列表 任务 3.通过 event_loop.run_until_complete(task) 我们 就开启 事件循环 直到这个任务执行结束。 4.async with aiohttp.ClientSession() as session: 是创建了一个异步的网络请求的上线文管理具柄 5.async with session.get('http://www.baidu.com') as resp: 异步请求数据 6.res = await resp.text() 异步的接收数据 再解释一下两个关键词 1.async 如果一个函数被这个async 关键词修饰 那这个函数就是一个 future object 2.await 协程对象执行到这个关键词定义之处就会做挂起操作,原理是与yield /yield from 类似的。
使用 aiohttp、requests 作为客户端 模拟多任务请求 做一下两者的性能测试。 我们的请求地址为: url = "http://www.baidu.com" 分别模拟请求: 1.50次调用 2.300次调用
# -*- encoding: utf-8 -*-
# requests 方式
import random
import time
import datetime
import requests
def request_task():
res = requests.get(url="http://www.baidu.com",verify=False)
print(res.status_code)
def request_main():
start = time.time()
for _ in range(300):
request_task()
end = time.time()
print("发送300次,耗时: %s" % (end - start)) # 发送300次,耗时: 7.497658014297485
if __name__ == "__main__":
request_main()
# -*- encoding: utf-8 -*-
# aiohttp 方式
import aiohttp
import time
import asyncio
async def aoi_main():
async with aiohttp.ClientSession() as session:
async with session.get('http://www.baidu.com') as resp:
print(resp.status)
start = time.time()
scrape_index_tasks = [asyncio.ensure_future(aoi_main()) for _ in range(300)]
loop = asyncio.get_event_loop()
tasks = asyncio.gather(*scrape_index_tasks)
loop.run_until_complete(tasks)
end = time.time()
print("发送300次,耗时: %s" % (end - start)) # 发送300次,耗时: 2.5207901000976562
我这边测试的最终数据为:
通过简单的测试我们可以得出一些结论:
背景: 有做过爬虫的同学应该知道,同一个ip大并发量请求同一个域名,还没过多久你的这个ip 就会被查封了,所以我们就需要通过代理服务去做请求。
# -*- encoding: utf-8 -*-
import aiohttp
import time
import asyncio
async def main():
async with aiohttp.ClientSession() as session:
proxy_auth = aiohttp.BasicAuth('user', 'pass')
async with session.get("http://www.hao123.com", proxy="http://www.hao123.com", proxy_auth=proxy_auth) as resp:
print(resp.status)
if __name__ == '__main__':
event_loop = asyncio.get_event_loop()
result = event_loop.run_until_complete(asyncio.gather(main()))
event_loop.close()
# -*- encoding: utf-8 -*-
import aiohttp
import time
import asyncio
async def main():
async with aiohttp.ClientSession() as session:
proxy_auth = aiohttp.BasicAuth('user', 'pass')
async with session.get("http://www.hao123.com", proxy="https://www.hao123.com", proxy_auth=proxy_auth) as resp:
print(resp.status)
if __name__ == '__main__':
event_loop = asyncio.get_event_loop()
result = event_loop.run_until_complete(asyncio.gather(main()))
event_loop.close()
我们请求之后会发现报错: ValueError: Only http proxies are supported
查阅 aiohttp 文档 可知: aiohttp supports plain HTTP proxies and HTTP proxies that can be upgraded to HTTPS via the HTTP CONNECT method. aiohttp does not support proxies that must be connected to via https://. 也就是说: aiohttp 支持纯 HTTP 代理和可以通过 HTTP CONNECT 方法升级到 HTTPS 的 HTTP 代理,不支持必须通过 https:// 连接的代理。
网上找了一大圈也没有找到太好的解决方案,查看了源码 找到一个可以解决这个问题的轮子,我贴出来大家可以参考。
# -*- encoding: utf-8 -*-
import asyncio
import aiohttp
from aiohttp_socks import ProxyConnector
async def fetch(session, url):
async with session.get(url) as response:
return await response.text()
async def main(url):
connector = ProxyConnector.from_url('https://xxx.xxx.com')
async with aiohttp.ClientSession(connector=connector, headers=headers) as session:
html = await fetch(session, url)
# to do list
pass
def execute():
urls = ["http://www.hao123.com","http://www.baidu.com"]
loop = asyncio.get_event_loop()
tasks = [main(url) for url in urls]
loop.run_until_complete(asyncio.wait(tasks))
本文分享自 python编程从入门到实践 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体同步曝光计划 ,欢迎热爱写作的你一起参与!