Perché Scrape Shopify Stores?
Acquisti poteri oltre 4 milioni di negozi online in tutto il mondo, da piccoli marchi indipendenti ai principali rivenditori. Questo lo rende una delle fonti più ricche di intelligenza e-commerce. Raschiando negozi Shopify, è possibile monitorare i prezzi dei concorrenti, monitorare i lanci dei prodotti, analizzare le tendenze del mercato e costruire database di prodotti completi.
La buona notizia è che Shopify ha una struttura prevedibile che rende la demolizione più sistematica della maggior parte delle piattaforme di e-commerce. Ogni negozio Shopify espone alcuni dati attraverso endpoint standardizzati, il che significa che un'architettura single scraper può funzionare in migliaia di negozi diversi. Per una visione più ampia delle strategie di raschiamento e-commerce, vedere il nostro e-commerce dati scraping guida.
Comprendere la struttura del negozio
Ogni negozio Shopify segue lo stesso URL e i modelli di dati, indipendentemente dal tema o dalla personalizzazione.
Pubblica JSON Endpoints
Shopify espone i dati dei prodotti tramite endpoint JSON che non richiedono l'autenticazione. Questi sono il modo più efficiente per raschiare Shopify negozi perché si ottengono dati strutturati senza parasing HTML.
| Fine | Dati resi | Pagina |
|---|---|---|
/products.json | Tutti i prodotti con varianti, prezzi, immagini | ?page=N&limit=250 |
/products/{handle}.json | Dettagli prodotto singolo | N/A |
/collections.json | Tutte le collezioni | ?page=N |
/collections/{handle}/products.json | Prodotti in una collezione | ?page=N&limit=250 |
/meta.json | Memorizzare metadati (nome, descrizione) | N/A |
Struttura dei dati del prodotto
Ogni oggetto prodotto dell'API JSON include:
- Informazioni di base: titolo, maniglia (slug), body html (descrizione), venditore, product type, tag
- Varianti: Ogni variante ha il suo prezzo, confronti at prezzo, SKU, stato dell'inventario e valori di opzione (dimensione, colore, ecc.)
- Immagini: URL per tutte le immagini del prodotto con testo alt
- Date: creato at, aggiornato at, pubblicato at
Limitamento del tasso
Shopify applica limiti di velocità per proteggere le prestazioni del negozio. Gli endpoint di JSON pubblici tipicamente consentono 2-4 richieste al secondo per IP prima di effettuare il timone. Questo è dove Prossi residenziali diventare essenziale — la diffusione di richieste attraverso più IP consente di mantenere il throughput senza colpire limiti di velocità su qualsiasi singolo IP.
Configurazione proxy per Shopify
La limitazione della velocità di Shopify è basata su IP, rendendo la rotazione del proxy la strategia primaria per la raschiatura a scala.
Impostazione ProxyHat
# Rotating residential proxy (new IP per request)
http://USERNAME:PASSWORD@gate.proxyhat.com:8080
# Geo-targeted for region-specific stores
http://USERNAME-country-US:PASSWORD@gate.proxyhat.com:8080
# Sticky session for paginated scraping of one store
http://USERNAME-session-shopify001:PASSWORD@gate.proxyhat.com:8080Per Shopify scraping, utilizzare la rotazione per-richiesta quando si raschiano diversi negozi, e sessioni appiccicose durante l'impaginazione attraverso un catalogo di prodotti di un singolo negozio. Questo modello imita il comportamento di navigazione naturale.
Attuazione di Python
Ecco un raschietto Shopify prodotto ProxyHat Python SDK.
JSON API Scraper
import requests
import json
import time
import random
from dataclasses import dataclass, field
from typing import Optional
PROXY_URL = "http://USERNAME:PASSWORD@gate.proxyhat.com:8080"
USER_AGENTS = [
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/124.0.0.0 Safari/537.36",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 Chrome/124.0.0.0 Safari/537.36",
]
@dataclass
class ShopifyProduct:
id: int
title: str
handle: str
vendor: str
product_type: str
tags: list[str]
variants: list[dict]
images: list[str]
min_price: float
max_price: float
created_at: str
updated_at: str
def get_session(store_domain: str) -> requests.Session:
"""Create a session with proxy and headers configured."""
session = requests.Session()
session.proxies = {"http": PROXY_URL, "https": PROXY_URL}
session.headers.update({
"User-Agent": random.choice(USER_AGENTS),
"Accept": "application/json",
"Accept-Language": "en-US,en;q=0.9",
})
return session
def scrape_all_products(store_domain: str) -> list[ShopifyProduct]:
"""Scrape all products from a Shopify store via JSON API."""
products = []
page = 1
session = get_session(store_domain)
while True:
url = f"https://{store_domain}/products.json?page={page}&limit=250"
try:
response = session.get(url, timeout=30)
response.raise_for_status()
except requests.RequestException as e:
print(f"Error on page {page}: {e}")
break
data = response.json()
page_products = data.get("products", [])
if not page_products:
break
for p in page_products:
prices = [float(v["price"]) for v in p.get("variants", [])
if v.get("price")]
product = ShopifyProduct(
id=p["id"],
title=p["title"],
handle=p["handle"],
vendor=p.get("vendor", ""),
product_type=p.get("product_type", ""),
tags=p.get("tags", "").split(", ") if p.get("tags") else [],
variants=[{
"id": v["id"],
"title": v["title"],
"price": v["price"],
"compare_at_price": v.get("compare_at_price"),
"sku": v.get("sku"),
"available": v.get("available", False),
} for v in p.get("variants", [])],
images=[img["src"] for img in p.get("images", [])],
min_price=min(prices) if prices else 0,
max_price=max(prices) if prices else 0,
created_at=p.get("created_at", ""),
updated_at=p.get("updated_at", ""),
)
products.append(product)
print(f"Page {page}: {len(page_products)} products (total: {len(products)})")
page += 1
time.sleep(random.uniform(1, 3))
return products
def scrape_collections(store_domain: str) -> list[dict]:
"""Scrape all collections from a Shopify store."""
collections = []
page = 1
session = get_session(store_domain)
while True:
url = f"https://{store_domain}/collections.json?page={page}"
try:
response = session.get(url, timeout=30)
response.raise_for_status()
except requests.RequestException:
break
data = response.json()
page_collections = data.get("collections", [])
if not page_collections:
break
collections.extend(page_collections)
page += 1
time.sleep(random.uniform(1, 2))
return collections
# Example: Scrape multiple Shopify stores
if __name__ == "__main__":
stores = [
"example-store-1.myshopify.com",
"example-store-2.com",
"example-store-3.com",
]
for store in stores:
print(f"\nScraping: {store}")
products = scrape_all_products(store)
print(f"Found {len(products)} products")
# Save to JSON
with open(f"{store.replace('.', '_')}_products.json", "w") as f:
json.dump([vars(p) for p in products], f, indent=2)
time.sleep(random.uniform(3, 7))Cambiamenti di prezzo di monitoraggio
def compare_prices(store_domain: str, previous_data: dict) -> list[dict]:
"""Compare current prices with previously stored data."""
changes = []
products = scrape_all_products(store_domain)
for product in products:
prev = previous_data.get(product.handle)
if not prev:
changes.append({
"type": "new_product",
"handle": product.handle,
"title": product.title,
"price": product.min_price,
})
continue
if product.min_price != prev.get("min_price"):
changes.append({
"type": "price_change",
"handle": product.handle,
"title": product.title,
"old_price": prev["min_price"],
"new_price": product.min_price,
"change_pct": ((product.min_price - prev["min_price"])
/ prev["min_price"] * 100)
if prev["min_price"] else 0,
})
return changesNode.js Attuazione
Una versione Node.js utilizzando SDK del nodo di ProxyHat.
const axios = require("axios");
const { HttpsProxyAgent } = require("https-proxy-agent");
const fs = require("fs");
const PROXY_URL = "http://USERNAME:PASSWORD@gate.proxyhat.com:8080";
const agent = new HttpsProxyAgent(PROXY_URL);
async function scrapeShopifyProducts(storeDomain) {
const products = [];
let page = 1;
while (true) {
const url = `https://${storeDomain}/products.json?page=${page}&limit=250`;
try {
const { data } = await axios.get(url, {
httpsAgent: agent,
headers: {
"User-Agent":
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/124.0.0.0 Safari/537.36",
Accept: "application/json",
},
timeout: 30000,
});
const pageProducts = data.products || [];
if (pageProducts.length === 0) break;
for (const p of pageProducts) {
const prices = p.variants.map((v) => parseFloat(v.price)).filter(Boolean);
products.push({
id: p.id,
title: p.title,
handle: p.handle,
vendor: p.vendor,
productType: p.product_type,
tags: p.tags ? p.tags.split(", ") : [],
minPrice: Math.min(...prices),
maxPrice: Math.max(...prices),
variants: p.variants.map((v) => ({
id: v.id,
title: v.title,
price: v.price,
compareAtPrice: v.compare_at_price,
sku: v.sku,
available: v.available,
})),
images: p.images.map((img) => img.src),
updatedAt: p.updated_at,
});
}
console.log(`Page ${page}: ${pageProducts.length} products (total: ${products.length})`);
page++;
// Random delay 1-3 seconds
await new Promise((r) => setTimeout(r, 1000 + Math.random() * 2000));
} catch (err) {
console.error(`Error on page ${page}: ${err.message}`);
break;
}
}
return products;
}
async function scrapeMultipleStores(stores) {
const results = {};
for (const store of stores) {
console.log(`\nScraping: ${store}`);
const products = await scrapeShopifyProducts(store);
results[store] = products;
console.log(`Found ${products.length} products`);
// Delay between stores
await new Promise((r) => setTimeout(r, 3000 + Math.random() * 4000));
}
return results;
}
// Usage
scrapeMultipleStores([
"example-store-1.myshopify.com",
"example-store-2.com",
]).then((results) => {
fs.writeFileSync("shopify_data.json", JSON.stringify(results, null, 2));
console.log("Data saved to shopify_data.json");
});Shopify-Specific Scraping Strategies
Scoprire Shopify Stores
Prima di raschiare, è necessario identificare quali siti concorrenti eseguire su Shopify. Gli indicatori comuni includono:
- The
/products.jsonendpoint restituisce valido JSON - sorgente HTML contiene
Shopify.themeocdn.shopify.com - The
x-shopify-stageintestazione è presente in risposte
Gestione di negozi con password
Alcuni negozi Shopify richiedono una password per accedere. Questi sono in genere pre-lancio o negozi all'ingrosso. Gli endpoint JSON restituiranno un reindirizzamento alla pagina della password. Salta questi negozi nel tuo canale di raschiamento a meno che non hai accesso autorizzato.
Trattare con domini personalizzati
Negozi spesso utilizzano domini personalizzati invece di .myshopify.com. L'API JSON funziona allo stesso modo su domini personalizzati. Basta usare il dominio pubblico del negozio nelle vostre richieste.
Monitoraggio dell'inventario
Le varianti del prodotto includono un available campo che indica lo stato delle azioni. Tracciando questo campo nel corso del tempo, è possibile monitorare i livelli di inventario dei concorrenti e identificare quando i prodotti escono dal magazzino — intelligenza utile per i prezzi e le decisioni di ripristino.
Evitare blocchi e limiti di velocità
Mentre Shopify è più raschietto-friendly di Amazon, ancora applica protezioni.
| Protezione | Dettagli | Mitigazione |
|---|---|---|
| Limitamento della tariffa IP | ~2-4 req/sec per IP per gli endpoint JSON | Ruotare i proxy residenziali attraverso le richieste |
| Protezione del cloudflare | Alcuni negozi utilizzano Cloudflare | IP residenziali con intestazioni simili a browser |
| Rilevazione del punto | Modelli comportamentali monitorati | Randomitare ritardi e Utente-Agents |
| Pagine di password | Pre-lancio/mercati all'ingrosso chiusi | Salta o utilizza l'accesso autorizzato |
Per ulteriori informazioni sulla gestione di sistemi anti-bot, leggere la nostra guida su come raschiare i siti web senza bloccarsi.
Portachiavi: Shopify's JSON API è l'approccio più efficiente di raschiatura — ti dà dati strutturati senza parsing HTML. Usalo prima di tornare a ritagliare HTML.
Casi di utilizzo dei dati
Una volta raccolti i dati del prodotto Shopify, ecco le applicazioni più preziose:
- Prezzi competitivi: Traccia i prezzi dei concorrenti attraverso le categorie di prodotti e regola la tua strategia di prezzi in tempo reale.
- Ricerca prodotto: Identificare prodotti di tendenza, nuovi lanci e lacune di mercato monitorando più negozi.
- Analisi di mercato: Aggregare i dati in centinaia di negozi Shopify per comprendere le tendenze del mercato, la distribuzione dei prezzi e la crescita della categoria.
- Arricchimento catalogo: Utilizza le descrizioni dei prodotti concorrenti, immagini e specifiche per migliorare le tue inserzioni.
- Monitoraggio del marchio: Traccia venditori non autorizzati dei tuoi prodotti e monitora la conformità MAP su Shopify storefronts.
Asporto chiave
- Shopify
/products.jsonendpoint è il metodo di demolizione più efficiente — usarlo prima di parsing HTML. - Un'unica architettura raschietto funziona in tutti i negozi Shopify grazie alla struttura standardizzata.
- I proxy residenziali con rotazione superano il limite di velocità IP di Shopify.
- Utilizzare sessioni appiccicose quando impaginare attraverso il catalogo di un singolo negozio.
- Traccia i prezzi a livello variante e la disponibilità per l'intelligenza competitiva completa.
- Inizia con I proxy residenziali di ProxyHat per scalare il tuo Shopify raschiando in modo affidabile.
Pronto per iniziare a raschiare negozi Shopify? Scopri la nostra e-commerce dati scraping guida per la strategia completa, e controllare la nostra Guida proxy Python e Guida proxy Node.js per dettagli di implementazione. Visita la nostra pagina dei prezzi per iniziare.






