Shopifyn /products.json-päätepiste on yksi verkkokauppadatan huonosti vartioiduimmista aarteista. Lisää se minkä tahansa Shopify-kaupan URL-osoitteen loppuun, niin saat takaisin jäsenneltyä JSON-dataa — ilman API-avaimia, ilman tunnistautumista ja ilman sitä, että sinun täytyy penkoa läpi monimutkaista HTML:ää.
Työskentelen -tiimissä, joten mietin koko ajan, miten ihmiset hakevat dataa verkosta. Shopify-datan poiminta nousee esiin kerta toisensa jälkeen: myyntitiimit seuraavat kilpailijoiden hintoja, verkkokaupan operatiiviset tiimit vertailevat tuotevalikoimia ja hankintatiimit etsivät uusia toimittajia. Kun Shopifylla on ja alusta kattaa noin , poimittavaa tuotetietoa on valtavasti.
Tämä opas käy läpi koko prosessin: mitä päätepiste palauttaa, miten satojen tai tuhansien tuotteiden läpikäynti onnistuu, miten vältät estot rate limit -rajojen keskellä ja miten Shopifyn sisäkkäinen JSON muunnetaan siistiksi CSV- tai Excel-tiedostoksi pandasilla. Mukana ovat myös päätepisteet, joista muut eivät juuri puhu (/collections.json, /meta.json), sekä vaihtoehto ilman koodausta niille, jotka haluavat ohittaa Pythonin kokonaan.
Mikä Shopifyn /products.json-päätepiste on, ja miksi se tekee datan poiminnasta helppoa?
Jokaisella Shopify-kaupalla on julkinen päätepiste osoitteessa {store-url}/products.json, joka palauttaa jäsenneltyä tuotetietoa. Ei API-avaimia. Ei OAuthia. Ei minkäänlaista tunnistautumista. Lisää vain /products.json kaupan URL-osoitteen loppuun, niin saat JSON-taulukon koko katalogin tuotteista.
Kokeile vaikka heti: avaa selaimessa tai . Näet siistiä, jäsenneltyä JSONia, jossa on tuotteen nimi, hinta, versiot, kuvat, tunnisteet — kaikki.
Verrattuna vaihtoehtoon: Shopifyn HTML-teemojen purkaminen on työlästä, koska rakenne on monitasoinen, kauppakohtaisesti vaihteleva ja muuttuu aina, kun kauppias päivittää teemansa. Tästä olisi kyse:
HTML-lähestymistapa (vaivalloinen):
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-lähestymistapa (selkeä):
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 voittaa johdonmukaisuudessa, luotettavuudessa ja helpossa käsiteltävyydessä. Päätepiste tukee myös kahta keskeistä kyselyparametria — ?limit= (enintään 250 tuotetta per sivu, oletuksena 30) ja ?page= sivutukseen — ja käytämme niitä laajasti alla olevassa koodissa.
Tärkeä ero: kyseessä on julkinen verkkokaupan päätepiste, ei . Admin API vaatii kaupan omistajan tunnisteet ja antaa pääsyn tilauksiin, varastotasoihin ja asiakastietoihin. Julkinen /products.json-päätepiste tarjoaa vain tuotetietoa, jota kuka tahansa voi lukea. Kerron eron tarkemmin myöhemmin, koska tästä syntyy paljon hämmennystä foorumeilla.
Huomio: kaikki Shopify-kaupat eivät paljasta tätä päätepistettä. Omissa testeissäni noin 71 % kaupoista palautti kelvollisen JSONin (esim. allbirds.com, gymshark.com, colourpop.com, kyliecosmetics.com toimivat), mutta osa räätälöidyistä toteutuksista palauttaa 404:n (hiutdenim.co.uk, bombas.com). Nopea tarkistus on helppo: käy osoitteessa {store-url}/products.json selaimessa ja katso, mitä saat.
Miksi Shopify kannattaa scrapeata Pythonilla? Tärkeimmät liiketoiminnan käyttötapaukset
Miksi nähdä vaivaa? ROI:n takia. käyttää nyt automatisoitua hintaseurantaa kilpailija-analyysiin, kun osuus oli vain 34 % vuonna 2020. Ja tutkimusten mukaan . Tässä datassa on siis oikeaa rahaa.
Yleisimmät käyttötapaukset, joita näen:
| Käyttötapaus | Kenelle hyödyksi | Mitä saat |
|---|---|---|
| Kilpailijoiden hintaseuranta | Verkkokaupan operatiiviset tiimit | Seuraa hinnanmuutoksia, alennuksia ja vertailuhintoja kilpailijoiden katalogeissa |
| Tuotetutkimus ja hankinta | Hankinta / tuotevalikoiman hallinta | Vertaa ominaisuuksia, versioita, materiaaleja ja saatavuutta |
| Liidien generointi | Myyntitiimit | Poimi kauppakatalogeista toimittajanimet, bränditiedot ja yhteystiedot |
| Markkina- ja kategoriatutkimus | Markkinointitiimit | Ymmärrä tuotemix, tunnisteet, kokoelmien rakenne ja asemointi |
| Varasto- ja saatavuusseuranta | Toimitusketjutiimit | Seuraa varianttikohtaista saatavuutta (available: true/false) ajan mittaan |
| Uusien tuotteiden tunnistus | Tuotetiimit | Seuraa created_at-aikaleimoja ja huomaa kilpailijoiden uudet lanseeraukset |
Python on tähän työhön luonteva valinta. käyttää Pythonia ensisijaisena kielenään, ja ekosysteemi — requests HTTP-kutsuihin, pandas datan käsittelyyn, httpx asynkroniseen käyttöön — tekee URL-osoitteesta taulukoksi -polun rakentamisesta suoraviivaista alle 80 rivillä koodia.
Täydellinen products.json-kenttäviite: mitä kaikki kentät tarkoittavat
Useimmat oppaat näyttävät vain title, id ja handle, ja siirtyvät siitä eteenpäin. Shopifyn JSON-vastaus sisältää kuitenkin yli 40 kenttää tuotteissa, varianteissa, kuvissa ja optioissa. Kun tiedät, mitä on tarjolla ennen scraping-koodin kirjoittamista, vältät sen, että joudut tekemään kaiken uusiksi myöhemmin.
Tämä viite perustuu live-vastauksiin osoitteesta /products.json, jotka haettiin 16.4.2026. Rakenne on sama kaikissa kaupoissa, jotka paljastavat tämän päätepisteen.
Tuotetason kentät
| Kenttä | Tietotyyppi | Esimerkkiarvo | Liiketoiminnallinen käyttö |
|---|---|---|---|
id | Kokonaisluku | 123456789 | Yksilöllinen tuotetunniste deduplikointiin |
title | Merkkijono | "Classic Blue Jeans" | Tuotenimi katalogeihin ja vertailuihin |
handle | Merkkijono | "classic-blue-jeans" | URL-slug — rakenna tuotesivun linkit muodossa {store}/products/{handle} |
body_html | Merkkijono (HTML) tai null | Our best-selling... | Tuotekuvaus sisällön analyysiin ja SEO-tutkimukseen |
vendor | Merkkijono | "Hiut Denim" | Brändi-/toimittajan nimi liidien hankintaan tai sourcingiin |
product_type | Merkkijono | "Jeans" | Luokituskenttä markkina-analyysiin |
created_at | ISO DateTime | "2024-01-15T10:30:00-05:00" | Seuraa, milloin tuotteet lisättiin (uudet lanseeraukset) |
updated_at | ISO DateTime | "2025-03-01T08:00:00-05:00" | Havaitse viimeaikaiset muutokset katalogissa |
published_at | ISO DateTime | "2024-01-16T00:00:00-05:00" | Tiedä, milloin tuote julkaistiin verkkokaupassa |
tags | Merkkijonotaulukko | ["organic", "women", "straight-leg"] | Avainsana-/tagianalyysi SEO:hon, luokitteluun ja trendien tunnistamiseen |
variants | Objektitaulukko | (katso varianttikentät alempaa) | Hinta, SKU ja saatavuus varianttitasolla |
images | Objektitaulukko | (katso kuvakentät alempaa) | Tuotekuvien URL-osoitteet katalogeihin ja visuaaliseen analyysiin |
options | Objektitaulukko | [{"name": "Size", "values": ["S","M","L"]}] | Ymmärrä tuotteen konfiguraatio (koko, väri, materiaali) |
Varianttitason kentät (sisäkkäin jokaisen tuotteen alla)
| Kenttä | Tietotyyppi | Esimerkki | Käyttötapaus |
|---|---|---|---|
id | Kokonaisluku | 987654321 | Yksilöllinen varianttitunniste |
title | Merkkijono | "32 / Blue" | Variantin näyttönimi |
sku | Merkkijono | "HD-BLU-32" | SKU-tunniste varastonhallintajärjestelmiin |
price | Merkkijono | "185.00" | Hintaseuranta (huomaa: kyseessä on merkkijono, muunna luvuksi laskutoimituksia varten) |
compare_at_price | Merkkijono tai null | "200.00" | Alkuperäinen hinta — tärkeä alennusten seurannassa |
available | Totuusarvo | true | Saatavuus varastossa (ainoa julkinen varastoindikaattori) |
weight | Liukuluku | 1.2 | Kuljetus- ja logistiikka-analyysi |
option1, option2, option3 | Merkkijono | "32", "Blue", null | Yksittäiset optioarvot |
created_at, updated_at | ISO DateTime | — | Varianttikohtainen muutosten seuranta |
Kuvaan liittyvät kentät
| Kenttä | Tietotyyppi | Esimerkki | Käyttötapaus |
|---|---|---|---|
id | Kokonaisluku | 111222333 | Yksilöllinen kuvatunniste |
src | Merkkijono (URL) | "https://cdn.shopify.com/..." | Suora kuvan latauslinkki |
alt | Merkkijono tai null | "Front view of jeans" | Alt-tekstin analyysi saavutettavuuden näkökulmasta |
position | Kokonaisluku | 1 | Kuvien järjestys |
width, height | Kokonaisluku | 2048, 2048 | Kuvan mitat |
Mitä julkisessa päätepisteessä EI ole
Tärkeä sudenkuoppa: inventory_quantity EI ole saatavilla julkisissa /products.json-vastauksissa. Tämä kenttä poistettiin julkisista JSON-päätepisteistä joulukuussa 2017 turvallisuussyistä. Ainoa saatavuusindikaattori on variantin available-kenttä (true tai false). Todelliset varastomäärät saa vain todennetun Admin API:n kautta kaupan omistajan tunnuksilla.
Ennen kuin kirjoitat scraping-koodin, käy tämä taulukko läpi ja päätä, mitkä kentät ovat sinun käyttötapauksessasi olennaisia. Jos seuraat hintoja, tarvitset variants[].price, variants[].compare_at_price ja variants[].available. Jos teet liidien hankintaa, keskity kenttiin vendor, product_type ja tags. Suodata sen mukaan — CSV:stä tulee paljon siistimpi.
products.jsonin yli: kokoelmat, meta ja muut Shopify-päätepisteet
Mikään kilpailijan opas ei juuri mainitse näitä päätepisteitä. Ne ovat olennaisia tosissaan tehtävässä kilpailija-analyysissä.
/collections.json — kaikki kaupan kategoriat
Palauttaa kaikki kokoelmat eli kategoriat kaupassa otsikoineen, handleineen, kuvauksineen ja tuotelukumäärineen. Varmistin tämän zoologistperfumes.comissa, allbirds.comissa ja gymshark.comissa — kaikki palauttivat kelvollisen JSONin.
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}
Haluatko ymmärtää, miten kilpailija rakentaa kataloginsa? Tämä on se päätepiste.
/collections/{handle}/products.json — tuotteet kategorian mukaan
Palauttaa tuotteet suodatettuna tietyn kokoelman perusteella. Sama JSON-rakenne kuin /products.json-päätepisteessä, mutta rajattuna yhteen kategoriaan. Tämä on ratkaisevaa kategoriakohtaisessa scrapingissä — esimerkiksi jos haluat seurata vain kilpailijan “Sale”- tai “New Arrivals” -kokoelmaa.
/meta.json — kaupan metatiedot
Palauttaa kaupan nimen, kuvauksen, valuutan, maan ja — tässä se hyödyllinen osa — published_products_count-arvon. Sen avulla voit laskea etukäteen täsmälleen, montako sivua tarvitset: ceil(published_products_count / 250). Ei enää arvailua ja sivunumeroiden kasvattamista, kunnes saat tyhjän vastauksen.
Mitä päätepistettä kannattaa käyttää?
| Mitä haluat | Päätepiste | Tarvitaanko tunnistautuminen? |
|---|---|---|
| Kaikki tuotteet (julkiset) | /products.json | Ei |
| Tuotteet tietystä kategoriasta | /collections/{handle}/products.json | Ei |
| Kaupan metatiedot + tuotelukumäärä | /meta.json | Ei |
| Kaikki kokoelmat (kategoriat) | /collections.json | Ei |
| Tilaus-/myyntidata (vain oma kauppa) | Admin API /orders.json | Kyllä (API-avain) |
| Varastomäärät (vain oma kauppa) | Admin API /inventory_levels.json | Kyllä |
Toistuva foorumikysymys — “Voinko scrapeata, montako yksikköä kilpailija on myynyt?” — saa lyhyen vastauksen: ei. Ei julkisista päätepisteistä. Myyntidata ja varastomäärät vaativat todennetun Admin API:n, joten tarvitset kaupan omistajan pääsyn. Julkiset päätepisteet tarjoavat vain tuoteluettelon.

