Автоматизируйте маркетинговое исследование: как парсить Shopify с помощью Python

Последнее обновление: April 16, 2026

Эндпоинт Shopify /products.json — один из самых недооценённых секретов в e-commerce данных. Просто добавьте его к URL любого магазина на Shopify, и вы получите структурированный JSON без API-ключей, без авторизации и без разбора сложного вложенного HTML.

Я работаю в команде , поэтому много думаю о том, как люди собирают данные из веба. И тема парсинга Shopify всплывает постоянно — команды продаж отслеживают цены конкурентов, операционные специалисты в e-commerce сравнивают каталоги товаров, закупщики ищут новых поставщиков. С на Shopify и долей платформы около , объём доступных для сбора товарных данных огромен.

В этом руководстве я разберу весь процесс: что возвращает этот эндпоинт, как проходить по тысячам товаров с пагинацией, как не упереться в лимиты запросов и не получить блокировку, а также как превратить вложенный JSON Shopify в аккуратный CSV или Excel-файл с помощью pandas. Я также покажу другие эндпоинты, о которых почти никто не говорит (/collections.json, /meta.json), и предложу no-code альтернативу для тех, кто не хочет использовать Python.

Что такое эндпоинт Shopify /products.json и почему он так упрощает парсинг

У каждого магазина на Shopify есть публичный эндпоинт {store-url}/products.json, который возвращает структурированные данные о товарах. Никаких API-ключей. Никакого OAuth. Вообще никакой авторизации. Достаточно добавить /products.json к адресу магазина — и вы получите JSON-массив со всеми товарами каталога.

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

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

Подход через HTML (больно):

1<div class="product-card__info">
2  <h3 class="product-card__title">
3    <a href="/products/classic-blue-jeans">Classic Blue Jeans</a>
4  </h3>
5  <span class="price price--on-sale" data-product-price>$149.00</span>
6</div>

Подход через JSON (аккуратно):

1{
2  "title": "Classic Blue Jeans",
3  "handle": "classic-blue-jeans",
4  "vendor": "Hiut Denim",
5  "variants": [{"price": "149.00", "sku": "HD-BLU-32", "available": true}]
6}

JSON выигрывает по стабильности, надёжности и простоте обработки. Эндпоинт также поддерживает два ключевых параметра запроса — ?limit= (до 250 товаров на страницу, по умолчанию 30) и ?page= для пагинации — и мы активно будем использовать их в коде ниже.

Важное различие: это публичный storefront-эндпоинт, а не . Admin API требует токены доступа владельца магазина и даёт данные о заказах, остатках и клиентах. Публичный /products.json — это только данные о товарах в режиме чтения, доступные любому. Ниже я подробно объясню разницу, потому что на форумах вокруг этого постоянно возникает путаница.

Оговорка: не у каждого магазина на Shopify открыт этот эндпоинт. По моим тестам, примерно 71% магазинов возвращают валидный JSON (allbirds.com, gymshark.com, colourpop.com, kyliecosmetics.com — всё работает), а у некоторых кастомных конфигураций приходит 404 (hiutdenim.co.uk, bombas.com). Быстрая проверка простая: откройте {store-url}/products.json в браузере и посмотрите результат.

Зачем парсить Shopify на Python? Основные бизнес-сценарии

Зачем вообще этим заниматься? Из-за ROI. Сейчас используют автоматический сбор цен для конкурентной аналитики, тогда как в 2020 году таких было всего 34%. Исследования также показывают, что . Эти данные действительно стоят денег.

Вот самые частые сценарии, с которыми я сталкиваюсь:

This paragraph contains content that cannot be parsed and has been skipped.

Python здесь подходит идеально. , используют Python как основной язык, а экосистема — requests для HTTP, pandas для обработки данных, httpx для асинхронных запросов — позволяет довольно быстро пройти путь от «у меня есть URL» до «у меня есть таблица» менее чем за 80 строк кода.

Полный справочник по полям products.json: что означает каждое поле

