код 429 при использовании aiohttp
мне нужно получить ответ с более чем 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)
Исключений код не возвращает. Хотя бы подскажите в каком направлении думать и что можно использовать. Спасибо
Ответы (1 шт):
Нужно было установить максимальное количество одновременных подключений, которых connector разрешит установить. Это нужно, потому что многие веб-серверы имеют ограничения на количество одновременных подключений, которые они разрешают с одного IP-адреса. Это делается так:
async with aiohttp.ClientSession(connector=aiohttp.TCPConnector(limit=10)) as session:
Идея с добавлением корутин, которые возвращали 429, снова в список
tasks
была в правильная, однако реализация была неверной. Если просто добавлять задачи, используяtasks.append(asyncio.create_task(fetch(session, url, params)))
, то эти новые задачи не будут исполняться до нового запускаawait asyncio.gather(*tasks)
. Вместо этого нужно делать так:loop = asyncio.get_event_loop()
await loop.create_task(fetch(session, URL.get('otodom'), params))
Тогда только что созданные задачи будут исполнены.