Scarnox · Blog

Мониторинг цен через парсинг: практическое руководство

Мониторинг цен — это проверка цены товара на наборе сайтов по расписанию и запись результатов, чтобы сравнивать их со временем. Им пользуются ритейлеры, маркетплейсы и аналитики. Парсинг цен также один из самых частых способов, которым скрепер сталкивается с капчей, поэтому архитектуру стоит продумать заранее. В этом руководстве рассказано, что отслеживать, как извлекать числа из страниц, которые никогда не задумывались для парсинга, как хранить изменения и отправлять уведомления, а также как оставаться в рамках правил сайта.

Начните с источника, которым вы можете пользоваться

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

Архитектура из пяти частей

Надежный монитор состоит из пяти частей. Держите их раздельно, так проще отлаживать:

  1. Планировщик. Решает, какие страницы товаров посещать и когда. Распределяйте посещения в течение дня, а не проверяйте все в одну и ту же минуту.
  2. Загрузчик. Скачивает страницу с аккуратной частотой, повторами и кешем.
  3. Парсер. Извлекает цену, контекст валюты и статус наличия.
  4. Хранилище. Сохраняет каждое наблюдение с временной меткой, чтобы была история.
  5. Оповещатель. Сравнивает новое значение с последним и уведомляет, когда оно пересекает заданный вами порог.

Извлечение цен из неаккуратных страниц

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

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-сайтов.

Ответственный парсинг

Следующие шаги

Начните с бесплатного пробного баланса, карта не нужна: создайте аккаунт и опробуйте поток PopularCaptcha на странице, автоматизация которой вам разрешена. Актуальные тарифы — на странице цен.