В большинстве статей показывают только title, id и handle, а потом сразу переходят к коду. Но JSON-ответ Shopify содержит более 40 полей на уровне товаров, вариантов, изображений и опций. Если заранее знать, что доступно, вы сэкономите себе повторный сбор данных позже.

Я собрал этот справочник на основе живых ответов /products.json, полученных 16 апреля 2026 года. Структура одинакова для всех магазинов, у которых этот эндпоинт открыт.

Поля на уровне товара

ПолеТип данныхПримерБизнес-применение
idЦелое число123456789Уникальный идентификатор товара для дедупликации
titleСтрока"Classic Blue Jeans"Название товара для каталогов и сравнений
handleСтрока"classic-blue-jeans"URL-слуг — ссылку на страницу товара можно собрать как {store}/products/{handle}
body_htmlСтрока (HTML) или null

Our best-selling...

Описание товара для контент-анализа и SEO-исследований
vendorСтрока"Hiut Denim"Название бренда/поставщика для генерации лидов или поиска поставщиков
product_typeСтрока"Jeans"Категоризация товара для анализа рынка
created_atISO DateTime"2024-01-15T10:30:00-05:00"Отслеживание даты добавления товара (для выявления новых запусков)
updated_atISO DateTime"2025-03-01T08:00:00-05:00"Выявление недавних изменений в каталоге
published_atISO DateTime"2024-01-16T00:00:00-05:00"Понимание, когда товар стал доступен на витрине
tagsМассив строк["organic", "women", "straight-leg"]Анализ тегов и ключевых слов для SEO, категоризации и поиска трендов
variantsМассив объектов(см. поля вариантов ниже)Цена, SKU и доступность по каждому варианту
imagesМассив объектов(см. поля изображений ниже)URL изображений товаров для каталогов и визуального анализа
optionsМассив объектов[{"name": "Size", "values": ["S","M","L"]}]Понимание конфигурации товара (размер, цвет, материал)

Поля на уровне варианта (вложены в каждый товар)

ПолеТип данныхПримерСценарий использования
idЦелое число987654321Уникальный идентификатор варианта
titleСтрока"32 / Blue"Отображаемое название варианта
skuСтрока"HD-BLU-32"Сопоставление SKU для складских систем
priceСтрока"185.00"Мониторинг цен (обратите внимание: это строка, для расчётов нужно преобразовать в float)
compare_at_priceСтрока или null"200.00"Исходная цена — критично для отслеживания скидок
availableЛогический типtrueНаличие на складе (единственный публичный индикатор запасов)
weightЧисло с плавающей точкой1.2Анализ доставки и логистики
option1, option2, option3Строка"32", "Blue", nullЗначения отдельных опций
created_at, updated_atISO DateTimeОтслеживание изменений на уровне варианта

Поля на уровне изображения

ПолеТип данныхПримерСценарий использования
idЦелое число111222333Уникальный идентификатор изображения
srcСтрока (URL)"https://cdn.shopify.com/..."Прямая ссылка для скачивания изображения
altСтрока или null"Front view of jeans"Alt-текст изображения для анализа доступности
positionЦелое число1Порядок изображения
width, heightЦелое число2048, 2048Размеры изображения

Чего нет в публичном эндпоинте

Важный нюанс: inventory_quantity отсутствует в публичных ответах /products.json. Это поле было убрано из публичных JSON-эндпоинтов в декабре 2017 года по соображениям безопасности. Единственный индикатор запасов, который вы получаете, — это булево поле available у каждого варианта (true или false). Чтобы получить реальные остатки, нужен авторизованный Admin API с доступом владельца магазина.

Перед тем как писать код парсинга, посмотрите на эту таблицу и решите, какие поля важны именно для вашей задачи. Если вы отслеживаете цены, вам нужны variants[].price, variants[].compare_at_price и variants[].available. Если вы ищете лиды, делайте упор на vendor, product_type и tags. Фильтруйте данные сразу — CSV получится намного чище.

Помимо products.json: коллекции, meta и другие эндпоинты Shopify

Ни одна похожая статья не упоминает эти эндпоинты. А для серьёзной конкурентной аналитики они очень полезны.

