Автоматизація збору цін у супермаркетах за допомогою Scrapy, Splash та Kaggle

Мене звати Дмитро, я займаюсь збором даних з інтернету та автоматизацією процесів, пов’язаних з цим. Маю досвід у використанні інструментів для моніторингу та аналізу ринкових тенденцій, зокрема — Scrapy, Splash, Kaggle та Python.

Мій проєкт про порівняння цін на продукти в супермаркетах демонструє, як автоматизація допомагає аналізувати дані для кращого розуміння змін на ринку та прийняття обґрунтованих бізнес-рішень. А саме — дає змогу глибше аналізувати цінові тенденції, сезонні коливання та потенційні зовнішні чинники, які впливають на вартість продуктів.

У статті розповім, як я автоматизував збір цін з супермаркетів АТБ та Metro з 31 серпня 2023 року до 30 вересня 2024 року за допомогою Kaggle, Scrapy й Scrapy-Splash.

Процес збору даних

Ось короткий огляд кроків, які я виконав для автоматизації процесу збору даних.

1. Налаштування середовища

  • Kaggle — використав для організації наборів даних та notebook.
  • Scrapy (популярний фреймворк Python) — для веб-скрапінгу.
  • Scrapy-Splash — для обробки динамічного контенту на сайтах. Наприклад, цін, що рендеряться через JavaScript.

2. Scrapy Spider

Написав парсер на Scrapy для Metro. Нижче представлена спрощена версія того, як я структуризував свої Scrapy-павуки.

Встановив scrapy:

!pip install -q scrapy

І приклад коду:

import scrapy
from scrapy.crawler import CrawlerProcess

class MySpider(scrapy.Spider):
    name = "metro"

    def start_requests(self): 
        urls = <тут згенерувати список url-адрес>
        for url in urls:
            yield scrapy.Request(url=url, method="GET", headers=headers, callback=self.parse) 

    def parse(self, response):
        json_data = json.loads(response.text) 
        <тут видобуваються дані>

if __name__ == "__main__":
    process = CrawlerProcess()

    process.crawl(MySpider)
    process.start()

3. Scrapy-Splash Spider

Для скрапінгу АТБ я використовував Scrapy-Splash. Splash дозволяє павуку рендерити JavaScript і працювати з динамічним контентом, що було необхідно для отримання коректних даних з сайту магазину.

Для встановлення і Scrapy, і Scrapy-Splash, я використовував такі команди:

!pip install -q scrapy-splash
!pip install -q scrapy

І приклад коду:

import scrapy
import scrapy_splash
from scrapy.crawler import CrawlerProcess

script = """
function main(splash)
  splash:init_cookies(splash.args.cookies)
  assert(splash:go{
    splash.args.url,
    headers=splash.args.headers,
    http_method=splash.args.http_method,
    body=splash.args.body,
    })
  assert(splash:wait(0.5))

  local entries = splash:history()
  local last_response = entries[#entries].response
  return {
    url = splash:url(),
    headers = last_response.headers,
    http_status = last_response.status,
    cookies = splash:get_cookies(),
    html = splash:html(),
  }
end
"""

headers = {"ключ": "значення"}

class MySpider(scrapy.Spider):
    name = "atb"

    def start_requests(self): 
        urls = <тут згенерувати список url-адрес>
        for url in urls:               
            yield scrapy_splash.SplashRequest(url, self.parse,
                    endpoint='execute',
                    cache_args=['lua_source'],
                    args={'lua_source': script},
                    headers=atb_headers
                )

    def parse(self, response):
        <тут видобуваються дані>

if __name__ == "__main__":
    process = CrawlerProcess()

    process.crawl(MySpider)
    process.start()

4. Scheduling Spiders

На Kaggle є можливість налаштувати автоматичне виконання notebook. Таким чином зручно періодично запускати павуків Scrapy без необхідності ручного втручання. Для налаштування планування виконайте наступні кроки.

У правому меню знайдіть опцію:

Schedule a notebook to run.
Налаштуйте розклад відповідно до потреб (наприклад, щоденно, щотижня, щомісяця). Форма проста у використанні й інтуїтивно зрозуміла. У моєму випадку я налаштував щомісячний запуск скриптів.


5. Завантаження даних на Kaggle

Після збору даних я створив датасет Kaggle для зберігання та поширення інформації. Це забезпечує легкий доступ до інформації для подальшого аналізу та візуалізації.

Усі зібрані дані про ціни на продукти у АТБ та Metro можна знайти в цьому датасеті.

6. Ну і аналіз даних

Після збору даних я створив Kaggle's notebook для аналізу цін з часом. Процес підготовки даних і які дані там є, ви можете знайти тут.

Після виконання попередньої обробки даних я отримав наступні результати:



Середня ціна

Зміни цін з часом у АТБ

  • Мінімальна ціна: 68.58;
  • Максимальна ціна: 77.05;
  • Різниця: 8.47 (зростання на 11%).

