异步请求的奇怪错误

ksh*_*kvn 4 python-3.x python-asyncio

async def rss_downloader(rss):\n    global counter\n    async with download_limit:\n        headers = {\n            \'User-Agent\': \'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.79 Safari/537.36\'\n        }\n        try:\n            response = await httpx.get(rss, headers=headers, verify=False)\n            if response.status_code == 200:\n                r_text = response.text\n                await downloaded_rss.put({\'url\': rss, \'feed\': r_text})\n            else:\n                counter += 1\n                print(f\'\xe2\x84\x96{counter} - {response.status_code} - {rss}\')\n        except (\n            ConnectTimeout, ConnectionClosed\n        ):\n            not_found_rss.append(rss)\n        except Exception:\n            not_found_rss.append(rss)\n            logging.exception(f\'{rss}\')\n\n\nasync def main():\n    parser_task = asyncio.create_task(parser_queue())\n    tasks = [\n        asyncio.create_task(rss_downloader(item[\'url\'])) for item in db[config[\'mongodb\'][\'channels_collection\']].find({\'url\': {\'$ne\': \'No RSS\'}})\n    ]\n    await asyncio.gather(*tasks, parser_task)\n
Run Code Online (Sandbox Code Playgroud)\n\n

通常,此代码无法加载某些页面,从而导致各种错误。下面是一些错误的示例。\n但是当我尝试一次加载相同的页面时,一切都很好:

\n\n
In [1]: import httpx\n\nIn [2]: r = await httpx.get(\'http://www.spinmob.com/nirvanictrance.xml\')\n\nIn [3]: r\nOut[3]: <Response [200 OK]>\n\nIn [4]:\n
Run Code Online (Sandbox Code Playgroud)\n\n

作为一个信号量,我设置了 20 个工作人员的限制,这并不算多,我尝试的越来越少 - 尽管如此,还是出现了这些错误。\n为什么会发生这种情况,我该怎么办?

\n

Par*_*erD 10

httpx文档涵盖了ReadTimeout您遇到的情况:

默认情况下,HTTPX 会谨慎地在所有地方强制执行超时。默认行为是在网络不活动 5 秒后引发 TimeoutException。读取超时指定等待接收数据块(例如响应正文的块)的最大持续时间。如果 HTTPX 无法在此时间范围内接收数据,ReadTimeout则会引发异常。

首先尝试禁用读取超时持续时间(改编自上面链接中的示例):

timeout = httpx.Timeout(10.0, read_timeout=None)
response = await httpx.get(rss, headers=headers, verify=False, timeout=timeout)
Run Code Online (Sandbox Code Playgroud)

然后尝试不同的超时持续时间,看看什么对于您的用例来说是合理的。


编辑:API 已更新,参数名称已从更改read_timeoutread

timeout = httpx.Timeout(10.0, read=None)
Run Code Online (Sandbox Code Playgroud)

  • 现在的 api 似乎是“timeout = httpx.Timeout(10.0, read=None)”。注意缺少的“_timeout” (5认同)