/collections.json — все категории магазина

Возвращает все коллекции (категории) магазина с названиями, handle, описаниями и количеством товаров. Я проверил это на zoologistperfumes.com, allbirds.com и gymshark.com — везде вернулся валидный JSON.

1{
2  "collections": [
3    {
4      "id": 308387348539,
5      "title": "Attars",
6      "handle": "attars",
7      "published_at": "2026-03-29T12:20:32-04:00",
8      "products_count": 1,
9      "image": { "src": "https://cdn.shopify.com/..." }
10    }
11  ]
12}

Хотите понять, как конкурент структурирует свой каталог? Вот нужный эндпоинт.

/collections/{handle}/products.json — товары по категории

Возвращает товары, отфильтрованные по конкретной коллекции. Структура JSON такая же, как у /products.json, но только для одной категории. Это особенно важно для парсинга на уровне категорий — например, если вам нужно отслеживать только коллекции конкурента «Sale» или «New Arrivals».

/meta.json — метаданные магазина

Возвращает название магазина, описание, валюту, страну и — что особенно полезно — published_products_count. Это число позволяет заранее точно посчитать, сколько страниц пагинации потребуется: ceil(published_products_count / 250). Больше не нужно вслепую увеличивать номер страницы, пока не получите пустой ответ.

Какой эндпоинт использовать?

| Что вам нужно | Эндпоинт | Нужна авторизация? | |---|---|---|---| | Все товары (публично) | /products.json | Нет | | Товары конкретной категории | /collections/{handle}/products.json | Нет | | Метаданные магазина + количество товаров | /meta.json | Нет | | Все коллекции (категории) | /collections.json | Нет | | Данные о заказах/продажах (только свой магазин) | Admin API /orders.json | Да (API key) | | Количество остатков (только свой магазин) | Admin API /inventory_levels.json | Да |

Частый вопрос на форумах — «Можно ли узнать, сколько единиц продал конкурент?» — имеет короткий ответ: нет. Не через публичные эндпоинты. Данные о продажах и количестве запасов доступны только через авторизованный Admin API, а значит, нужен доступ владельца магазина. Публичные эндпоинты дают только данные каталога товаров.

shopify-data-access-methods.webp

Как парсить Shopify на Python: пошаговая настройка

  • Уровень сложности: Начальный
  • Время: ~15 минут (настройка + первый запуск)
  • Что понадобится: Python 3.11+, pip, терминал и URL магазина Shopify для парсинга

Шаг 1: Установите Python и необходимые библиотеки

Убедитесь, что у вас установлен Python 3.11 или новее (для pandas 3.0.x это обязательно). Затем установите две библиотеки, которые нам понадобятся:

1pip install requests pandas

Для экспорта в Excel дополнительно понадобится:

1pip install openpyxl

В начале скрипта добавьте такие импорты:

1import requests
2import pandas as pd
3import time
4import random
5import json

При запуске скрипта не должно быть ошибок импорта. Если pandas ругается на версию, обновите Python до 3.12.

Шаг 2: Получите данные о товарах из /products.json

Вот базовая функция, которая принимает URL магазина, обращается к эндпоинту и возвращает распарсенный JSON:

1def fetch_products_page(store_url, page=1, limit=250):
2    """Fetch a single page of products from a Shopify store."""
3    url = f"{store_url.rstrip('/')}/products.json"
4    params = {"limit": limit, "page": page}
5    headers = {
6        "User-Agent": "Mozilla/5.0 (compatible; ProductResearch/1.0)"
7    }
8    response = requests.get(url, params=params, headers=headers, timeout=30)
9    response.raise_for_status()
10    return response.json().get("products", [])

Ключевые детали:

  • limit=250 — максимальное значение, которое допускает Shopify на одной странице. По умолчанию 30, так что явная установка этого параметра сокращает число запросов до 8 раз.
  • Заголовок User-Agent: всегда задавайте реалистичный. Запросы без User-Agent чаще срабатывают на антибот-защиту Shopify.
  • timeout=30: один зависший запрос не должен блокировать весь скрипт.

