私が作成した単純な Web スクレイパーを最適化しようとしています。メイン ページのテーブルから URL のリストを取得し、それらの「サブ」URL のそれぞれに移動して、それらのページから情報を取得します。を使用して、同期的に正常に書き込むことができましたconcurrent.futures.ThreadPoolExecutor()
。ただし、使用するために最適化しようとしていasyncio
ますhttpx
。これらは、何百もの http 要求を行うのに非常に高速であるように思われるためです。
asyncio
andを使用して次のスクリプトを作成しましhttpx
たが、次のエラーが発生し続けます。
httpcore.RemoteProtocolError: Server disconnected without sending a response.
RuntimeError: The connection pool was closed while 4 HTTP requests/responses were still in-flight.
スクリプトを実行すると、接続が失われ続けるようです。同期バージョンを実行しようとしても、同じエラーが発生しました。リモート サーバーがリクエストをブロックしていると考えていましたが、元のプログラムを実行して、問題なく同じ IP アドレスから各 URL にアクセスできました。
この例外の原因は何ですか?また、どのように修正しますか?
import httpx
import asyncio
async def get_response(client, url):
resp = await client.get(url, headers=random_user_agent()) # Gets a random user agent.
html = resp.text
return html
async def main():
async with httpx.AsyncClient() as client:
tasks = []
# Get list of urls to parse.
urls = get_events('https://main-url-to-parse.com')
# Get the responses for the detail page for each event
for url in urls:
tasks.append(asyncio.ensure_future(get_response(client, url)))
detail_responses = await asyncio.gather(*tasks)
for resp in detail_responses:
event = get_details(resp) # Parse url and get desired info
asyncio.run(main())