我需要从 600 多个页面中获得答案,但大多数答案都带有错误 429。我尝试将那些带有 429 的答案发送回任务,但这也没有多大帮助。
async def fetch(session: aiohttp.ClientSession, url: str, params: dict) -> str:
async with session.get(url, headers=headers, params=params) as response:
global tasks
if response.status == 429:
tasks.append(asyncio.create_task(fetch(session, url, params)))
return
response = await response.text()
return response
async def parse_otodom() -> tuple:
async with aiohttp.ClientSession() as session:
html = await fetch(session, URL.get('otodom'), {})
soup = BeautifulSoup(html, 'lxml')
page_quantity = int(
soup.find('ul', class_='e1h66krm4 css-iiviho').find_all('li', class_='css-1lclt1h')[-1].text)
for page_number in range(1, page_quantity + 1):
tasks.append(asyncio.create_task(fetch(session, URL.get('otodom'), {'page': page_number})))
global tasks
global results_number
for result in await asyncio.gather(*tasks):
if result != None:
results_number+=1
asyncio.run(parse_otodom())
print(results_number)
该代码不返回任何异常。至少告诉我往什么方向思考,可以用什么。谢谢
有必要设置连接器允许建立的最大同时连接数。这是必要的,因为许多 Web 服务器对单个 IP 地址允许的同时连接数有限制。这是这样完成的:
与 aiohttp.ClientSession(connector=aiohttp.TCPConnector(limit=10)) 异步作为会话:
将返回429的协程添加回列表的想法
tasks是正确的,但实现是不正确的。如果您只是使用添加任务tasks.append(asyncio.create_task(fetch(session, url, params))),那么这些新任务将不会被执行,直到新的启动await asyncio.gather(*tasks)。相反,你需要这样做:循环 = asyncio.get_event_loop()
等待循环.create_task(fetch(会话, URL.get('otodom'), params))
然后新创建的任务将被执行。