Разделы · Код и программные интерфейсы
Задача техническая, прошу совета по устройству.
Состояние прогона храню в файле, чтобы продолжать после обрыва. Список адресов читаю из файла и раздаю по кругу.
async with aiohttp.ClientSession() as s:
for i in range(3):
try:
r = await s.get(url, proxy=adres, timeout=30)
break
except Exception:
await asyncio.sleep(2 ** i)
Буду признателен за конкретику.
Подтверждаю, у нас было ровно то же самое.
Разбор ответа держите отдельно от сбора. Тогда смена разметки не требует перегонять данные заново, достаточно перечитать сохранённое.
А что показывают логи в момент падения?
Долго держал старую схему, пока не упёрся.
Адрес выбирайте по кругу с пропуском тех, что в отказе. Случайный выбор даёт перекос, кому-то достанется втрое больше запросов.
Сессия должна создаваться один раз и жить весь прогон. Новая сессия на каждый запрос съедает время на установку соединения и путает настройки.
Проверял два поставщика на одинаковой задаче. Тот, где не режут трафик, дал прогон в полтора раза быстрее. Сейчас работаю через приватные прокси IPv4 и SOCKS5.
Проверьте, что настройка вообще применилась.
Был случай, когда всё сошлось только на третий день разбора.
Сессия должна создаваться один раз и жить весь прогон. Новая сессия на каждый запрос съедает время на установку соединения и путает настройки.
Пришёл к этому не сразу, сначала сделал ошибку.
Повторы делайте с растущей паузой: первая через две секунды, вторая через четыре, третья через восемь. Три попытки достаточно, дальше проблема не в связи.
async with aiohttp.ClientSession() as s:
for i in range(3):
try:
r = await s.get(url, proxy=adres, timeout=30)
break
except Exception:
await asyncio.sleep(2 ** i)
Держите нас в курсе.
Тут есть тонкость, о которой обычно забывают.
Повторы делайте с растущей паузой: первая через две секунды, вторая через четыре, третья через восемь. Три попытки достаточно, дальше проблема не в связи.
Разбор ответа держите отдельно от сбора. Тогда смена разметки не требует перегонять данные заново, достаточно перечитать сохранённое.
async with aiohttp.ClientSession() as s:
for i in range(3):
try:
r = await s.get(url, proxy=adres, timeout=30)
break
except Exception:
await asyncio.sleep(2 ** i)Уменьшите потоки вдвое и замерьте заново.
Считайте по темпу, всё остальное вторично.
Расскажу, чем закончилось у меня.
Логируйте код ответа, время и адрес. Три поля, и почти любой разбор потом занимает минуты.
Состояние прогона храните построчно, а не одним куском в конце. Тогда обрыв на девяностом проценте не стоит вам всего прогона.
async with aiohttp.ClientSession() as s:
for i in range(3):
try:
r = await s.get(url, proxy=adres, timeout=30)
break
except Exception:
await asyncio.sleep(2 ** i)Долго держал старую схему, пока не упёрся.
Число одновременных задач подбирайте замером, а не на глаз. Обычно кривая выходит на полку, и дальше растёт только число отказов.
Всё верно написали выше, добавлю от себя пару деталей.
Логируйте код ответа, время и адрес. Три поля, и почти любой разбор потом занимает минуты.
Адрес выбирайте по кругу с пропуском тех, что в отказе. Случайный выбор даёт перекос, кому-то достанется втрое больше запросов.
Осторожнее с этим выводом, он верен не всегда.
Логируйте код ответа, время и адрес. Три поля, и почти любой разбор потом занимает минуты.
Согласен с предыдущим ответом, но с одной оговоркой.
Логируйте код ответа, время и адрес. Три поля, и почти любой разбор потом занимает минуты.
Разбор ответа держите отдельно от сбора. Тогда смена разметки не требует перегонять данные заново, достаточно перечитать сохранённое.
async with aiohttp.ClientSession() as s:
for i in range(3):
try:
r = await s.get(url, proxy=adres, timeout=30)
break
except Exception:
await asyncio.sleep(2 ** i)
Тема нужная, подписался.