Проверьте на известном магазине:

1products = fetch_products_page("https://allbirds.com")
2print(f"Fetched {len(products)} products")
3print(f"First product: {products[0]['title']}")

Должно получиться что-то вроде: Fetched 250 products и название первого товара.

Шаг 3: Настройте пагинацию, чтобы собрать все товары

Один запрос возвращает максимум 250 товаров. У большинства магазинов товаров больше (у Allbirds — более 1,420). Нужно проходить по страницам, пока не вернётся пустой ответ.

1def scrape_all_products(store_url, delay=1.0):
2    """Scrape all products from a Shopify store, handling pagination."""
3    all_products = []
4    page = 1
5    while True:
6        print(f"Fetching page {page}...")
7        products = fetch_products_page(store_url, page=page, limit=250)
8        if not products:
9            print(f"No more products. Total: {len(all_products)}")
10            break
11        all_products.extend(products)
12        print(f"  Got {len(products)} products (total so far: {len(all_products)})")
13        page += 1
14        # Будьте вежливы: делайте паузу между запросами
15        time.sleep(delay + random.uniform(0, 0.5))
16    return all_products

Когда products возвращается пустым, вы дошли до конца.

time.sleep() с небольшим случайным разбросом помогает не превышать неофициальный лимит Shopify примерно в ~2 запроса в секунду.

Совет: если вы сначала запросите /meta.json, то уже будете знать общее количество товаров и сможете точно рассчитать число страниц: pages = ceil(product_count / 250). Это избавляет от лишнего пустого запроса в конце.

Шаг 4: Разберите данные и оставьте нужные поля

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

1def extract_product_data(products):
2    """Extract key fields from products, flattening variants."""
3    rows = []
4    for product in products:
5        for variant in product.get("variants", []):
6            rows.append({
7                "product_id": product["id"],
8                "title": product["title"],
9                "handle": product["handle"],
10                "vendor": product.get("vendor", ""),
11                "product_type": product.get("product_type", ""),
12                "tags": ", ".join(product.get("tags", [])),
13                "created_at": product.get("created_at", ""),
14                "variant_id": variant["id"],
15                "variant_title": variant.get("title", ""),
16                "sku": variant.get("sku", ""),
17                "price": variant.get("price", ""),
18                "compare_at_price": variant.get("compare_at_price", ""),
19                "available": variant.get("available", ""),
20                "image_url": product["images"][0]["src"] if product.get("images") else ""
21            })
22    return rows

Так вы получите по одной строке на каждый вариант — это самый удобный формат для сравнения цен, потому что один товар вроде «Classic Blue Jeans» может иметь 12 вариантов (6 размеров × 2 цвета), и у каждого будет своя цена и статус наличия.

Экспорт Shopify-данных в CSV и Excel с помощью pandas

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

Проблема в том, что JSON Shopify вложенный. Один товар может содержать десяток вариантов, у каждого — своя цена, SKU и наличие. Превратить это в таблицу требует немного работы с pandas.

Преобразуем вложенный JSON в чистую таблицу

Есть два подхода — в зависимости от задачи:

Вариант A: одна строка = один вариант (лучше всего для мониторинга цен и запасов)

1# Используем функцию extract_product_data из шага 4
2products = scrape_all_products("https://allbirds.com")
3rows = extract_product_data(products)
4df = pd.DataFrame(rows)
5print(f"DataFrame shape: {df.shape}")
6print(df.head())

Так вы получите плоскую таблицу, где каждая строка — уникальная комбинация товара и варианта. У магазина с 500 товарами и в среднем 4 вариантами на товар получится DataFrame примерно на 2,000 строк.

Вариант B: одна строка = один товар (лучше для общего обзора каталога)

