我有5,00,000个网址.并希望异步获得每个响应.
import aiohttp
import asyncio
@asyncio.coroutine
def worker(url):
response = yield from aiohttp.request('GET', url, connector=aiohttp.TCPConnector(share_cookies=True, verify_ssl=False))
body = yield from response.read_and_close()
print(url)
def main():
url_list = [] # lacs of urls, extracting from a file
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait([worker(u) for u in url_list]))
main()
Run Code Online (Sandbox Code Playgroud)
我一次想要200个连接(并发200个),而不是因为这个
当我运行这个程序50个网址它工作正常,url_list[:50]
但但如果我通过整个列表,我得到这个错误
aiohttp.errors.ClientOSError: Cannot connect to host www.example.com:443 ssl:True Future/Task exception was never retrieved future: Task()
Run Code Online (Sandbox Code Playgroud)
可能是频率太高,服务器拒绝在限制后做出响应?
为什么这行不通:
try:
async with asyncio.wait_for(aiohttp.get(url), 2) as resp:
print(resp.text())
except asyncio.TimeoutError as e:
pass
Run Code Online (Sandbox Code Playgroud)
给
async with asyncio.wait_for(aiohttp.get(url), 2) as resp:
AttributeError: __aexit__
Run Code Online (Sandbox Code Playgroud)
据我了解,asyncio.wait_for()将传递 , 的未来aiohttp.get(),它有一个__aenter__and__aexit__方法(正如有效的事实所证明的那样async with aiohttp.get())。
我有一个代码,正在使用侦听WebSocket上的消息aiohttp。
看起来像:
async for msg in ws:
await self._ws_msg_handler.handle_message(ws, msg, _services)
Run Code Online (Sandbox Code Playgroud)
(原始代码)ws的实例在哪里aiohttp.web.WebSocketResponse()
在我的测试中,我模拟了WebSocketResponse()它及其__aiter__方法:
def coro_mock(**kwargs):
return asyncio.coroutine(mock.Mock(**kwargs))
@pytest.mark.asyncio
@mock.patch('aiojsonrpc.request_handler.WebSocketMessageHandler')
async def test_rpc_websocket_handler(
MockWebSocketMessageHandler,
rpc_websocket_handler
):
ws_response = 'aiojsonrpc.request_handler.WebSocketResponse'
with mock.patch(ws_response) as MockWebSocketResponse:
MockRequest = mock.MagicMock()
req = MockRequest()
ws_instance = MockWebSocketResponse.return_value
ws_instance.prepare = coro_mock()
ws_instance.__aiter__ = coro_mock(return_value=iter(range(5)))
ws_instance.__anext__ = coro_mock()
handle_msg_result = 'Message processed'
MockWebSocketMessageHandler.handle_message.side_effect = Exception(
handle_msg_result)
msg_handler = MockWebSocketMessageHandler()
with pytest.raises(Exception) as e:
await request_handler.RpcWebsocketHandler(msg_handler)(req)
assert str(e.value) …Run Code Online (Sandbox Code Playgroud) pytest python-3.x python-asyncio aiohttp python-unittest.mock
aiohttpwebsocket支持(即WebSocketResponse)和websockets (均提供异步支持)有什么区别?可以混合吗?
我正在从烧瓶转移到 aiohttp,我需要在不支持异步的 Oracle 数据库中执行一些查询。所以我想知道如何在 aiohttp 中做到这一点?
这个怎么样?
或者还有其他(正确的)方法来做到这一点?
提前致谢!
将异步用于套接字服务器的推荐方法是:
import asyncio
async def handle_client(reader, writer):
request = (await reader.read(100)).decode()
response = "Data received."
writer.write(response.encode())
async def main():
loop.create_task(asyncio.start_server(handle_client, 'localhost', 15555))
loop = asyncio.get_event_loop()
loop.create_task(main())
loop.run_forever()
Run Code Online (Sandbox Code Playgroud)
这可以正常工作,但是现在我需要接收适当的客户端请求,然后使用aiohttp库从第三方的Restful API获取数据。
这需要创建一个会话变量,如下所示:
from aiohttp import ClientSession
session = ClientSession()
Run Code Online (Sandbox Code Playgroud)
但这也应该在协程本身内部,因此我将其放入main中:
async def main():
session = ClientSession()
loop.create_task(asyncio.start_server(handle_client, '', 55555))
Run Code Online (Sandbox Code Playgroud)
现在,我需要将会话变量传递给aiohttp get coroutine来获取其余的API数据:
async with session.get(url, params=params) as r:
try:
return await r.json(content_type='application/json')
except aiohttp.client_exceptions.ClientResponseError:
....
Run Code Online (Sandbox Code Playgroud)
我的问题是,如果它坚持只具有读取器,写入器参数,而全局变量对协程内部必须存在会话却没有帮助,那么如何将会话变量传递给handle_client协程?
我必须发送大量HTTP请求,一旦所有HTTP请求都返回,程序就可以继续.听起来像是一场完美的比赛asyncio.有点天真,我把我的电话包裹requests在一个async函数中,然后把它们给了asyncio.这不起作用.
在线搜索后,我找到了两个解决方案:
asynciorun_in_executor为了更好地理解这一点,我写了一个小基准.服务器端是一个烧瓶程序,在回答请求之前等待0.1秒.
from flask import Flask
import time
app = Flask(__name__)
@app.route('/')
def hello_world():
time.sleep(0.1) // heavy calculations here :)
return 'Hello World!'
if __name__ == '__main__':
app.run()
Run Code Online (Sandbox Code Playgroud)
客户是我的基准
import requests
from time import perf_counter, sleep
# this is the baseline, sequential calls to requests.get
start = perf_counter()
for i in range(10):
r = requests.get("http://127.0.0.1:5000/")
stop = perf_counter()
print(f"synchronous took {stop-start} seconds") # 1.062 secs …Run Code Online (Sandbox Code Playgroud) 如何从 aiohttp.web 处理程序返回 HTML 页面?
有没有类似于json_response() 的东西?
是否可以获取使用 aiohttp 发出的每个请求的响应时间和响应大小?
文档似乎在任何地方都没有这些属性。
谢谢
aiohttp ×10
python ×7
python-3.x ×5
async-await ×1
coroutine ×1
cx-oracle ×1
pytest ×1
websocket ×1