Shopify-Shops mit Proxies scrapen: Komplettanleitung

Erfahren Sie, wie Sie Shopify Speicherdaten mit JSON API Endpoints und Wohn-Proxies abkratzen. Vollständiger Python- und Node.js-Code für die Extraktion von Produkten, Preisen und Inventardaten.

Shopify-Shops mit Proxies scrapen: Komplettanleitung

Warum Scrape Shopify Stores?

Shopify Mächte über 4 Millionen Online-Shops weltweit, von kleinen unabhängigen Marken bis zu großen Einzelhändlern. Dies macht es zu einer der reichsten Quellen der E-Commerce-Intelligenz. Durch das Abkratzen von Shopify-Shops können Sie die Wettbewerberpreise verfolgen, Produkteinführungen überwachen, Markttrends analysieren und umfassende Produktdatenbanken aufbauen.

Die gute Nachricht ist, dass Shopify eine vorhersehbare Struktur hat, die das Abkratzen systematischer macht als die meisten E-Commerce-Plattformen. Jeder Shopify-Store legt bestimmte Daten durch standardisierte Endpunkte frei, was bedeutet, dass eine einzige Scraper-Architektur über Tausende von verschiedenen Geschäften arbeiten kann. Für einen breiteren Überblick über e-Commerce-Schrottstrategien siehe unsere e-Commerce Daten-Schrottführer.

Shopify's Store Structure verstehen

Jeder Shopify-Store folgt den gleichen URL- und Datenmustern, unabhängig vom Thema oder der Anpassung.

Öffentliche JSON Endpunkte

Shopify legt Produktdaten über JSON-Endpunkte frei, die keine Authentifizierung erfordern. Dies sind die effizienteste Möglichkeit, Shopify-Shops zu kratzen, weil Sie strukturierte Daten ohne HTML-Pasing erhalten.

Öffentliche JSON Endpunkte
EndpunktDaten zurückgegebenPagination
/products.jsonAlle Produkte mit Varianten, Preise, Bilder?page=N&limit=250
/products/{handle}.jsonEinzelprodukt DetailN/A
/collections.jsonAlle Kollektionen?page=N
/collections/{handle}/products.jsonProdukte in einer Sammlung?page=N&limit=250
/meta.jsonMetadaten speichern (Name, Beschreibung)N/A

Produktdatenstruktur

Jedes Produktobjekt der JSON API umfasst:

  • Grundinformationen: Titel, Griff (slug), body html (Beschreibung), Anbieter, product type, tags
  • Varianten: Jede Variante hat einen eigenen Preis, vergleichen at price, SKU, Inventarstatus und Optionswerte (Größe, Farbe, etc.)
  • Bilder: URLs für alle Produktbilder mit Alttext
  • Datum: erstellt at, aktualisiert at, publiziert at

Grenzwerte

Shopify gilt für den Schutz der Speicherleistung. Die öffentlichen JSON Endpunkte erlauben typischerweise 2-4 Anfragen pro Sekunde pro IP, bevor die Drosselung eintritt. Hier ist Wohngebiete werden essentiell – die Verbreitung von Anfragen über mehrere IPs ermöglicht es Ihnen, den Durchsatz beizubehalten, ohne die Geschwindigkeitsbegrenzungen auf jedem einzelnen IP zu treffen.

Proxy-Konfiguration für Shopify

Shopify's Rate Limiting ist IP-basiert, so dass Proxy Rotation die primäre Strategie für Schrott im Maßstab.

ProxyHat Setup

# 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:8080

Für Shopify-Schrott, verwenden Sie per-Request-Rotation, wenn Sie verschiedene Läden, und klebrige Sitzungen, wenn Sie durch einen einzelnen Shop Produktkatalog paginieren. Dieses Muster imitiert natürliches Surfverhalten.

Implementierung von Python

Hier ist ein produktionsbereiter Shopify-Schrotter mit ProxyHat's Python SDK.

JSON API Scrap

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))

Monitoring Preisveränderungen Across Stores

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 changes

Node.js Implementierung

Eine Node.js-Version mit ProxyHat's Node SDK.

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 Strategien

Shopify Stores entdecken

Vor dem Abkratzen müssen Sie identifizieren, welche Wettbewerber-Websites auf Shopify laufen. Gemeinsame Indikatoren umfassen:

  • Die /products.json Endpoint gibt gültig JSON zurück
  • HTML-Quelle enthält Shopify.theme oder cdn.shopify.com
  • Die x-shopify-stage Header ist in Antworten vorhanden

