Pourquoi Scrape Shopify Stores?
Shopify pouvoirs plus de 4 millions de magasins en ligne dans le monde, des petites marques indépendantes aux grands détaillants. Cela en fait l'une des sources les plus riches de renseignements sur le commerce électronique. En grattant les magasins Shopify, vous pouvez suivre les prix des concurrents, surveiller les lancements de produits, analyser les tendances du marché et créer des bases de données complètes sur les produits.
La bonne nouvelle est que Shopify a une structure prévisible qui rend la démolition plus systématique que la plupart des plateformes de commerce électronique. Chaque magasin Shopify expose certaines données au moyen de paramètres normalisés, ce qui signifie qu'une seule architecture de racleur peut fonctionner dans des milliers de magasins différents. Pour un aperçu plus large des stratégies de démolition du commerce électronique, voir notre Guide de suppression des données sur le commerce électronique.
Comprendre la structure du magasin Shopify
Chaque magasin Shopify suit les mêmes modèles d'URL et de données, quel que soit le thème ou la personnalisation.
Points d'arrêt du JSON public
Shopify expose les données du produit à travers les paramètres JSON qui ne nécessitent pas d'authentification. Ce sont la façon la plus efficace de gratter les magasins Shopify parce que vous obtenez des données structurées sans analyse HTML.
| Point d'arrivée | Données renvoyées | Pagination |
|---|---|---|
/products.json | Tous les produits avec variantes, prix, images | ?page=N&limit=250 |
/products/{handle}.json | Détail du produit unique | Sans objet |
/collections.json | Toutes les collections | ?page=N |
/collections/{handle}/products.json | Produits dans une collection | ?page=N&limit=250 |
/meta.json | Stockage des métadonnées (nom, description) | Sans objet |
Structure des données sur les produits
Chaque objet produit de l'API JSON comprend:
- Informations de base: titre, poignée (slug), body html (description), fournisseur, type de produit, tags
- Variantes: Chaque variante a son propre prix, compare at price, SKU, état des stocks et valeurs d'option (taille, couleur, etc.)
- Images : URLs pour toutes les images de produits avec texte alt
- Dates: created at, updated at, publied at
Limite des taux
Shopify applique des limites de taux pour protéger les performances des magasins. Les paramètres JSON publics permettent généralement 2-4 requêtes par seconde par IP avant de griffer. C'est là que Proxies résidentielles devenir essentiel — répartir les requêtes sur plusieurs IP vous permet de maintenir le débit sans frapper les limites de taux sur une seule IP.
Configuration mandataire pour Shopify
Shopify limite le taux en se basant sur l'IP, ce qui fait de la rotation par procuration la principale stratégie de graissage à l'échelle.
Configuration 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:8080Pour Shopify gratter, utiliser la rotation par demande lors de la démolition de différents magasins, et des sessions collantes lors de la pagination à travers le catalogue de produits d'un seul magasin. Ce modèle imite le comportement de navigation naturel.
Mise en œuvre de Python
Voici un racleur Shopify prêt à la production Python SDK de ProxyHat.
Scrapeur d'API JSON
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))Surveillance des variations de prix dans les magasins
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 changesMise en œuvre de Node.js
Une version Node.js utilisant Le nœud SDK de 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");
});Stratégies de scrapage spécifiques
Découvrez les magasins Shopify
Avant de gratter, vous devez identifier quels sites concurrents fonctionnent sur Shopify. Les indicateurs communs sont les suivants:
- Les
/products.jsonle paramètre retourne JSON valide - Source HTML contient
Shopify.themeoucdn.shopify.com - Les
x-shopify-stageen-tête est présent dans les réponses
Gestion des magasins Passworded
Certains magasins Shopify nécessitent un mot de passe pour y accéder. Ce sont généralement des magasins de pré-lancement ou de gros. Les paramètres JSON retourneront une redirection vers la page de mot de passe. Passez ces magasins dans votre pipeline à moins d'avoir un accès autorisé.
Traitement des domaines personnalisés
Shopify magasins utilisent souvent des domaines personnalisés au lieu de .myshopify.com. L'API JSON fonctionne de la même manière sur des domaines personnalisés. Utilisez simplement le domaine public du magasin dans vos demandes.
Suivi des inventaires
Les variantes de produits comprennent available champ indiquant l'état du stock. En suivant ce champ au fil du temps, vous pouvez surveiller les niveaux d'inventaire des concurrents et identifier quand les produits sortent des stocks — renseignements utiles pour les décisions de tarification et de restockage.
Éviter les blocs et les limites de taux
Alors que Shopify est plus facile à gratter qu'Amazon, il applique toujours les protections.
| Protection | Détails | Atténuation |
|---|---|---|
| Limite du taux de PI | ~2-4 req/sec par IP pour les paramètres JSON | Rotation des procurations résidentielles à travers les demandes |
| Protection contre les nuages | Certains magasins utilisent Cloudflare | IP résidentielles avec en-têtes de type navigateur |
| Détection du bot | Patterns comportementaux suivis | Randomiser les retards et les agents utilisateurs |
| Pages de mot de passe | Magasins de pré-lancement et de gros verrouillés | Sauter ou utiliser l'accès autorisé |
Pour en savoir plus sur la manipulation des systèmes anti-bots, lisez notre guide sur comment gratter des sites Web sans se faire bloquer.
Key takeaway: L'API JSON de Shopify est l'approche de grattage la plus efficace — elle vous donne des données structurées sans analyse HTML. Utilisez-le avant de revenir à la grattage HTML.
Cas d'utilisation des données
Une fois que vous avez recueilli les données Shopify produit, voici les applications les plus précieuses:
- Prix concurrentiels: Suivez les prix des concurrents selon les catégories de produits et ajustez votre stratégie de tarification en temps réel.
- Recherche sur les produits : Identifier les produits de tendance, les nouveaux lancements et les lacunes du marché en surveillant plusieurs magasins.
- Analyse du marché: Données agrégées sur des centaines de magasins Shopify pour comprendre les tendances du marché, la distribution des prix et la croissance des catégories.
- enrichissement du catalogue: Utilisez des descriptions de produits concurrents, des images et des spécifications pour améliorer vos propres listes.
- Surveillance de la marque: Suivez les vendeurs non autorisés de vos produits et surveillez la conformité MAP dans les magasins Shopify.
A emporter des clés
- Boutiques
/products.jsonendpoint est la méthode de grattage la plus efficace — utilisez-la avant l'analyse HTML. - Une architecture de racleur unique fonctionne dans tous les magasins Shopify en raison de la structure normalisée.
- Les proxys résidentiels avec rotation ont surmonté la limite de taux IP de Shopify.
- Utilisez des sessions collantes lors de la pagination à travers le catalogue d'un seul magasin.
- Suivre les prix et la disponibilité des variantes pour une intelligence concurrentielle complète.
- Commencez par Proxies résidentielles de ProxyHat à l'échelle de votre Shopify grattage fiable.
Prêt à commencer à gratter Shopify magasins? Explorez notre Guide de suppression des données sur le commerce électronique pour la stratégie complète, et vérifier notre Guide de proxy Python et Guide de proxy Node.js pour les détails de mise en œuvre. Visitez notre page de prix pour commencer.