Зміни цін з часом у Metro

  • Мінімальна ціна: 161.43;
  • Максимальна ціна: 177.95;
  • Різниця: 16.52 (зростання на 9%).

Порівняння цін за категоріями

Ось порівняння цін тих категорій в АТБ, де відбулися зміни, більші за 15%:

CategoryFirst PriceLast PriceDifference
Juices, Nectars34.8753.980.354075
Chocolate53.3472.070.259952
Coffee, Cocoa139.27178.240.218641
Kitchen Goods83.15105.650.212967
Baked Goods, Pastries33.9042.900.209790
Oils and Vinegar112.63140.980.201108
Hard Cheeses60.9576.150.199594
Sour Cream36.2645.200.197788
Water26.2332.670.196939
Breakfast Cereals33.4541.430.192729
Flour44.3554.150.180979
Baby Dairy Products15.5018.830.176627
Nuts, Dried Fruits50.1660.000.163974
Cream37.1044.330.163158
Yogurts28.9134.510.162276
Pet Food49.0358.380.160262
Fruits, Berries44.5652.930.158070
Batteries61.7373.030.154731
Candies99.38117.360.153158


А ось порівняння змін цін категорій Metro:

CategoryFirst PriceLast Price
Babies162.72159.95
Bakery59.0762.37
Canned Food, Oil, Vinegar129.71145.60
Chemicals167.64179.31
Crisps and Snacks75.1283.27
Dairy and Eggs102.97111.06
Drinks123.01135.72
Eighteen Plus418.15421.95
For Animals220.11236.55
Frozen209.00235.10
Fruits and Vegetables134.88194.08
Hobby and Rest294.90165.82
Home Interior and Textiles227.50189.43
Hot Drinks202.35227.18
Household Goods141.75228.22
Kitchenware288.90329.60
Meat, Fish, Poultry170.23195.46
Packets and Cereals93.96102.67
Personal Hygiene213.18207.52
Sauces and Spices71.0184.39
Snacks and Sweets79.6698.33
Stationery94.6699.20



Висновок

З серпня 2023 до вересня 2024 року дані показують суттєві коливання цін у різних категоріях продуктів в супермаркетах АТБ та Metro. АТБ продемонстрував більш значні зміни. При цьому в окремих категоріях, таких як соки, шоколад та кава, спостерігалося зростання цін понад 20%. Ці збільшення, ймовірно, були спричинені факторами ланцюга постачання та інфляцією.

Metro загалом демонстрував помірніші зміни, проте в категоріях «Фрукти та овочі» спостерігалося значне зростання. «Побутові товари» також зазнали різкого зростання цін, у той час як ціни на товари з категорій «Хобі та відпочинок» й «Інтер'єр дому» несподівано знизилися. Можливо, через розпродажі або зміну пріоритетів споживачів.

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

Такі інсайти можуть допомогти споживачам приймати обґрунтовані рішення щодо покупок, а ритейлерам — ефективно коригувати стратегії ціноутворення.

Підписуйтеся на Telegram-канал «DOU #tech», щоб не пропустити нові технічні статті

👍ПодобаєтьсяСподобалось9
До обраногоВ обраному2
LinkedIn
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

У рітейлу це поставлено на поток. Є цілі агенції які цим займаються. І там не тільки парсинг. Є навіть офлайн моніторинг з людьми які ходять по магазинам і записують ціни. Моніториться все, включаючи ціни у бабок на ринках

ціни бабок на ринку це вже інший рівень

Дмитро, дякую за статтю.
Скажіть, будь ласка, чому ви надали текст програм з пропусками url, та помилками.
Ви це зробили навмисно, чи просто помилились?
Наприклад, в циклах for явна помилка:
замість for url in urls: написано for url in url:
Та і далі оці вставки <тут видобуваються дані> трохи дивують, бо саме тут найдільш цікава частина програми. )))))
Дякую ще раз за статтю.

Помилки не навмисні
Мета статті була в тому щоб показати ідею, а не реалізацію.
І по добуванню даних, то там не має нічого цікавого (звичайний json/html)

Привіт!
А що робите із магазинами, котрі не дуже хочуть, щоб їх парсили?

Привіт!
Тут два варіанти або парсити або не парсити

цікаво. А ще було б цікаво порівнювати ті самі продукти між двох супермаркетів, але це мабуть треба щоб на сайтах були їх штрихкоди

Доброго дня, Дмитро! підкажіть будь ласка, лінку яку ви зашили в «в цьому датасеті» це лінка на щось, що змінюється у відповідності до теперішнього часу? Аналіз доволі цікавий, просто я поки не зареєстрований в Kaggli. Не зовсім розумію як він працює і чи зможу я, зареєструвавшись там, користуватись вашим датасетом.
Дякую

Доброго дня!
На Kaggle знаходяться csv файли, кожного місяця додаються нові.

Підписатись на коментарі