Miten Shopify scrapeataan Pythonilla: vaiheittainen käyttöönotto
- Vaikeustaso: Aloittelija
- Aikaa kuluu: noin 15 minuuttia (asennus + ensimmäinen scrape)
- Tarvitset: Python 3.11+,
pip, terminaalin ja Shopify-kaupan URL-osoitteen
Vaihe 1: Asenna Python ja tarvittavat kirjastot
Varmista, että käytössäsi on Python 3.11 tai uudempi (pandas 3.0.x vaatii sen). Asenna sitten kaksi tarvitsemaamme kirjastoa:
1pip install requests pandas
Excel-vientiä varten tarvitset lisäksi:
1pip install openpyxl
Lisää skriptin alkuun nämä importit:
1import requests
2import pandas as pd
3import time
4import random
5import json
Kun ajat skriptin, import-virheitä ei pitäisi tulla. Jos pandas antaa versio-virheen, päivitä Python 3.12:een.
Vaihe 2: Hae tuotetiedot /products.json-päätepisteestä
Tässä on perustoiminto, joka ottaa kaupan URL-osoitteen, kutsuu päätepistettä ja palauttaa puretun JSONin:
1def fetch_products_page(store_url, page=1, limit=250):
2 """Hakee yhden tuotesivun Shopify-kaupasta."""
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", [])
Keskeiset yksityiskohdat:
limit=250on Shopifyn sallima maksimi per sivu. Oletusarvo on 30, joten tämän asettaminen pienentää pyyntöjen kokonaismäärää jopa kahdeksasosaan.User-Agent-otsake: aseta aina uskottava arvo. Pyynnöt ilman User-Agentia laukaisevat todennäköisemmin Shopifyn bottisuojaukset.timeout=30: älä anna yksittäisen pyynnön jäädä roikkumaan loputtomiin.
Testaa tunnetulla kaupalla:
1products = fetch_products_page("https://allbirds.com")
2print(f"Noudettuja tuotteita: {len(products)}")
3print(f"Ensimmäinen tuote: {products[0]['title']}")
Näet jotakin tämän kaltaista: Noudettuja tuotteita: 250 ja ensimmäisen tuotteen nimen.
Vaihe 3: Käsittele sivutus, jotta saat kaikki tuotteet talteen
Yksi pyyntö palauttaa korkeintaan 250 tuotetta. Useimmissa kaupoissa on enemmän (Allbirdsillä yli 1 420). Siksi sinun täytyy kiertää sivuja, kunnes saat tyhjän vastauksen.
1def scrape_all_products(store_url, delay=1.0):
2 """Scrapeaa kaikki tuotteet Shopify-kaupasta sivutuksen avulla."""
3 all_products = []
4 page = 1
5 while True:
6 print(f"Haetaan sivua {page}...")
7 products = fetch_products_page(store_url, page=page, limit=250)
8 if not products:
9 print(f"Ei enempää tuotteita. Yhteensä: {len(all_products)}")
10 break
11 all_products.extend(products)
12 print(f" Saatiin {len(products)} tuotetta (yhteensä nyt: {len(all_products)})")
13 page += 1
14 # Ole kohtelias: odota pyyntöjen välissä
15 time.sleep(delay + random.uniform(0, 0.5))
16 return all_products
Kun products palautuu tyhjänä, olet päässyt loppuun.
time.sleep()-odotus satunnaisella jitterillä pitää sinut Shopifyn epävirallisen rate limitin alapuolella (~2 pyyntöä sekunnissa).
Vinkki: jos haet ensin /meta.json-päätepisteen, tiedät jo tuotteiden kokonaismäärän ja voit laskea tarkasti tarvittavien sivujen määrän: pages = ceil(product_count / 250). Näin vältät yhden ylimääräisen tyhjän pyynnön loppupäässä.
Vaihe 4: Puretaan ja valitaan tarvittavat kentät
Kun sinulla on kaikki tuotteet Python-listana sanakirjoja, poimi vain ne kentät, jotka oikeasti tarvitset. Tässä esimerkissä haetaan yleisimmät kentät hintaseurantaa varten:
1def extract_product_data(products):
2 """Poimii tärkeät kentät tuotteista ja litistää variantit."""
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
Tämä luo yhden rivin per variantti — erittäin hyödyllinen muoto hintavertailuun, koska yksi tuote kuten “Classic Blue Jeans” voi sisältää 12 varianttia (6 kokoa × 2 väriä), joista jokaisella on oma hinta ja saatavuustila.
Vie Shopify-data CSV- ja Excel-muotoon pandasilla
Moni muu Shopify-scraping-opas dumppaa raakaa JSONia tiedostoon ja on tyytyväinen siihen. Kehittäjälle se voi riittää. Mutta verkkokauppa-analyytikolle, joka tarvitsee taulukon perjantaihin mennessä, siitä ei ole iloa.
Ongelma on siinä, että Shopifyn JSON on sisäkkäinen. Yksi tuote voi sisältää tusinan variantteja, joilla jokaisella on oma hinta, SKU ja saatavuus. Tämän litistäminen riveiksi ja sarakkeiksi vaatii hieman pandas-työtä.
Muunna sisäkkäinen JSON siistiksi taulukoksi
Kaksi vaihtoehtoa käyttötapauksesta riippuen:
Vaihtoehto A: yksi rivi per variantti (paras hintaseurantaan ja varaston seurantaan)
1# Käyttäen Step 4:n extract_product_data-funktiota
2products = scrape_all_products("https://allbirds.com")
3rows = extract_product_data(products)
4df = pd.DataFrame(rows)
5print(f"DataFramen koko: {df.shape}")
6print(df.head())
Tämä antaa litteän taulukon, jossa jokainen rivi on ainutlaatuinen tuote-variantti-yhdistelmä. Kauppa, jossa on 500 tuotetta ja keskimäärin 4 varianttia per tuote, tuottaa noin 2 000 rivin DataFramen.
Vaihtoehto B: yksi rivi per tuotekooste (paras katalogin yleiskatsaukseen)
1def summarize_products(products):
2 """Yksi rivi per tuote ja min/max-hinta varianttien mukaan."""
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
Vie CSV-, Excel- ja Google Sheets -muotoon
1# CSV-vienti (käytä utf-8-sig:tä, jotta Excel käsittelee erikoismerkit oikein)
2df.to_csv("shopify_products.csv", index=False, encoding="utf-8-sig")
3# Excel-vienti (vaatii openpyxl-kirjaston)
4df.to_excel("shopify_products.xlsx", index=False, engine="openpyxl")
5print("Viety tiedostoihin shopify_products.csv ja shopify_products.xlsx")
Google Sheetsiin voit käyttää gspread-kirjastoa service accountin kanssa, mutta rehellisesti sanottuna useimmissa tapauksissa CSV:n vienti ja lataus Google Driveen on nopeampaa ja yksinkertaisempaa.
Tuotantokelpoinen Python-scraping: rate limitit, uudelleenyritykset ja estojen kiertäminen
Perusskripti toimii pienten kauppojen kanssa hyvin. Mutta entä kun scrappaat yli 5 000 tuotteiden kauppaa tai useita kauppoja peräkkäin? Silloin ongelmat alkavat.
Ymmärrä Shopifyn rate limitit ja estokäyttäytyminen
Shopifyn julkisilla JSON-päätepisteillä ei ole virallisesti dokumentoituja rate limitejä (toisin kuin Admin API:n leaky bucket -mallissa), mutta käytännön testit osoittavat seuraavaa:
- Turvallinen nopeus: noin 2 pyyntöä sekunnissa per kauppa
- Lievä yläraja: noin 40 pyyntöä minuutissa ennen rajoitusten aktivoitumista
- HTTP 429: "Too Many Requests" — tavallinen rate limit -vastaus
- HTTP 430: Shopify-tyyppinen koodi, joka viittaa turvatason estoon, ei pelkkään rate limit -tilanteeseen
- HTTP 403 tai CAPTCHA-uudelleenohjaus: Joissakin kaupoissa lisäsuojausta Cloudflaren kautta
Pilvi-infrastruktuurista tulevat pyynnöt (AWS Lambda, Google Cloud Run) laukaisevat estoja erityisen herkästi, koska näiden IP-alueiden väärinkäyttöaste on korkea.
Tekniikat luotettavaan Shopify-datan poimintaan
Tässä eteneminen mallista “toimii omalla koneella” malliin “toimii tuotannossa”:
| Taso | Tekniikka | Luotettavuus |
|---|---|---|
| Perus | requests.get() + ?page= | Kaatuu suurissa katalogeissa, voi tulla estoja |
| Keskitaso | requests.Session() + ?limit=250 + time.sleep(1) + uudelleenyritys 429:lle | Toimii useimmissa kaupoissa |
| Edistynyt | Asynkroninen httpx + kiertävä User-Agent + eksponentiaalinen backoff | Tuotantotasoinen, skaalaa yli 10K tuotteeseen |
Keskitaso (suositus useimmille käyttäjille):
1import requests
2from requests.adapters import HTTPAdapter
3from urllib3.util.retry import Retry
4def create_session():
5 """Luo requests-session automaattisella uudelleenyrityksellä."""
6 session = requests.Session()
7 retries = Retry(
8 total=5,
9 backoff_factor=1, # sleep: 0,5 s, 1 s, 2 s, 4 s, 8 s
10 status_forcelist=[429, 430, 500, 502, 503, 504],
11 respect_retry_after_header=True
12 )
13 session.mount("https://", HTTPAdapter(max_retries=retries))
14 session.headers.update({
15 "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36"
16 })
17 return session
Retry-asetukset käsittelevät 429-vastaukset automaattisesti eksponentiaalisella backoffilla. backoff_factor=1 tarkoittaa, että odotusajat ovat 0,5 s → 1 s → 2 s → 4 s → 8 s uudelleenyritysten välillä. Session uudelleenkäyttö (requests.Session()) tuo myös yhteyspoolauksen, mikä vähentää kuormaa, kun samaan domainiin tehdään useita pyyntöjä.
User-Agentin kierrätys: jos scrappaat useita kauppoja, vaihda 3–5 realistisen selaimen User-Agent-merkkijonon välillä. Kyse ei ole huijaamisesta, vaan siitä, ettet näytä botilta, joka lähettää joka kerta samat otsakkeet.
Täydellinen toimiva Python-skripti Shopify-datan poimintaan ja CSV-vientiin
Tässä on koko valmis skripti, jonka voit kopioida sellaisenaan. Se on noin 75 riviä varsinaista koodia (kommenttien lisäksi), ja olen testannut sitä Allbirdsilla (1 420 tuotetta), ColourPopilla (yli 2 000 tuotetta) sekä Zoologist Perfumesilla (pieni katalogi).
1import requests
2import pandas as pd
3import time
4import random
5from requests.adapters import HTTPAdapter
6from urllib3.util.retry import Retry
7def create_session():
8 """Luo session, jossa on uudelleenyritykset rate limitejä varten."""
9 session = requests.Session()
10 retries = Retry(
11 total=5,
12 backoff_factor=1,
13 status_forcelist=[429, 430, 500, 502, 503, 504],
14 respect_retry_after_header=True
15 )
16 session.mount("https://", HTTPAdapter(max_retries=retries))
17 session.headers.update({
18 "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
19 "AppleWebKit/537.36 (KHTML, like Gecko) "
20 "Chrome/125.0.0.0 Safari/537.36"
21 })
22 return session
23def scrape_shopify(store_url, delay=1.0):
24 """Scrapeaa kaikki tuotteet Shopify-kaupasta /products.jsonin kautta."""
25 session = create_session()
26 all_products = []
27 page = 1
28 base_url = f"{store_url.rstrip('/')}/products.json"
29 while True:
30 print(f" Sivu {page}...", end=" ")
31 resp = session.get(base_url, params={"limit": 250, "page": page}, timeout=30)
32 resp.raise_for_status()
33 products = resp.json().get("products", [])
34 if not products:
35 break
36 all_products.extend(products)
37 print(f"{len(products)} tuotetta (yhteensä: {len(all_products)})")
38 page += 1
39 time.sleep(delay + random.uniform(0, 0.5))
40 return all_products
41def flatten_to_variants(products):
42 """Litistää sisäkkäisen tuotteen JSONin yhdeksi riviksi per variantti."""
43 rows = []
44 for p in products:
45 base = {
46 "product_id": p["id"],
47 "title": p["title"],
48 "handle": p["handle"],
49 "vendor": p.get("vendor", ""),
50 "product_type": p.get("product_type", ""),
51 "tags": ", ".join(p.get("tags", [])),
52 "created_at": p.get("created_at", ""),
53 "updated_at": p.get("updated_at", ""),
54 "image_url": p["images"][0]["src"] if p.get("images") else "",
55 }
56 for v in p.get("variants", []):
57 row = {**base}
58 row["variant_id"] = v["id"]
59 row["variant_title"] = v.get("title", "")
60 row["sku"] = v.get("sku", "")
61 row["price"] = v.get("price", "")
62 row["compare_at_price"] = v.get("compare_at_price", "")
63 row["available"] = v.get("available", "")
64 rows.append(row)
65 return rows
66if __name__ == "__main__":
67 STORE_URL = "https://allbirds.com" # Vaihda tähän kohdekauppasi
68 OUTPUT_CSV = "shopify_products.csv"
69 OUTPUT_EXCEL = "shopify_products.xlsx"
70 print(f"Scrapataan {STORE_URL}...")
71 products = scrape_shopify(STORE_URL)
72 print(f"\nScrapattuja tuotteita yhteensä: {len(products)}")
73 print("Muunnetaan varianttitason riveiksi...")
74 rows = flatten_to_variants(products)
75 df = pd.DataFrame(rows)
76 print(f"DataFrame: {df.shape[0]} riviä x {df.shape[1]} saraketta")
77 df.to_csv(OUTPUT_CSV, index=False, encoding="utf-8-sig")
78 df.to_excel(OUTPUT_EXCEL, index=False, engine="openpyxl")
79 print(f"\nViety tiedostoihin {OUTPUT_CSV} ja {OUTPUT_EXCEL}")
Aja se komennolla python scrape_shopify.py. Allbirdsilla tämä kestää noin 45 sekuntia ja tuottaa CSV:n, jossa on noin 5 000+ riviä (yksi per variantti). Pääte näyttää suunnilleen tältä:
1Scrapataan https://allbirds.com...
2 Sivu 1... 250 tuotetta (yhteensä: 250)
3 Sivu 2... 250 tuotetta (yhteensä: 500)
4 ...
5 Sivu 6... 170 tuotetta (yhteensä: 1420)
6Scrapattuja tuotteita yhteensä: 1420
7Muunnetaan varianttitason riveiksi...
8DataFrame: 5680 riviä x 14 saraketta
9Viety tiedostoihin shopify_products.csv ja shopify_products.xlsx
Ohita Python: scrapea Shopify kahdella klikkauksella Thunderbitillä (ei-koodillinen vaihtoehto)
Kaikki eivät halua asentaa Pythonia, korjailla import-virheitä tai ylläpitää scraping-skriptiä. Myyjälle, joka tarvitsee kilpailijahinnat huomisaamuun mennessä, Python on usein liioittelua.
Siksi rakennimme -ratkaisun — AI-verkkoscraperin Chrome-laajennuksena. Ei koodia, ei API-avaimia, ei ympäristön käyttöönottoa.
Miten Thunderbit scrapeaa Shopify-kauppoja
Thunderbitissä on erillinen Shopify Scraper -malli, joka on valmiiksi konfiguroitu Shopify-tuotesivuille. Asennat -laajennuksen, avaat Shopify-kaupan ja klikkaat “Scrape”. Malli poimii automaattisesti tuotteen nimet, kuvaukset, hinnat, varianttitiedot, kuvat ja toimittajatiedot.
Kaupoissa, joissa malli ei osu täysin kohdalleen (räätälöidyt teemat, poikkeava asettelu), Thunderbitin AI Suggest Fields -ominaisuus lukee sivun ja luo sarake-ehdotukset automaattisesti. Voit muokata niitä: nimetä sarakkeita uudelleen, lisätä kenttiä tai kirjoittaa ohjeita kuten “poimi vain tuotteet, joilla on compare_at_price asetettu”.
Muutama ominaisuus, joka vastaa suoraan Python-skriptin toimintoja:
- Alisivujen scrapeaus: käy automaattisesti jokaisella tuotteen yksityiskohtasivulla ja rikastaa taulukkoa täydellisillä kuvauksilla, arvosteluilla tai varianttitiedoilla — sama asia, jonka Python-skripti tekee selaamalla sivuja, mutta ilman koodia.
- Automaattinen sivutus: hoitaa klikkaamalla etenevän sivutuksen ja loputtoman scrollauksen ilman asetuksia.
- Ajastettu scrapeaus: aseta toistuvat ajot (esim. “joka maanantai klo 9”) jatkuvaa hintaseurantaa varten — ilman cron-työtä tai palvelinta.
- Ilmainen vienti CSV-, Excel-, Google Sheets-, Airtable- tai Notion-muotoon kaikilla suunnitelmilla.
Python-skripti vs. Thunderbit: rehellinen vertailu
| Tekijä | Python-skripti | Thunderbit (ei-koodia) |
|---|---|---|
| Käyttöönottoaika | 15–60 min (ympäristö + koodi) | noin 2 min (Chrome-laajennuksen asennus) |
| Koodaustarve | Kyllä (Python) | Ei lainkaan |
| Muokattavuus | Rajaton | AI-ehdotetut kentät + omat promptit |
| Sivutuksen käsittely | Koodattava itse | Automaattinen |
| Vientimuodot | Koodattava itse (CSV/Excel) | CSV, Excel, Google Sheets, Airtable, Notion (ilmainen) |
| Ajastetut ajot | Cron-työ + hosting | Sisäänrakennettu ajastin |
| Rate limit -käsittely | Uudelleenyritykset/backoff koodattava itse | Hoidetaan automaattisesti |
| Paras käyttötapa | Kehittäjät, suuret dataputket | Liiketoimintakäyttäjät, nopeat poiminnat, toistuva seuranta |
Käytä Pythonia, kun tarvitset täyden hallinnan tai integrointia laajempaan dataputkeen. Käytä Thunderbitia, kun tarvitset dataa nopeasti etkä halua ylläpitää koodia. Syvempään katsaukseen , olemme kirjoittaneet erillisen oppaan aiheesta.

