Перейти к содержимому
PD
Парсинг данных

Парсинг сайтов на Python: Playwright, ретраи, дедупликация

Какой стек выбрать под задачу, как писать селекторы, которые переживают правки вёрстки, как устроены ретраи и почему дедупликация нужна с самого начала.

Все статьи гида Парсинг данных · 11

Разница между работающим один раз скриптом и парсером, который работает месяцами, - не в библиотеках. Она в обработке того, что идёт не по плану.

Выбор стека

Порядок проверки, экономящий недели:

1. Есть ли API. Иногда есть недокументированный: посмотрите, какие фоновые запросы делает страница. Часто данные приходят готовой структурой, и разбирать разметку не нужно вовсе. Это лучший из возможных сценариев.

2. Есть ли данные в исходном ответе. Запросите страницу обычным HTTP-запросом и посмотрите, есть ли в ней нужное. Если есть - берите связку HTTP-клиента и разборщика разметки. Быстро, дёшево, легко параллелится.

3. Только если данных нет - управление настоящим браузером. Дороже в десятки раз по ресурсам и времени.

Практика показывает: браузер нужен реже, чем к нему прибегают. Проверка занимает пять минут и часто экономит основную часть работы.

Селекторы, которые переживают правки

Вёрстка меняется, и это главная причина поломок.

Опирайтесь на смысл, а не на положение. Атрибуты с осмысленными именами и текстовые метки живут дольше, чем длинные пути по дереву и автоматически сгенерированные имена классов.

Не привязывайтесь к порядку. Третий блок в списке перестанет быть третьим при первом же изменении.

Ищите от устойчивого якоря. Найдите контейнер карточки товара по осмысленному признаку и дальше ищите внутри него.

Проверяйте, что нашли. Пустой результат должен быть явной ошибкой, а не пустой строкой в выгрузке. Парсер, молча собравший тысячу пустых записей, хуже упавшего: об упавшем вы узнаете сразу.

Полезная привычка: отдельная проверка структуры. Небольшой набор эталонных страниц и проверка, что все обязательные поля находятся. Запускается перед основным сбором и ловит изменение вёрстки до того, как вы соберёте мусор.

Ретраи

Сеть ненадёжна, сайты отвечают ошибками, соединения обрываются. Без ретраев парсер не переживёт и часа.

Что важно:

Различайте типы ошибок. Таймаут и временная ошибка сервера повторяются. Ошибка «страница не найдена» - нет: повтор даст тот же результат.

Нарастающая задержка. Повторять сразу означает добить сайт, который и так отвечает плохо.

Ограничение попыток. Иначе один проблемный адрес заберёт всё время.

Повтор с другого адреса, если работаете через прокси: тот же адрес, скорее всего, снова получит отказ - см. ротацию.

Отдельная обработка блокировки. Если вместо данных пришла проверка, повторять бессмысленно - надо менять условия сбора.

Дедупликация и сохранение прогресса

Две вещи, которые кажутся необязательными и становятся критичными на объёме.

Дедупликация. Одна и та же запись приходит несколько раз: пагинация пересекается, ретраи повторяют страницы, возобновление начинается с середины.

Нужен устойчивый ключ: артикул, идентификатор из адреса страницы, штрихкод. Название и цена ключом быть не могут - они меняются. Проверка на существование по ключу перед записью решает проблему целиком.

Сохранение прогресса. Сбор десяти тысяч страниц однажды прервётся: сеть, ошибка, перезапуск. Без сохранения прогресса вы начинаете заново.

Практически: отмечайте обработанные страницы, чтобы возобновление продолжало с места остановки. Это же даёт возможность запускать сбор порциями вместо одного длинного прогона.

Что ещё стоит сделать сразу

  • Ограничить темп. Пауза между запросами - и вежливость, и способ не попасть под ограничение.
  • Логировать адрес и результат для каждой страницы. Без этого разбор невозможен.
  • Проверять данные на выходе. Цена как строка, отрицательное количество, дата из будущего - признаки того, что разбор сломался.
  • Сохранять сырой ответ при ошибке разбора. Через день вы не воспроизведёте страницу, на которой упало.

Как выгружать результат - в Excel. Готовые инструменты без кода - программы для парсинга. Обзор - гид по парсингу.

Вопросы и ответы

Что использовать для парсинга на Python?

Для страниц, где данные есть в исходном ответе, - обычные HTTP-запросы с разбором разметки: быстро и дёшево. Для страниц, где содержимое дорисовывается скриптами, - управление настоящим браузером. Проверять надо в этом порядке: браузер нужен реже, чем кажется.

Почему парсер работает и собирает пустые данные?

Потому что селектор не нашёл элемент, а код обработал это как отсутствие значения. Парсер должен различать «поля нет на странице» и «поле пустое»: первое - сбой, требующий внимания, второе - валидные данные. Без этого вы получите тысячи пустых строк и узнаете об этом поздно.

Зачем нужна дедупликация при парсинге?

Потому что одна и та же запись приходит несколько раз: пагинация пересекается, ретраи повторяют страницы, запуск возобновляется с середины. Без устойчивого ключа и проверки на существование вы получите дубликаты, которые потом придётся чистить руками.

Ещё по теме

Сделаю под ключ

Соберу парсер под ваш источник

С обходом защиты, прокси и выгрузкой в таблицу, базу или Telegram. Работает по расписанию без вас.

от 300 $ · 3-7 дней

Похожий кейсEtsy Keyword FinderПриложение для аудита ключевых слов Etsy на очереди задач: отправляете ID листинга и до 20 ключей, а фоновые воркеры проходят реальную выдачу шаг за шагом со скриншотами.

«Очень быстрый парсинг, спасибо большое! Даже получилось чуть больше номеров, всем рекомендую! Делал заказ 2 раза, всё устраивает, буду обращаться ещё.»

sotasoftdv · Kwork