背景¶
早期爬虫用 requests + ThreadPoolExecutor,并发开到 32 时仍受限于 GIL 与 socket 复用。
改写¶
httpx.AsyncClient + asyncio.gather:
async with httpx.AsyncClient(timeout=10) as c:
tasks = [c.get(url) for url in urls]
pages = await asyncio.gather(*tasks)
坑¶
Client不要每次新建,复用同一个以保持 keep-alive;- 单页异常用
return_exceptions=True,避免整批失败; - QPS 太大时记得用
aiometer加并发上限。