Vinkkejä ja parhaat käytännöt Shopify-kauppojen scrapeamiseen
Nämä pätevät riippumatta työkalusta:
- Käytä aina
?limit=250pyyntöjen minimoimiseksi. Oletusarvo 30 tuotetta per sivu tarkoittaa 8 kertaa enemmän pyyntöjä samaan dataan. - Kunnioita kauppaa: lisää 1–2 sekunnin viiveet pyyntöjen väliin. Palvelimen kuormittaminen nopeilla pyyntösarjoilla on huonoa käytäntöä ja lisää estoja.
- Tarkista
robots.txtensin: Shopifyn oletus-robots.txtEI estä/products.json-päätepistettä. Osa kaupoista kuitenkin lisää omia sääntöjään, joten varmista asia ennen laajamittaista scrapea. - Tallenna raakadata ensin paikallisesti ja käsittele vasta sitten. Jos parsintalogiikka muuttuu myöhemmin, sinun ei tarvitse scrapeata uudelleen. Yksinkertainen
json.dump(all_products, open("raw_data.json", "w"))ennen litistämistä säästää paljon vaivaa. - Poista duplikaatit
product.id:n perusteella: sivutuksen reunatapaukset voivat joskus palauttaa samoja tuotteita sivurajoilla. Nopeadf.drop_duplicates(subset=["product_id", "variant_id"])korjaa tämän. - Muunna
pricefloat-tyypiksi ennen laskemista. Shopify palauttaa hinnat merkkijonoina ("185.00"), ei numeroina. - Seuraa päätepisteen muutoksia: vaikka
/products.jsonon ollut vakaa vuosia, Shopify voisi teoriassa rajoittaa sitä. Jos scraperi saa yhtäkkiä 404-virheitä, tarkista ensin kauppa käsin.
Lisää tietoa kestävien scraperien rakentamisesta löydät oppaastamme .
Lainsäädännölliset ja eettiset näkökohdat Shopify-datan poiminnassa
Lyhyt osio, mutta tärkeä.
/products.json-päätepiste tarjoaa julkisesti saatavilla olevaa tuotetietoa — samaa tietoa, jonka kuka tahansa näkee kauppaa selatessaan. Shopifyn käyttöehdoissa puhutaan “automaattisista menetelmistä” palvelujen käyttöön, mutta tämä viittaa alustaan itseensä (hallintapaneeliin, kassaan), ei julkiseen verkkokauppadataan. Shopify-kohtaisia scraping-kanteita ei ole jätetty vireille huhtikuuhun 2026 mennessä.
Keskeiset oikeustapaukset tukevat julkisen datan scrapeamista: hiQ v. LinkedIn vahvisti, että julkisesti saatavilla olevan datan scrapeaminen ei riko CFAA:ta, ja Meta v. Bright Data (2024) linjasi, että käyttöehtorajoitukset koskevat vain tilanteita, joissa käyttäjä on kirjautuneena.
Parhaat käytännöt:
- scrapea vain julkisesti saatavilla olevaa tuotetietoa
- älä scrapea henkilö- tai asiakastietoja
- kunnioita
robots.txt:ää ja rate limitejä - noudata GDPR:ää/CCPA:ta, jos käsittelet henkilötietoja (tuotekatalogidata ei ole henkilötietoa)
- identifioi itsesi selkeällä User-Agent-merkkijonolla
- oman Shopify-kaupan scrapeaminen Admin API:n kautta on aina sallittua
Syvempään katsaukseen katso kirjoituksemme .
Yhteenveto ja tärkeimmät opit
Shopifyn julkinen /products.json-päätepiste tekee verkkokauppadatan poiminnasta poikkeuksellisen helppoa. Työnkulku on: lisää /products.json → hae Pythonilla → sivuta ?limit=250&page=-parametreilla → litistä pandasilla → vie CSV- tai Excel-muotoon.
Mitä tämä opas kattaa, mutta monet muut eivät:
- Täydellinen kenttäviite: tiedät tarkalleen, mitä dataa on saatavilla (yli 40 kenttää tuotteissa, varianteissa ja kuvissa) ennen kuin kirjoitat ensimmäistäkään riviä koodia
- Lisäpäätepisteet:
/collections.jsonja/meta.jsonantavat kategoriatason tiedot ja kaupan metatiedot, joita kilpailijaoppaat eivät yleensä käsittele - Tuotantokelpoiset tekniikat: session uudelleenkäyttö, eksponentiaalinen backoff, User-Agent-otsakkeet ja
?limit=250todellisia rate limitejä varten - Oikea CSV-/Excel-vienti: pandasilla litistetty varianttitason data, ei pelkkää raakaa JSON-dumppia
- Ei-koodillinen vaihtoehto: käyttäjille, jotka arvostavat nopeutta enemmän kuin koodin joustavuutta
Yksittäisiin tai toistuviin Shopify-datan noutoihin ilman koodia kokeile — Shopify Scraper -malli hoitaa kaiken sivutuksesta vientiin. Räätälöityihin dataputkiin tai useiden kauppojen laajamittaiseen scrapeamiseen tämän oppaan Python-skripti antaa täyden hallinnan.
Katso vaiheittaisia video-opastuksia varten tai tutustu oppaisiimme ja saadaksesi lisää vastaavia tekniikoita.
Usein kysytyt kysymykset
Voiko minkä tahansa Shopify-kaupan scrapeata products.json-päätepisteellä?
Useimmat Shopify-kaupat paljastavat tämän päätepisteen oletuksena — testeissäni noin 71 % palautti kelvollisen JSONin. Jotkin kaupat, joissa on räätälöityjä asetuksia tai lisäsuojauksia (Cloudflare, headless-ratkaisut), voivat palauttaa 404:n tai estää pyynnön. Nopea tarkistus: avaa {store-url}/products.json selaimessa. Jos näet JSONin, olet kunnossa.
Onko Shopify-kauppojen scrapeaminen laillista?
Julkinen tuotetieto (hinnat, nimet, kuvat, kuvaukset) on yleensä saatavilla, ja oikeustapaukset kuten hiQ v. LinkedIn tukevat julkisesti saatavilla olevan tiedon scrapeamista. Tarkista kuitenkin aina kyseisen kaupan käyttöehdot ja oman maasi lait. Älä scrapea henkilö- tai asiakastietoja, ja noudata rate limitejä.
Kuinka monta tuotetta Shopify-kaupasta voi scrapeata?
Kokonaismäärälle ei ole kovaa ylärajaa. Sivutus ?limit=250&page=-parametreilla antaa sinun hakea koko katalogin. Erittäin suurissa kaupoissa (25 000+ tuotetta) käytä session uudelleenkäyttöä ja viiveitä rate limit -ongelmien välttämiseksi. /meta.json-päätepiste kertoo tarkan tuotemäärän etukäteen, joten tiedät, montako sivua odottaa.
Mikä on ero products.json-päätepisteen ja Shopify Admin API:n välillä?
/products.json on julkinen päätepiste — ei tunnistautumista, vain luettavaa tuotetietoa, kaikkien saatavilla. Admin API vaatii kaupan omistajan tunnisteet ja tarjoaa tilaukset, varastomäärät, asiakastiedot sekä kirjoitusoikeudet. Jos tarvitset myyntidata tai todelliset varastomäärät, tarvitset Admin API -pääsyn (eli sinun täytyy olla kaupan omistaja tai saada lupa omistajalta).
Voinko scrapeata Shopifya ilman Pythonia?
Ehdottomasti. Työkalut kuten mahdollistavat Shopify-kauppojen scrapeamisen Chrome-laajennuksella ilman koodausta. Se hoitaa sivutuksen automaattisesti ja vie datan suoraan CSV-, Excel-, Google Sheets-, Airtable- tai Notion-muotoon. Kehittäjille, jotka suosivat muita kieliä, sama /products.json-päätepiste toimii myös JavaScriptillä, Rubylla, Go:lla — millä tahansa kielellä, joka osaa tehdä HTTP-pyyntöjä ja parsia JSONia.
Lisää luettavaa