Umgang mit passwortierten Stores

Einige Shopify-Shops benötigen ein Passwort zum Zugriff. Dies sind typischerweise Vor-Lunch- oder Großhandelsgeschäfte. Die JSON Endpunkte werden eine Umleitung auf die Passwortseite zurückgeben. Überspringen Sie diese Läden in Ihrer Schrottpipeline, es sei denn, Sie haben autorisierten Zugang.

Umgang mit benutzerdefinierten Domains

Shopify-Shops verwenden oft benutzerdefinierte Domains statt .myshopify.com. Die JSON API funktioniert genauso auf benutzerdefinierten Domains. Verwenden Sie einfach die Public-Fate-Domain des Stores in Ihren Anfragen.

Inventar Tracking

Produktvarianten umfassen eine available Feld, das den Bestandsstatus angibt. Indem Sie dieses Feld im Laufe der Zeit verfolgen, können Sie die Inventarwerte der Konkurrenten überwachen und identifizieren, wann Produkte aus dem Lager gehen — nützliche Intelligenz für Preis- und Wiederaufstockungsentscheidungen.

Vermeiden von Blöcken und Grenzwerten

Während Shopify kraterfreundlicher ist als Amazon, erzwingt es immer noch Schutz.

Vermeiden von Blöcken und Grenzwerten
SchutzDetailsMitiging
IP-Beschränkung~2-4 req/sec per IP für JSON EndpunkteVerdrehen von Wohn-Proxis über Anfragen
DatenschutzEinige Läden verwenden CloudflareResidential IPs mit Browser-ähnlichen Headern
Bot-DetektionVerhaltensmuster überwachtZufällige Verzögerungen und User-Agents
PasswortseitenPre-Launch/Wholesale-Shops gesperrtSkip oder autorisierter Zugriff

Mehr zum Umgang mit Anti-Bot-Systemen, lesen Sie unsere Anleitung auf wie man Websites schrott, ohne blockiert zu werden.

Key Takeaway: Shopify's JSON API ist der effizienteste Schrottansatz – es gibt Ihnen strukturierte Daten ohne HTML-Pasing. Verwenden Sie es, bevor Sie zurück zu HTML Scraping.

Anwendungsfälle

Sobald Sie die Produktdaten von Shopify gesammelt haben, sind hier die wertvollsten Anwendungen:

  • Wettbewerbspreis: Verfolgen Sie die Wettbewerberpreise in Produktkategorien und passen Sie Ihre Preisstrategie in Echtzeit an.
  • Produktforschung: Identifizieren Sie Trendprodukte, neue Starts und Marktlücken, indem Sie mehrere Läden überwachen.
  • Marktanalyse: Aggregate Daten in Hunderten von Shopify-Shops, um Markttrends, Preisverteilung und Kategoriewachstum zu verstehen.
  • Kataloganreicherung: Verwenden Sie Konkurrentenproduktbeschreibungen, Bilder und Spezifikationen, um Ihre eigenen Listen zu verbessern.
  • Brandüberwachung: Verfolgen Sie unbefugte Verkäufer Ihrer Produkte und überwachen Sie MAP-Compliance über Shopify-Shopfronts.

Schlüsselanhänger

  • Geschäfte /products.json Endpoint ist die effizienteste Abstreifmethode – verwenden Sie sie vor dem HTML-Pasing.
  • Eine einzige Scraper-Architektur arbeitet in allen Shopify-Stores aufgrund der standardisierten Struktur.
  • Residential-Proxies mit Rotation überwinden Shopifys IP-basierte Rate Begrenzung.
  • Verwenden Sie klebrige Sitzungen, wenn Sie sich durch einen einzelnen Shop Katalog paginieren.
  • Verfolgen Sie die Preisgestaltung und Verfügbarkeit von Varianten für umfassende wettbewerbsfähige Intelligenz.
  • Beginnen Sie mit ProxyHat's Wohn-Proxies Ihr Shopify-Schrott zuverlässig zu skalieren.

Fertig zu starten Scraping Shopify Läden? Entdecken Sie unsere e-Commerce Daten-Schrottführer für die volle Strategie und überprüfen Sie unsere Python Proxyführer und Node.js Proxyführer für Implementierungsdetails. Besuchen Sie uns Seite zu beginnen.

Bereit loszulegen?

Zugang zu über 50 Mio. Residential-IPs in über 148 Ländern mit KI-gesteuerter Filterung.

Preise ansehenResidential Proxies
← Zurück zum Blog