1def summarize_products(products):
2    """One row per product with min/max price across variants."""
3    rows = []
4    for product in products:
5        prices = [float(v["price"]) for v in product.get("variants", []) if v.get("price")]
6        rows.append({
7            "product_id": product["id"],
8            "title": product["title"],
9            "vendor": product.get("vendor", ""),
10            "product_type": product.get("product_type", ""),
11            "variant_count": len(product.get("variants", [])),
12            "min_price": min(prices) if prices else None,
13            "max_price": max(prices) if prices else None,
14            "any_available": any(v.get("available", False) for v in product.get("variants", [])),
15            "tags": ", ".join(product.get("tags", []))
16        })
17    return rows

Экспорт в CSV, Excel и Google Sheets

1# Экспорт в CSV (используйте utf-8-sig, чтобы Excel корректно обрабатывал спецсимволы)
2df.to_csv("shopify_products.csv", index=False, encoding="utf-8-sig")
3# Экспорт в Excel (требует openpyxl)
4df.to_excel("shopify_products.xlsx", index=False, engine="openpyxl")
5print("Exported to shopify_products.csv and shopify_products.xlsx")

Для Google Sheets можно использовать библиотеку gspread и service account, но, честно говоря, для большинства задач проще и быстрее экспортировать в CSV, а затем загрузить файл в Google Drive.

Парсинг Shopify в продакшене: лимиты, ретраи и защита от блокировок

Базовый скрипт нормально работает на небольших магазинах. Но если вы парсите магазин с 5,000+ товарами или несколько магазинов подряд, начинаются проблемы.

Как Shopify ограничивает запросы и блокирует трафик

У публичных JSON-эндпоинтов Shopify нет официально опубликованных лимитов (в отличие от модели leaky bucket в Admin API), но на практике видно следующее:

  • Безопасная скорость: около 2 запросов в секунду на один магазин
  • Мягкий предел: примерно 40 запросов в минуту, после чего начинается throttling
  • HTTP 429: «Too Many Requests» — стандартный ответ на превышение лимита
  • HTTP 430: специфичный для Shopify код, означающий блокировку на уровне безопасности, а не просто rate limiting
  • HTTP 403 или редирект на CAPTCHA: у некоторых магазинов включена дополнительная защита Cloudflare

Запросы из облачных инфраструктур общего пользования (AWS Lambda, Google Cloud Run) особенно часто приводят к блокировкам, потому что с этих IP-диапазонов идёт высокий уровень злоупотреблений.

Как надёжно парсить Shopify

Вот путь от «работает на моём ноутбуке» до «готово для продакшена»:

УровеньТехникаНадёжность
Базовыйrequests.get() + ?page=Ломается на больших каталогах, может получить блокировку
Среднийrequests.Session() + ?limit=250 + time.sleep(1) + retry на 429Работает на большинстве магазинов
ПродвинутыйAsync httpx + ротация User-Agent + экспоненциальный backoffПодходит для продакшена, масштабируется до 10K+ товаров

Средний уровень (рекомендуется большинству пользователей):

