fly*_*yer 112 python python-requests python-3.4 aiohttp
我想做并行的http请求任务asyncio
,但我发现python-requests
会阻塞事件循环asyncio
.我发现了aiohttp,但它无法使用http代理提供http请求服务.
所以我想知道是否有办法在借助的帮助下进行异步http请求asyncio
.
chr*_*ian 172
要使用asyncio的请求(或任何其他阻塞库),您可以使用BaseEventLoop.run_in_executor在另一个线程中运行一个函数并从中获取以获得结果.例如:
import asyncio
import requests
@asyncio.coroutine
def main():
loop = asyncio.get_event_loop()
future1 = loop.run_in_executor(None, requests.get, 'http://www.google.com')
future2 = loop.run_in_executor(None, requests.get, 'http://www.google.co.uk')
response1 = yield from future1
response2 = yield from future2
print(response1.text)
print(response2.text)
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
Run Code Online (Sandbox Code Playgroud)
这将同时获得两个响应.
使用python 3.5,您可以使用新的await
/ async
语法:
import asyncio
import requests
async def main():
loop = asyncio.get_event_loop()
future1 = loop.run_in_executor(None, requests.get, 'http://www.google.com')
future2 = loop.run_in_executor(None, requests.get, 'http://www.google.co.uk')
response1 = await future1
response2 = await future2
print(response1.text)
print(response2.text)
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
Run Code Online (Sandbox Code Playgroud)
有关更多信息,请参阅PEP0492.
min*_*ter 73
aiohttp已经可以与HTTP代理一起使用:
import asyncio
import aiohttp
@asyncio.coroutine
def do_request():
proxy_url = 'http://localhost:8118' # your proxy address
response = yield from aiohttp.request(
'GET', 'http://google.com',
proxy=proxy_url,
)
return response
loop = asyncio.get_event_loop()
loop.run_until_complete(do_request())
Run Code Online (Sandbox Code Playgroud)
osp*_*der 28
上面的答案仍然使用旧的Python 3.4风格协程.如果你有Python 3.5+,这就是你要写的.
aiohttp
现在支持 http代理
import aiohttp
import asyncio
async def fetch(session, url):
async with session.get(url) as response:
return await response.text()
async def main():
urls = [
'http://python.org',
'https://google.com',
'http://yifei.me'
]
tasks = []
async with aiohttp.ClientSession() as session:
for url in urls:
tasks.append(fetch(session, url))
htmls = await asyncio.gather(*tasks)
for html in htmls:
print(html[:100])
if __name__ == '__main__':
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
Run Code Online (Sandbox Code Playgroud)
考虑到 aiohttp 是功能齐全的 Web 框架,我\xe2\x80\x99d 建议使用更轻量级的东西,例如支持异步请求的 httpx ( https://www.python-httpx.org/ )。它具有与请求几乎相同的 api:
\n>>> async with httpx.AsyncClient() as client:\n... r = await client.get(\'https://www.example.com/\')\n...\n>>> r\n<Response [200 OK]>\n
Run Code Online (Sandbox Code Playgroud)\n
有异步的一个很好的例子/等待循环并且通过Pimin康斯坦丁Kefaloukos的一篇文章中线程 Python和ASYNCIO易于并行的HTTP请求:
为了最小化总完成时间,我们可以增加线程池的大小以匹配我们必须进行的请求的数量.幸运的是,这很容易做到,我们将在下面看到.下面的代码清单是如何使用20个工作线程的线程池生成20个异步HTTP请求的示例:
# Example 3: asynchronous requests with larger thread pool
import asyncio
import concurrent.futures
import requests
async def main():
with concurrent.futures.ThreadPoolExecutor(max_workers=20) as executor:
loop = asyncio.get_event_loop()
futures = [
loop.run_in_executor(
executor,
requests.get,
'http://example.org/'
)
for i in range(20)
]
for response in await asyncio.gather(*futures):
pass
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
73930 次 |
最近记录: |