Эндпоинт 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_at | ISO DateTime | "2024-01-15T10:30:00-05:00" | Отслеживание даты добавления товара (для выявления новых запусков) |
updated_at | ISO DateTime | "2025-03-01T08:00:00-05:00" | Выявление недавних изменений в каталоге |
published_at | ISO 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_at | ISO 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 на 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**: если вы парсите несколько магазинов, чередуйте 3–5 реалистичных браузерных 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, когда данные нужны быстро и вы не хотите поддерживать код. Более подробно о мы отдельно писали в другом руководстве.

Советы и лучшие практики при парсинге Shopify-магазинов
Они актуальны независимо от того, какой инструмент вы выберете:
- Всегда используйте
?limit=250, чтобы сократить число запросов. При стандартных 30 товарах на страницу запросов будет в 8 раз больше при тех же данных. - Уважайте магазин: делайте задержку 1–2 секунды между запросами. Агрессивные частые запросы — плохая практика и повышают риск блокировки.
- Сначала проверьте
robots.txt: стандартныйrobots.txtShopify не блокирует/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-скрипт из этого руководства даст полный контроль.
Посмотрите наш с видеоинструкциями или изучите наши материалы о и — там тоже много полезных приёмов.
Часто задаваемые вопросы
Можно ли парсить любой магазин 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.
Узнать больше