1import requests
2from requests.adapters import HTTPAdapter
3from urllib3.util.retry import Retry
4> This paragraph contains content that cannot be parsed and has been skipped.
5Конфигурация `Retry` автоматически обрабатывает ответы 429 с экспоненциальной задержкой. Параметр `backoff_factor=1` означает последовательность пауз 0.5 с → 1 с → 2 с → 4 с → 8 с между повторными попытками. Повторное использование `requests.Session()` даёт ещё и pooling соединений, что снижает накладные расходы при серии запросов к одному домену.
6**Ротация User-Agent**: если вы парсите несколько магазинов, чередуйте 35 реалистичных браузерных User-Agent. Это не про обман, а про то, чтобы не выглядеть как бот с одинаковыми заголовками в каждом запросе.
7<iframe width="560" height="315" src="https://www.youtube.com/embed/p3Z-qtUp4p8" title="Web Scraping Project: Save Shopify Products to Database" frameBorder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowFullScreen></iframe>
8## Полный рабочий Python-скрипт для парсинга Shopify с экспортом в CSV
9Ниже — полный скрипт, который можно просто скопировать и запустить. В нём примерно 75 строк реального кода (плюс комментарии), и я тестировал его на Allbirds (1,420 товаров), ColourPop (2,000+ товаров) и Zoologist Perfumes (небольшой каталог).
10```python
11import requests
12import pandas as pd
13import time
14import random
15from requests.adapters import HTTPAdapter
16from urllib3.util.retry import Retry
17> This paragraph contains content that cannot be parsed and has been skipped.
18def scrape_shopify(store_url, delay=1.0):
19    """Scrape all products from a Shopify store via /products.json."""
20    session = create_session()
21    all_products = []
22    page = 1
23    base_url = f"{store_url.rstrip('/')}/products.json"
24> This paragraph contains content that cannot be parsed and has been skipped.
25        if not products:
26            break
27        all_products.extend(products)
28        print(f"{len(products)} products (total: {len(all_products)})")
29        page += 1
30        time.sleep(delay + random.uniform(0, 0.5))
31    return all_products
32> This paragraph contains content that cannot be parsed and has been skipped.
33if __name__ == "__main__":
34    STORE_URL = "https://allbirds.com"  # Change this to your target store
35    OUTPUT_CSV = "shopify_products.csv"
36    OUTPUT_EXCEL = "shopify_products.xlsx"
37    print(f"Scraping {STORE_URL}...")
38    products = scrape_shopify(STORE_URL)
39    print(f"\nTotal products scraped: {len(products)}")
40    print("Flattening to variant-level rows...")
41    rows = flatten_to_variants(products)
42    df = pd.DataFrame(rows)
43    print(f"DataFrame: {df.shape[0]} rows x {df.shape[1]} columns")
44    df.to_csv(OUTPUT_CSV, index=False, encoding="utf-8-sig")
45    df.to_excel(OUTPUT_EXCEL, index=False, engine="openpyxl")
46    print(f"\nExported to {OUTPUT_CSV} and {OUTPUT_EXCEL}")

Запустите его командой python scrape_shopify.py. Для Allbirds это занимает около 45 секунд и создаёт CSV примерно с 5,000+ строками (по одной на вариант). Вывод в терминале будет примерно таким:

1Scraping https://allbirds.com...
2  Page 1... 250 products (total: 250)
3  Page 2... 250 products (total: 500)
4  ...
5  Page 6... 170 products (total: 1420)
6Total products scraped: 1420
7Flattening to variant-level rows...
8DataFrame: 5680 rows x 14 columns
9Exported to shopify_products.csv and shopify_products.xlsx

Пропустите Python: парсите Shopify в 2 клика с Thunderbit (no-code альтернатива)

Не всем хочется ставить Python, разбираться с ошибками импорта или поддерживать скрипт парсинга. Для менеджера по продажам, которому прайс конкурента нужен уже завтра утром, Python — это перебор.

Именно поэтому мы создали — AI web scraper в формате расширения Chrome. Никакого кода, никаких API-ключей, никакой настройки окружения.

Как Thunderbit парсит магазины на Shopify

В Thunderbit есть готовый Shopify Scraper template, уже настроенный под страницы товаров Shopify. Вы устанавливаете , переходите в магазин на Shopify и нажимаете «Scrape». Шаблон автоматически извлекает названия товаров, описания, цены, детали вариантов, изображения и информацию о продавце.

Если шаблон не совпадает идеально с конкретным магазином (кастомная тема, необычная верстка), функция Thunderbit AI Suggest Fields анализирует страницу и автоматически предлагает названия колонок. Их можно подстроить: переименовать столбцы, добавить поля, написать инструкции вроде «извлекай только товары, у которых задан compare_at_price».

Несколько функций напрямую повторяют то, что делает Python-скрипт:

  • Парсинг подстраниц: автоматически открывает каждую страницу товара и обогащает таблицу полными описаниями, отзывами или деталями вариантов — по сути то же, что делает наш Python-скрипт через проход по страницам, но без кода.
  • Автоматическая пагинация: обрабатывает переход по страницам и бесконечную прокрутку без дополнительной настройки.
  • Плановый запуск: можно настроить повторяющиеся задачи (например, «каждый понедельник в 9:00») для постоянного мониторинга цен — без cron и без сервера.
  • Бесплатный экспорт в CSV, Excel, Google Sheets, Airtable или Notion на всех тарифах.

Python-скрипт vs Thunderbit: честное сравнение

ФакторPython-скриптThunderbit (no-code)
Время на настройку15–60 мин (окружение + код)~2 мин (установить расширение Chrome)
Нужен кодДа (Python)Нет
НастройкаБез ограниченийПоля, предложенные AI, + собственные промпты
ПагинацияНужно писать вручнуюАвтоматически
Форматы экспортаНужно реализовать самому (CSV/Excel)CSV, Excel, Google Sheets, Airtable, Notion (бесплатно)
Периодические запускиCron + хостингВстроенный планировщик
Работа с rate limitsНужно писать retries/backoffОбрабатывается автоматически
Лучше всего подходит дляРазработчиков, больших data pipelineБизнес-пользователей, быстрых выгрузок, регулярного мониторинга

Используйте Python, когда нужен полный контроль или вы встраиваете сбор данных в более крупный pipeline. Используйте Thunderbit, когда данные нужны быстро и вы не хотите поддерживать код. Более подробно о мы отдельно писали в другом руководстве.

python-vs-thunderbit-comparison.webp

Советы и лучшие практики при парсинге Shopify-магазинов

Они актуальны независимо от того, какой инструмент вы выберете:

  • Всегда используйте ?limit=250, чтобы сократить число запросов. При стандартных 30 товарах на страницу запросов будет в 8 раз больше при тех же данных.
  • Уважайте магазин: делайте задержку 1–2 секунды между запросами. Агрессивные частые запросы — плохая практика и повышают риск блокировки.
  • Сначала проверьте robots.txt: стандартный robots.txt Shopify не блокирует /products.json. Но некоторые магазины добавляют свои правила, поэтому перед массовым парсингом это стоит проверить.
  • Сохраняйте сырой JSON локально, а уже потом обрабатывайте его. Если логика парсинга изменится, не придётся собирать данные заново. Простого json.dump(all_products, open("raw_data.json", "w")) перед преобразованием достаточно, чтобы сэкономить много времени.
  • Удаляйте дубликаты по product.id: на границах страниц иногда могут попадаться повторяющиеся товары. Быстрый df.drop_duplicates(subset=["product_id", "variant_id"]) решает проблему.
  • Преобразуйте price в float перед вычислениями. Shopify возвращает цены строкой ("185.00"), а не числом.
  • Следите за изменениями эндпоинта: хотя /products.json стабилен уже много лет, теоретически Shopify может его ограничить. Если скрипт внезапно начал получать 404, сначала проверьте магазин вручную.

Если хотите узнать больше о создании надёжных скрейперов, посмотрите наше руководство по .

Юридические и этические аспекты парсинга Shopify

Короткий раздел, но важный.

Эндпоинт /products.json отдаёт общедоступные данные о товарах — ту же информацию, которую видит любой посетитель магазина. В Terms of Service Shopify есть формулировки о запрете использовать «автоматизированные средства» для доступа к «Services», но это относится к самой платформе (админ-панель, checkout), а не к публичным данным витрины. По состоянию на апрель 2026 года не было подано ни одного иска, специфичного именно для парсинга Shopify.

Ключевые судебные прецеденты поддерживают сбор публичных данных: дело hiQ v. LinkedIn подтвердило, что парсинг общедоступной информации не нарушает CFAA, а Meta v. Bright Data (2024) постановило, что ограничения ToS действуют только тогда, когда пользователь вошёл в систему.

Лучшие практики:

  • Парсите только общедоступные данные о товарах
  • Не собирайте персональные данные и данные клиентов
  • Соблюдайте robots.txt и rate limits
  • Соблюдайте GDPR/CCPA, если обрабатываете персональные данные (данные каталога товаров не являются персональными)
  • Используйте понятный User-Agent
  • Парсить свой собственный магазин Shopify через Admin API — всегда нормально

Для более глубокого разбора см. наш материал о .

Выводы и главное

Публичный эндпоинт Shopify /products.json делает извлечение e-commerce данных максимально простым. Рабочий процесс такой: добавить /products.json → получить данные на Python → пройти пагинацию через ?limit=250&page= → превратить JSON в таблицу с помощью pandas → экспортировать в CSV или Excel.

Что это руководство даёт сверх обычных статей:

  • Полный справочник по полям: вы заранее знаете, какие данные доступны (40+ полей на уровне товаров, вариантов и изображений), ещё до написания первой строки кода
  • Дополнительные эндпоинты: /collections.json и /meta.json дают аналитику по категориям и метаданные магазина, чего нет у большинства конкурирующих статей
  • Техники для продакшена: повторное использование сессии, экспоненциальный backoff, заголовки User-Agent и ?limit=250 для работы с реальными rate limits
  • Корректный экспорт в CSV/Excel: плоские данные на уровне вариантов через pandas, а не просто выгрузка сырого JSON
  • No-code альтернатива: для тех, кому важнее скорость, чем гибкость кода

Для разовых или регулярных выгрузок данных Shopify без кода попробуйте — шаблон Shopify Scraper сам справится со всем: от пагинации до экспорта. Если же вам нужны кастомные data pipeline или масштабный парсинг сразу по многим магазинам, Python-скрипт из этого руководства даст полный контроль.

Посмотрите наш с видеоинструкциями или изучите наши материалы о и — там тоже много полезных приёмов.

Попробуйте Thunderbit для парсинга Shopify

Часто задаваемые вопросы

Можно ли парсить любой магазин Shopify через products.json?

У большинства магазинов Shopify этот эндпоинт открыт по умолчанию — в тестах валидный JSON возвращали около 71% сайтов. У некоторых магазинов с кастомной конфигурацией или дополнительными уровнями защиты (Cloudflare, headless-архитектура) может возвращаться 404 или блокироваться запрос. Быстрая проверка: откройте {store-url}/products.json в браузере. Если видите JSON, значит всё в порядке.

Законно ли парсить магазины Shopify?

Публичные данные о товарах (цены, названия, изображения, описания) обычно доступны, а судебные прецеденты вроде hiQ v. LinkedIn поддерживают сбор общедоступной информации. При этом всегда проверяйте Terms of Service конкретного магазина и местные законы. Не собирайте персональные данные и данные клиентов, а также соблюдайте rate limits.

Сколько товаров можно спарсить из магазина Shopify?

Жёсткого общего лимита нет. Пагинация через ?limit=250&page= позволяет получить весь каталог. Для очень крупных магазинов (25,000+ товаров) используйте повторное использование сессии и задержки, чтобы не упереться в rate limits. Эндпоинт /meta.json заранее покажет точное количество товаров, чтобы вы понимали, сколько страниц ожидать.

В чём разница между products.json и Shopify Admin API?

/products.json — это публичный эндпоинт: без авторизации, только чтение, доступен всем. Admin API требует токены доступа владельца магазина и даёт заказы, количество остатков, данные о клиентах и возможность записи. Если нужны данные о продажах или реальные остатки, нужен доступ к Admin API (то есть вы должны быть владельцем магазина или иметь его разрешение).

Можно ли парсить Shopify без Python?

Абсолютно. Инструменты вроде позволяют собирать данные с Shopify через расширение Chrome без кода. Пагинация обрабатывается автоматически, а экспорт идёт сразу в CSV, Excel, Google Sheets, Airtable или Notion. Для разработчиков, предпочитающих другие языки, тот же /products.json работает с JavaScript, Ruby, Go — любым языком, который умеет делать HTTP-запросы и парсить JSON.

Узнать больше

Содержание

Попробуй Thunderbit

Собирай лиды и другие данные всего в 2 клика. На базе AI.

Получить Thunderbit Это бесплатно
Извлекай данные с помощью AI
Легко передавай данные в Google Sheets, Airtable или Notion
Chrome Store Rating
PRODUCT HUNT#1 Product of the Week