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. Похибка округлення з плаваючою крапкою може зробити дві однакові ціни схожими на різні. Зберігайте сирий текст поруч із розібраним значенням, щоб виправити помилку парсера пізніше без повторного завантаження кожної сторінки.

Зберігання історії і виявлення змін

Одна ціна - це знімок. Цінність монітора - в історії. Зберігайте один рядок на спостереження: ідентифікатор товару, джерело, мітку часу, розібране значення і сирий текст. Тоді сповіщення - це просте порівняння з попереднім рядком. Сповіщайте лише про значущі зміни, наприклад про падіння більше ніж на заданий відсоток або про те, що товар закінчився, щоб вас не засипало шумом.

Варіанти і комплекти

Сторінка товару часто показує кілька цін: окрему для кожного розміру чи кольору, ціну комплекту, ціну для членів програми або ціну, що з'являється лише після вибору. Вирішіть до початку розробки, що саме монітор має записувати. Поширений підхід - зберігати ідентифікатор варіанта разом із ціною, щоб зміна в одному розмірі не виглядала як зміна всього товару. Будьте обережні з цінами "від" і перекресленими початковими цінами, бо парсер, що бере не те число, створюватиме хибні сповіщення. Зберігайте текст мітки поруч із кожним значенням, щоб перевірити, що було прочитано, коли сповіщення здається хибним.

Планування з повагою до сайту

Перевіряйте кожен товар з інтервалом, що відповідає тому, як часто насправді змінюється його ціна. Товар, що змінюється щодня, не потребує перевірки щогодини. Додавайте джитер до кожного відвідування, обмежуйте кількість запитів на сайт на годину і кешуйте результати на обраний інтервал. Ці звички тримають ваше навантаження низьким, а дані - узгодженими.

Коли сторінка блокує вас

Сторінки цін часто є об'єктом автоматизованого доступу, тож ви можете побачити блокування, обмеження частоти або капчу. Відступайте, коли бачите 429 або 503, і припиняйте відвідувати сайт, який постійно відмовляє. Якщо капча з'являється на сторінці, яку ви маєте право автоматизувати, жива капча в Scarnox - це PopularCaptcha. Посібник по PopularCaptcha для Python показує потік токена. Прочитайте скрапінг без блокувань, перш ніж додавати більше механізмів, бо пауз зазвичай достатньо, щоб вирішити більшість проблем, а не будь-який додатковий інструмент.

Деякі сторінки відображають ціни через JavaScript. Для них дотримуйтеся підходу з скрапінгу сайтів на JavaScript.

Скрапінг відповідально

Що далі

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