Endpointul /products.json din Shopify este unul dintre cele mai bine ascunse secrete din datele de ecommerce. Îl adaugi la orice URL de magazin Shopify și primești JSON structurat înapoi — fără chei API, fără autentificare, fără să mai sapi prin HTML-ul încurcat.
Lucrez în echipa , așa că petrec mult timp gândindu-mă la felul în care oamenii extrag date de pe web. Iar extragerea datelor din Shopify apare constant — echipe de vânzări care urmăresc prețurile concurenței, specialiști ecommerce care compară cataloage de produse, oameni din achiziții care caută furnizori noi. Cu pe Shopify și cu aproximativ deținută de platformă, volumul de date despre produse care pot fi extrase este uriaș.
Acest ghid acoperă tot procesul: ce returnează endpointul, cum parcurgi mii de produse prin paginare, cum gestionezi limitele de rată fără să fii blocat și cum transformi JSON-ul imbricat din Shopify într-un CSV sau fișier Excel curat folosind pandas. Voi acoperi și endpointurile despre care aproape nimeni nu vorbește (/collections.json, /meta.json) și voi arăta o alternativă fără cod pentru cei care preferă să sară complet peste Python.
Ce este endpointul /products.json din Shopify și de ce face extragerea atât de ușoară
Fiecare magazin Shopify are un endpoint public la {store-url}/products.json care returnează date structurate despre produse. Fără chei API. Fără OAuth. Fără autentificare de niciun fel. Pur și simplu adaugi /products.json la URL-ul magazinului și primești un tablou JSON cu toate produsele din catalog.
Testează chiar acum: deschide sau în browser. Vei vedea JSON clar, organizat, cu titluri de produse, prețuri, variante, imagini, etichete — tot ce ai nevoie.
Compară asta cu alternativa: analizarea temelor HTML din Shopify, care sunt profund imbricate, inconsistente de la un magazin la altul și se schimbă de fiecare dată când comerciantul își actualizează tema. Iată cu ce ai avea de-a face:
Abordarea HTML (chinuitoare):
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>
Abordarea JSON (curată):
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 câștigă la consistență, fiabilitate și ușurință de parsare. Endpointul suportă și doi parametri cheie — ?limit= (până la 250 de produse pe pagină, implicit 30) și ?page= pentru paginare — pe care îi vom folosi intens în codul de mai jos.
Distincție importantă: acesta este un endpoint public al vitrinei online, nu . Admin API necesită tokenuri de acces de la proprietarul magazinului și oferă date despre comenzi, niveluri de stoc și informații despre clienți. Endpointul public /products.json oferă doar date de produs, read-only, accesibile oricui. Voi explica diferența în detaliu mai jos, pentru că e o confuzie foarte răspândită pe forumuri.
O precizare: nu orice magazin Shopify expune acest endpoint. În testele mele, aproximativ 71% dintre magazine returnează JSON valid (allbirds.com, gymshark.com, colourpop.com, kyliecosmetics.com funcționează), în timp ce unele configurații personalizate returnează 404 (hiutdenim.co.uk, bombas.com). Verificarea rapidă e simplă: intră pe {store-url}/products.json în browser și vezi ce primești.
De ce să extragi date din Shopify cu Python? Principalele cazuri de utilizare în business
De ce să te complici? ROI-ul. folosesc acum extragerea automatizată a prețurilor pentru competitive intelligence, față de doar 34% în 2020. Iar cercetările arată că o . Datele chiar valorează bani.
Iată cele mai frecvente utilizări pe care le văd:
This paragraph contains content that cannot be parsed and has been skipped.
Python este alegerea firească pentru acest tip de muncă. folosesc Python ca limbaj principal, iar ecosistemul — requests pentru HTTP, pandas pentru manipularea datelor, httpx pentru async — face foarte simplu drumul de la „am un URL” la „am un spreadsheet” în mai puțin de 80 de linii de cod.
Referință completă pentru câmpurile din products.json: explicația fiecărui câmp
Fiecare tutorial concurent îți arată title, id și handle, apoi merge mai departe. Răspunsul JSON din Shopify conține peste 40 de câmpuri pentru produse, variante, imagini și opțiuni. Dacă știi ce este disponibil înainte să scrii codul de scraping, eviți să refaci extragerea mai târziu.
Am preluat această referință din răspunsuri live de la /products.json, colectate pe 16 aprilie 2026. Structura este consistentă în toate magazinele care expun endpointul.
Câmpuri la nivel de produs
| Câmp | Tip de date | Valoare exemplu | Utilizare în business |
|---|---|---|---|
id | Integer | 123456789 | Identificator unic al produsului pentru deduplicare |
title | String | "Classic Blue Jeans" | Numele produsului pentru cataloage și comparații |
handle | String | "classic-blue-jeans" | Slug URL — construiești linkurile paginii produsului ca {store}/products/{handle} |
body_html | String (HTML) sau null | Our best-selling... | Descrierea produsului pentru analiză de conținut și cercetare SEO |
vendor | String | "Hiut Denim" | Numele brandului/furnizorului pentru lead gen sau aprovizionare |
product_type | String | "Jeans" | Clasificare de categorie pentru analiza pieței |
created_at | ISO DateTime | "2024-01-15T10:30:00-05:00" | Urmărești când au fost adăugate produsele (detectarea lansărilor noi) |
updated_at | ISO DateTime | "2025-03-01T08:00:00-05:00" | Detectezi modificări recente în catalog |
published_at | ISO DateTime | "2024-01-16T00:00:00-05:00" | Afli când au devenit publice produsele în magazin |
tags | Array de Stringuri | ["organic", "women", "straight-leg"] | Analiză de cuvinte cheie/etichete pentru SEO, categorizare și identificarea tendințelor |
variants | Array de Obiecte | (vezi câmpurile variantelor mai jos) | Preț, SKU, disponibilitate pentru fiecare variantă |
images | Array de Obiecte | (vezi câmpurile imaginilor mai jos) | URL-uri pentru imagini de produs, utile pentru cataloage și analiză vizuală |
options | Array de Obiecte | [{"name": "Size", "values": ["S","M","L"]}] | Înțelegi configurarea produsului (mărime, culoare, material) |
Câmpuri la nivel de variantă (imbricate în fiecare produs)
| Câmp | Tip de date | Exemplu | Utilizare |
|---|---|---|---|
id | Integer | 987654321 | Identificator unic al variantei |
title | String | "32 / Blue" | Numele afișat al variantei |
sku | String | "HD-BLU-32" | Potrivirea SKU-ului în sistemele de inventar |
price | String | "185.00" | Monitorizarea prețurilor (atenție: este string, transformă-l în float pentru calcule) |
compare_at_price | String sau null | "200.00" | Prețul original — esențial pentru urmărirea reducerilor |
available | Boolean | true | Disponibilitatea stocului (singurul indicator public de stoc) |
weight | Float | 1.2 | Analiză pentru livrare/logistică |
option1, option2, option3 | String | "32", "Blue", null | Valorile individuale ale opțiunilor |
created_at, updated_at | ISO DateTime | — | Urmărirea modificărilor la nivel de variantă |
Câmpuri la nivel de imagine
| Câmp | Tip de date | Exemplu | Utilizare |
|---|---|---|---|
id | Integer | 111222333 | Identificator unic al imaginii |
src | String (URL) | "https://cdn.shopify.com/..." | Link direct pentru descărcarea imaginii |
alt | String sau null | "Front view of jeans" | Text alternativ pentru analiza accesibilității |
position | Integer | 1 | Ordinea imaginilor |
width, height | Integer | 2048, 2048 | Dimensiunile imaginii |
Ce NU este disponibil în endpointul public
Un detaliu important: inventory_quantity NU este disponibil în răspunsurile publice /products.json. Acest câmp a fost eliminat din endpointurile publice în decembrie 2017 din motive de securitate. Singurul indicator de stoc pe care îl primești este câmpul boolean available de la fiecare variantă (true sau false). Ca să accesezi cantitățile reale din inventar, ai nevoie de Admin API autenticat, cu credențiale de la proprietarul magazinului.
Înainte să scrii codul de scraping, parcurge acest tabel și decide ce câmpuri contează pentru cazul tău de utilizare. Dacă faci monitorizare de preț, ai nevoie de variants[].price, variants[].compare_at_price și variants[].available. Dacă faci lead gen, concentrează-te pe vendor, product_type și tags. Filtrează în consecință — CSV-ul va fi mult mai curat.
Dincolo de products.json: colecții, meta și alte endpointuri Shopify
Niciun tutorial concurent nu menționează aceste endpointuri. Sunt esențiale pentru lucru serios de competitive intelligence.
/collections.json — toate categoriile magazinului
Returnează toate colecțiile (categoriile) din magazin, cu titluri, handle-uri, descrieri și numărul de produse. Am verificat asta pe zoologistperfumes.com, allbirds.com și gymshark.com — toate au returnat JSON valid.
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}
Vrei să înțelegi cum își organizează un concurent catalogul? Acesta este endpointul.
/collections/{handle}/products.json — produse dintr-o anumită categorie
Returnează produsele filtrate pentru o colecție specifică. Are aceeași structură JSON ca /products.json, dar este limitat la o singură categorie. E foarte util pentru scraping la nivel de categorie — de exemplu, dacă vrei să monitorizezi doar colecția „Sale” sau „New Arrivals” a unui concurent.
/meta.json — metadate la nivel de magazin
Returnează numele magazinului, descrierea, moneda, țara și — partea cea mai utilă — published_products_count. Acest contor îți permite să calculezi exact câte pagini de paginare vei avea nevoie: ceil(published_products_count / 250). Nu mai trebuie să incrementezi orbește paginile până când primești un răspuns gol.
Ce endpoint ar trebui să folosești?
| Ce vrei să obții | Endpoint | Necesită autentificare? |
|---|---|---|
| Toate produsele (public) | /products.json | Nu |
| Produse dintr-o categorie anume | /collections/{handle}/products.json | Nu |
| Metadate magazin + număr de produse | /meta.json | Nu |
| Toate colecțiile (categoriile) | /collections.json | Nu |
| Date despre comenzi/vânzări (doar propriul magazin) | Admin API /orders.json | Da (cheie API) |
| Cantități din inventar (doar propriul magazin) | Admin API /inventory_levels.json | Da |
Întrebarea repetată pe forumuri — „Pot să văd câte unități a vândut un concurent?” — are un răspuns scurt: nu. Nu din endpointurile publice. Datele despre vânzări și cantitățile din inventar necesită Admin API autentificat, ceea ce înseamnă că ai nevoie de acces de la proprietarul magazinului. Endpointurile publice oferă doar date despre catalogul de produse.

