Мониторинг цен через парсинг: практическое руководство
Мониторинг цен — это проверка цены товара на наборе сайтов по расписанию и запись результатов, чтобы сравнивать их со временем. Им пользуются ритейлеры, маркетплейсы и аналитики. Парсинг цен также один из самых частых способов, которым скрепер сталкивается с капчей, поэтому архитектуру стоит продумать заранее. В этом руководстве рассказано, что отслеживать, как извлекать числа из страниц, которые никогда не задумывались для парсинга, как хранить изменения и отправлять уведомления, а также как оставаться в рамках правил сайта.
Начните с источника, которым вы можете пользоваться
Прежде чем писать код, проверьте, предлагает ли сайт официальный способ получить данные: фид товаров, API или партнерскую программу. Они надежнее парсинга и снимают большую часть юридических и технических рисков. Парсинг — запасной вариант для общедоступных страниц, где официального пути нет, и условия сайта с robots.txt по-прежнему действуют. Юридический обзор отвечает на общие вопросы.
Архитектура из пяти частей
Надежный монитор состоит из пяти частей. Держите их раздельно, так проще отлаживать:
- Планировщик. Решает, какие страницы товаров посещать и когда. Распределяйте посещения в течение дня, а не проверяйте все в одну и ту же минуту.
- Загрузчик. Скачивает страницу с аккуратной частотой, повторами и кешем.
- Парсер. Извлекает цену, контекст валюты и статус наличия.
- Хранилище. Сохраняет каждое наблюдение с временной меткой, чтобы была история.
- Оповещатель. Сравнивает новое значение с последним и уведомляет, когда оно пересекает заданный вами порог.
Извлечение цен из неаккуратных страниц
Цены встречаются в разных формах: с разделителями тысяч, с десятичной запятой, с подписью перед числом или разбросанные по нескольким элементам. Держите парсер небольшим и тестируйте его на реальных примерах. Вот версия, которая предполагает распространенный формат: запятые для тысяч и точка для десятичных. Другие форматы приводите к нему до вызова функции.
import re
from decimal import Decimal, InvalidOperation
PRICE_PATTERN = re.compile(r"\d{1,3}(?:,\d{3})*(?:\.\d{1,2})?|\d+(?:\.\d{1,2})?")
def parse_price(text: str) -> Decimal | None:
"""Вернуть первое число в тексте как Decimal или None."""
match = PRICE_PATTERN.search(text.replace(" ", " "))
if not match:
return None
try:
return Decimal(match.group(0).replace(",", ""))
except InvalidOperation:
return None
print(parse_price("Now 1,249.50 in stock")) # Decimal('1249.50')
print(parse_price("Sold out")) # None
Используйте Decimal, а не float, для всего, что будете сравнивать или суммировать. Ошибки округления в плавающей точке могут сделать равные цены разными. Храните исходный текст рядом с разобранным значением, чтобы исправить ошибку парсера позже, не перезагружая каждую страницу.
Хранение истории и поиск изменений
Одна цена — это снимок. Ценность монитора в истории. Храните одну строку на каждое наблюдение: ID товара, источник, временную метку, разобранное значение и исходный текст. Тогда оповещение — это простое сравнение с предыдущей строкой. Оповещайте только о значимых изменениях, например о падении больше заданного процента или о том, что товар закончился, чтобы вас не засыпало шумом.
Варианты и наборы
На странице товара часто показано несколько цен: по одной на размер или цвет, цена набора, цена для участников или цена, которая появляется только после выбора. Решите до создания, что должен записывать монитор. Частый подход — хранить идентификатор варианта вместе с ценой, чтобы изменение одного размера не выглядело как изменение всего товара. Будьте осторожны с ценами «от» и зачеркнутыми исходными ценами, потому что парсер, который выберет не то число, даст ложные оповещения. Храните текст метки рядом с каждым значением, чтобы проверить, что было прочитано, когда оповещение выглядит неверным.
Планируйте вежливо
Проверяйте каждый товар с интервалом, который соответствует тому, как часто на самом деле меняется его цена. Товар, цена которого меняется раз в день, не требует проверки каждый час. Добавляйте случайный разброс к каждому посещению, ограничивайте число запросов к сайту в час и кешируйте результаты на выбранный интервал. Эти привычки снижают нагрузку и делают данные согласованными.
Когда страница вас блокирует
Страницы с ценами часто становятся целью автоматического доступа, поэтому вы можете увидеть блокировку, ограничение частоты или капчу. При 429 или 503 отступите и перестаньте посещать сайт, который продолжает вам отказывать. Если капча появилась на странице, автоматизация которой вам разрешена, живой тип капчи в Scarnox — PopularCaptcha. Руководство по PopularCaptcha на Python показывает поток с токеном. Прочитайте парсинг без блокировок, прежде чем добавлять инструменты, потому что соблюдение пауз обычно решает больше проблем, чем любой дополнительный инструмент.
Некоторые страницы отображают цены с помощью JavaScript. Для них следуйте подходу из руководства по парсингу JavaScript-сайтов.
Ответственный парсинг
- Сначала используйте официальные фиды или API и читайте условия каждого сайта, который мониторите.
- Соблюдайте
robots.txt, держите низкую частоту запросов и кешируйте результаты. - Не мониторьте конкурентов так, чтобы ухудшать их сервис.
- Ограничивайте собираемые данные тем, что вам нужно, и не храните персональную информацию, которая встречается на страницах товаров.
Следующие шаги
- Парсинг результатов поиска
- Парсинг без блокировок
- Ротация прокси для парсинга
- Законен ли парсинг сайтов? Общий обзор
Начните с бесплатного пробного баланса, карта не нужна: создайте аккаунт и опробуйте поток PopularCaptcha на странице, автоматизация которой вам разрешена. Актуальные тарифы — на странице цен.