Cum să extragi date din Shopify cu Python: configurare pas cu pas
- Nivel de dificultate: Începător
- Timp necesar: ~15 minute (configurare + prima extragere)
- Ce îți trebuie: Python 3.11+,
pip, un terminal și URL-ul unui magazin Shopify de extras
Pasul 1: Instalează Python și bibliotecile necesare
Asigură-te că ai instalat Python 3.11 sau o versiune mai nouă (pandas 3.0.x îl cere). Apoi instalează cele două biblioteci de care avem nevoie:
1pip install requests pandas
Pentru export în Excel, mai ai nevoie și de:
1pip install openpyxl
La începutul scriptului, adaugă aceste importuri:
1import requests
2import pandas as pd
3import time
4import random
5import json
Nu ar trebui să apară erori la import atunci când rulezi scriptul. Dacă pandas dă o eroare de versiune, actualizează Python la 3.12.
Pasul 2: Preia datele despre produse din /products.json
Iată o funcție de bază care primește un URL de magazin, apelează endpointul și returnează JSON-ul parsabil:
1def fetch_products_page(store_url, page=1, limit=250):
2 """Preia o singură pagină de produse dintr-un magazin Shopify."""
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", [])
Detalii importante:
limit=250este maximul permis de Shopify per pagină. Implicit este 30, deci setarea explicită reduce numărul total de cereri de până la 8 ori.- Headerul
User-Agent: folosește mereu unul realist. Cererile fără User-Agent au șanse mai mari să declanșeze sistemele anti-bot ale Shopify. timeout=30: nu lăsa o singură cerere să se blocheze la nesfârșit.
Testează cu un magazin cunoscut:
1products = fetch_products_page("https://allbirds.com")
2print(f"Am preluat {len(products)} produse")
3print(f"Primul produs: {products[0]['title']}")
Ar trebui să vezi ceva de genul: Am preluat 250 produse și apoi titlul primului produs.
Pasul 3: Gestionează paginarea pentru a extrage toate produsele
O singură cerere returnează cel mult 250 de produse. Majoritatea magazinelor au mai multe (Allbirds are peste 1.420). Trebuie să parcurgi paginile până când primești un răspuns gol.
1def scrape_all_products(store_url, delay=1.0):
2 """Extrage toate produsele dintr-un magazin Shopify, gestionând paginarea."""
3 all_products = []
4 page = 1
5 while True:
6 print(f"Se preia pagina {page}...")
7 products = fetch_products_page(store_url, page=page, limit=250)
8 if not products:
9 print(f"Nu mai sunt produse. Total: {len(all_products)}")
10 break
11 all_products.extend(products)
12 print(f" Am obținut {len(products)} produse (total până acum: {len(all_products)})")
13 page += 1
14 # Fii politicos: așteaptă între cereri
15 time.sleep(delay + random.uniform(0, 0.5))
16 return all_products
Când products revine gol, ai ajuns la final.
time.sleep() cu un mic jitter aleator te menține sub limita informală de rată a Shopify (~2 cereri/secundă).
Sfat util: dacă ai preluat mai întâi /meta.json, știi deja numărul total de produse și poți calcula exact câte pagini ai nevoie: pages = ceil(product_count / 250). Asta elimină modelul de „o cerere goală în plus la final”.
Pasul 4: Parsează și selectează câmpurile de care ai nevoie
Acum că ai toate produsele sub forma unei liste Python de dicționare, extrage doar câmpurile care te interesează. Iată un exemplu care preia cele mai comune câmpuri pentru monitorizarea prețurilor:
1def extract_product_data(products):
2 """Extrage câmpurile cheie din produse, aplatizând variantele."""
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
Asta creează câte un rând pentru fiecare variantă — formatul cel mai util pentru comparații de preț, pentru că un singur produs precum „Classic Blue Jeans” poate avea 12 variante (6 mărimi × 2 culori), fiecare cu propriul preț și propria stare de disponibilitate.
Exportă datele Shopify extrase în CSV și Excel cu pandas
Fiecare alt tutorial despre scraping Shopify aruncă JSON brut într-un fișier și gata. E ok pentru dezvoltatori. Inutil pentru analistul ecommerce care are nevoie de un spreadsheet până vineri.
Problema: JSON-ul din Shopify este imbricat. Un produs poate conține o duzină de variante, fiecare cu propriul preț, SKU și disponibilitate. Aplatizarea într-un tabel cu rânduri și coloane necesită puțină muncă în pandas.
Aplatizează JSON-ul imbricat într-un tabel curat
Există două abordări, în funcție de ce ai nevoie:
Varianta A: un rând pentru fiecare variantă (cea mai bună pentru monitorizarea prețurilor și a stocurilor)
1# Folosind funcția extract_product_data din Pasul 4
2products = scrape_all_products("https://allbirds.com")
3rows = extract_product_data(products)
4df = pd.DataFrame(rows)
5print(f"Forma DataFrame-ului: {df.shape}")
6print(df.head())
Asta îți oferă un tabel plat în care fiecare rând este o combinație unică produs-variantă. Un magazin cu 500 de produse și o medie de 4 variante per produs produce un DataFrame de aproximativ 2.000 de rânduri.
Varianta B: un rând pentru rezumatul fiecărui produs (cea mai bună pentru o privire de ansamblu asupra catalogului)
1def summarize_products(products):
2 """Un rând per produs, cu preț minim/maxim între variante."""
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
Exportă în CSV, Excel și Google Sheets
1# Export CSV (folosește utf-8-sig ca Excel să gestioneze corect caracterele speciale)
2df.to_csv("shopify_products.csv", index=False, encoding="utf-8-sig")
3# Export Excel (necesită openpyxl)
4df.to_excel("shopify_products.xlsx", index=False, engine="openpyxl")
5print("Exportat în shopify_products.csv și shopify_products.xlsx")
Pentru Google Sheets, poți folosi biblioteca gspread cu un service account, dar sincer — pentru majoritatea cazurilor, exportul în CSV și încărcarea în Google Drive este mai rapid și mai simplu.
Scraping Python pregătit pentru producție: limite de rată, retry-uri și anti-blocare
Scriptul de bază merge bine pentru magazine mici. Dar dacă extragi un magazin cu peste 5.000 de produse sau lovești mai multe magazine la rând? Acolo încep problemele.
Înțelegerea limitelor de rată și a comportamentului de blocare din Shopify
Endpointurile publice JSON din Shopify nu au limite de rată documentate oficial (spre deosebire de modelul leaky bucket din Admin API), dar testele empirice arată:
- Rată sigură: ~2 cereri pe secundă per magazin
- Prag moale: ~40 de cereri pe minut înainte să apară throttling-ul
- HTTP 429: „Too Many Requests” — răspunsul standard la limitarea de rată
- HTTP 430: un cod specific Shopify care indică o blocare la nivel de securitate (nu doar rate limiting)
- HTTP 403 sau redirecționare către CAPTCHA: unele magazine au protecție Cloudflare suplimentară
Cererile venite din infrastructură cloud partajată (AWS Lambda, Google Cloud Run) au șanse mai mari să declanșeze blocări, pentru că aceste intervale IP au rate mari de abuz.
Tehnici pentru a extrage date din Shopify în mod fiabil
Iată evoluția de la „merge pe laptopul meu” la „rulează în producție”:
| Nivel | Tehnică | Fiabilitate |
|---|---|---|
| De bază | requests.get() + ?page= | Se rupe la cataloage mari, poate fi blocat |
| Intermediar | requests.Session() + ?limit=250 + time.sleep(1) + retry la 429 | Funcționează pentru majoritatea magazinelor |
| Avansat | httpx async + rotire User-Agent + exponential backoff | Pregătit pentru producție, scalabil la peste 10K produse |
Nivel intermediar (recomandat pentru majoritatea utilizatorilor):
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.
5Configurația `Retry` gestionează automat răspunsurile 429 cu exponential backoff. `backoff_factor=1` înseamnă că secvența de așteptare este 0.5s → 1s → 2s → 4s → 8s între retry-uri. Reutilizarea sesiunii (`requests.Session()`) îți oferă și connection pooling, ceea ce reduce overhead-ul atunci când faci mai multe cereri către același domeniu.
6**Rotirea User-Agent-ului**: dacă extragi mai multe magazine, alternează între 3–5 stringuri User-Agent realiste de browser. Nu e vorba de a induce în eroare, ci de a nu arăta ca un bot care trimite același header la fiecare cerere.
7<iframe width="560" height="315" src="https://www.youtube.com/embed/p3Z-qtUp4p8" title="Proiect de web scraping: salvează produsele Shopify într-o bază de date" frameBorder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowFullScreen></iframe>
8## Script Python complet, funcțional, pentru extragerea Shopify cu export CSV
9Mai jos ai scriptul complet, gata de copiat și lipit, care combină tot ce am explicat mai sus. Are aproximativ 75 de linii de cod efectiv (plus comentarii) și l-am testat pe Allbirds (1.420 de produse), ColourPop (peste 2.000 de produse) și Zoologist Perfumes (catalog mic).
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 """Extrage toate produsele dintr-un magazin Shopify prin /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)} produse (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" # Schimbă cu magazinul țintă
35 OUTPUT_CSV = "shopify_products.csv"
36 OUTPUT_EXCEL = "shopify_products.xlsx"
37 print(f"Se extrag date din {STORE_URL}...")
38 products = scrape_shopify(STORE_URL)
39 print(f"\nTotal produse extrase: {len(products)}")
40 print("Aplatizare la nivel de variantă...")
41 rows = flatten_to_variants(products)
42 df = pd.DataFrame(rows)
43 print(f"DataFrame: {df.shape[0]} rânduri x {df.shape[1]} coloane")
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"\nExportat în {OUTPUT_CSV} și {OUTPUT_EXCEL}")
Rulează-l cu python scrape_shopify.py. Pentru Allbirds, durează cam 45 de secunde și produce un CSV cu peste 5.000 de rânduri (câte unul pentru fiecare variantă). Outputul din terminal arată cam așa:
1Se extrag date din https://allbirds.com...
2 Pagina 1... 250 produse (total: 250)
3 Pagina 2... 250 produse (total: 500)
4 ...
5 Pagina 6... 170 produse (total: 1420)
6Total produse extrase: 1420
7Aplatizare la nivel de variantă...
8DataFrame: 5680 rânduri x 14 coloane
9Exportat în shopify_products.csv și shopify_products.xlsx
Sare peste Python: extrage Shopify în 2 clickuri cu Thunderbit (alternativă no-code)
Nu toată lumea vrea să instaleze Python, să depaneze erori de import sau să întrețină un script de scraping. Pentru un reprezentant de vânzări care are nevoie de prețurile concurenței până mâine dimineață, Python este prea mult.
De aceea am creat — un AI web scraper care rulează ca extensie Chrome. Fără cod, fără chei API, fără configurare de mediu.
Cum extrage Thunderbit date din magazinele Shopify
Thunderbit are un Shopify Scraper template dedicat, preconfigurat pentru paginile de produse Shopify. Instalezi , navighezi la un magazin Shopify și dai click pe „Scrape”. Templateul extrage automat numele produselor, descrierile, prețurile, detaliile variantelor, imaginile și informațiile despre furnizor.
Pentru magazinele în care templateul nu se potrivește perfect (teme personalizate, layout-uri neobișnuite), funcția AI Suggest Fields din Thunderbit citește pagina și generează automat nume de coloane. Le poți personaliza — redenumești coloane, adaugi câmpuri, scrii instrucțiuni precum „extrage doar produsele care au setat compare_at_price”.
Câteva funcții care corespund direct cu ce face scriptul Python:
- Subpage scraping: vizitează automat fiecare pagină de detalii a produsului și îmbogățește tabelul cu descrieri complete, recenzii sau detalii despre variante — exact ce face scriptul nostru Python prin parcurgerea paginilor, dar fără cod.
- Paginare automată: gestionează automat click-urile pe pagini și scroll-ul infinit, fără configurare.
- Scraping programat: setezi joburi recurente (de exemplu, „în fiecare luni la ora 9:00”) pentru monitorizarea continuă a prețurilor — fără cron job sau server.
- Export gratuit în CSV, Excel, Google Sheets, Airtable sau Notion, indiferent de plan.
Script Python vs. Thunderbit: comparație sinceră
| Factor | Script Python | Thunderbit (fără cod) |
|---|---|---|
| Timp de configurare | 15–60 min (mediu + cod) | ~2 min (instalezi extensia Chrome) |
| Necesită codare | Da (Python) | Nu |
| Personalizare | Nelimitată | Câmpuri sugerate de AI + prompturi personalizate |
| Gestionarea paginării | Trebuie programată manual | Automată |
| Formate de export | Le scrii tu (CSV/Excel) | CSV, Excel, Google Sheets, Airtable, Notion (gratuit) |
| Rulare programată | Cron job + hosting | Scheduler integrat |
| Gestionarea limitelor de rată | Trebuie codate retry-uri/backoff | Gestionată automat |
| Cel mai potrivit pentru | Dezvoltatori, pipeline-uri mari de date | Utilizatori business, extrageri rapide, monitorizare recurentă |
Folosește Python când ai nevoie de control total sau când integrezi datele într-un pipeline mai mare. Folosește Thunderbit când ai nevoie rapid de date și nu vrei să întreții cod. Pentru o analiză mai detaliată despre , am scris un ghid separat pe această temă.

Sfaturi și bune practici pentru extragerea datelor din magazine Shopify
Acestea se aplică indiferent de instrumentul ales:
- Folosește întotdeauna
?limit=250ca să reduci numărul total de cereri. Implicitul de 30 per pagină înseamnă de 8 ori mai multe requesturi pentru aceleași date. - Respectă magazinul: adaugă întârzieri de 1–2 secunde între cereri. Bombardarea serverului cu requesturi rapide este o practică proastă și crește șansele să fii blocat.
- Verifică mai întâi
robots.txt:robots.txtimplicit din Shopify NU blochează/products.json. Totuși, unele magazine adaugă reguli personalizate, așa că verifică înainte să faci scraping la scară mare. - Salvează mai întâi JSON-ul brut local, apoi procesează-l. Dacă logica de parsare se schimbă mai târziu, nu va trebui să re-extragi datele. Un simplu
json.dump(all_products, open("raw_data.json", "w"))înainte de aplatizare te scapă de bătăi de cap. - Deduplicate după
product.id: uneori, la limitele dintre pagini pot apărea produse duplicate. Un rapiddf.drop_duplicates(subset=["product_id", "variant_id"])rezolvă problema. - Transformă
priceîn float înainte să faci calcule. Shopify returnează prețurile ca stringuri ("185.00"), nu ca numere. - Monitorizează eventualele schimbări ale endpointului: deși
/products.jsona fost stabil de ani de zile, teoretic Shopify ar putea să-l restricționeze. Dacă scraperul începe brusc să primească 404, verifică mai întâi manual magazinul.
Pentru mai multe despre cum construiești scrapers rezistenți, vezi ghidul nostru despre .
Considerații legale și etice când extragi date din Shopify
Secțiune scurtă, dar importantă.
Endpointul /products.json servește date despre produse disponibile public — exact aceleași informații pe care le vede orice vizitator când navighează magazinul. Termenii și condițiile Shopify conțin formulări despre nefolosirea „mijloacelor automate” pentru accesarea „Serviciilor”, dar această formulare se referă la platformă în sine (dashboard admin, checkout), nu la datele publice din vitrină. Până în aprilie 2026, nu au fost intentate procese specifice Shopify legate de scraping.
Precedentele juridice susțin scrapingul datelor publice: cazul hiQ v. LinkedIn a stabilit că extragerea datelor accesibile public nu încalcă CFAA, iar Meta v. Bright Data (2024) a decis că restricțiile din TOS se aplică doar când utilizatorul este logat.
Bune practici:
- Extrage doar datele publice despre produse
- Nu extrage date personale sau despre clienți
- Respectă
robots.txtși limitele de rată - Respectă GDPR/CCPA dacă prelucrezi orice fel de date personale (datele din catalogul de produse nu sunt personale)
- Identifică-te cu un string clar de User-Agent
- Extragerea propriului magazin Shopify prin Admin API este întotdeauna în regulă
Pentru o analiză mai detaliată, vezi articolul nostru despre .
Concluzie și idei esențiale
Endpointul public /products.json din Shopify face extragerea datelor de ecommerce incredibil de simplă. Fluxul este: adaugi /products.json → extragi cu Python → parcurgi paginarea cu ?limit=250&page= → aplatizezi cu pandas → exporți în CSV sau Excel.
Ce acoperă acest ghid și nu acoperă altele:
- Referință completă a câmpurilor: știi exact ce date sunt disponibile (peste 40 de câmpuri pentru produse, variante și imagini) înainte să scrii primul rând de cod
- Endpointuri suplimentare:
/collections.jsonși/meta.jsonîți oferă intelligence la nivel de categorie și metadate despre magazin, pe care niciun alt tutorial nu le acoperă - Tehnici pregătite pentru producție: reutilizarea sesiunii, exponential backoff, headere User-Agent și
?limit=250pentru a face față limitelor reale de rată - Export corect în CSV/Excel: date aplatizate la nivel de variantă, folosind pandas, nu doar dump-uri brute de JSON
- Alternativă no-code: pentru utilizatorii care preferă viteza în locul flexibilității codului
Pentru extrageri unice sau recurente din Shopify fără cod, încearcă — templateul Shopify Scraper se ocupă de tot, de la paginare la export. Pentru pipeline-uri personalizate sau scraping la scară mare în mai multe magazine, scriptul Python din acest ghid îți oferă control total.
Vezi pentru tutoriale video sau explorează ghidurile noastre despre și pentru tehnici conexe.
Întrebări frecvente
Poți extrage date din orice magazin Shopify cu products.json?
Cele mai multe magazine Shopify expun acest endpoint în mod implicit — în testele mele, aproximativ 71% au returnat JSON valid. Unele magazine cu configurații personalizate sau straturi suplimentare de securitate (Cloudflare, setup-uri headless) pot returna 404 sau pot bloca cererea. Verificarea rapidă: intră pe {store-url}/products.json în browser. Dacă vezi JSON, ești ok.
Este legal să extragi date din magazine Shopify?
Datele publice despre produse (prețuri, titluri, imagini, descrieri) sunt în general accesibile, iar precedente juridice precum hiQ v. LinkedIn susțin extragerea informațiilor disponibile public. Totuși, verifică întotdeauna termenii și condițiile magazinului și legile locale. Nu extrage date personale sau despre clienți și respectă limitele de rată.
Câte produse poți extrage dintr-un magazin Shopify?
Nu există o limită fixă pentru total. Paginarea cu ?limit=250&page= îți permite să recuperezi întregul catalog. Pentru magazine foarte mari (peste 25.000 de produse), folosește reutilizarea sesiunii și pauze între cereri ca să eviți rate limits. Endpointul /meta.json îți poate spune din start numărul exact de produse, ca să știi câte pagini să aștepți.
Care este diferența dintre products.json și Shopify Admin API?
/products.json este un endpoint public — fără autentificare, doar date de produs, accesibil oricui. Admin API cere tokenuri de acces de la proprietarul magazinului și oferă comenzi, cantități din inventar, date despre clienți și acces de scriere. Dacă ai nevoie de date despre vânzări sau de cantități reale din stoc, ai nevoie de acces la Admin API (adică trebuie să fii proprietarul magazinului sau să ai permisiunea acestuia).
Pot extrage date din Shopify fără Python?
Absolut. Instrumente precum îți permit să extragi date din magazine Shopify direct din extensia Chrome, fără cod. Gestionează automat paginarea și exportă direct în CSV, Excel, Google Sheets, Airtable sau Notion. Pentru dezvoltatorii care preferă alte limbaje, același endpoint /products.json funcționează și cu JavaScript, Ruby, Go — practic orice limbaj care poate face cereri HTTP și poate parsa JSON.
Află mai multe