Jak scrape Sklepy ze Sklepem: Kompletny przewodnik

Dowiedz się, jak zeskrobać dane sklepowe za pomocą punktów końcowych JSON API i proxy mieszkaniowe. Kompletny kod Python i Node.js do ekstrakcji produktów, cen i zapasów danych.

Jak scrape Sklepy ze Sklepem: Kompletny przewodnik

Dlaczego Scrape Shopify Stores?

Szopify uprawnień ponad 4 mln sklepów internetowych na całym świecie, od małych niezależnych marek do głównych detalistów. To czyni go jednym z najbogatszych źródeł inteligencji handlu elektronicznego. Poprzez skrobanie sklepach Shopify można śledzić ceny konkurencyjne, monitorować wprowadzanie produktów, analizować trendy rynkowe i budować kompleksowe bazy danych produktów.

Dobra wiadomość jest taka, że Shopify ma przewidywalną strukturę, która sprawia, że drapanie jest bardziej systematyczne niż większość platform handlu elektronicznego. Każdy sklep Shopify ujawnia pewne dane poprzez standardowe punkty końcowe, co oznacza, że jedna architektura scrapper może pracować w tysiącach różnych sklepów. Aby uzyskać szerszy przegląd strategii e-commerce scrating, zobacz nasz Przewodnik do zeskrobywania danych e-commerce.

Zrozumienie struktury sklepu Shopify

Każdy sklep Shopify śledzi ten sam adres URL i wzorce danych, niezależnie od tematu lub dostosowania.

Publiczne punkty końcowe JSON

Shopify ujawnia dane produktu poprzez punkty końcowe JSON, które nie wymagają uwierzytelniania. Są to najskuteczniejszy sposób zeskrobywania sklepów Shopify, ponieważ otrzymujesz uporządkowane dane bez przetwarzania HTML.

Punkt końcowyZwrócone danePaginacja
/products.jsonWszystkie produkty z wariantami, cenami, obrazkami?page=N&limit=250
/products/{handle}.jsonSzczegóły dotyczące jednego produktuNie dotyczy
/collections.jsonWszystkie kolekcje?page=N
/collections/{handle}/products.jsonProdukty w kolekcji?page=N&limit=250
/meta.jsonPrzechowywanie metadanych (nazwa, opis)Nie dotyczy

Struktura danych produktu

Każdy obiekt produktu z JSON API obejmuje:

  • Podstawowe informacje: tytuł, uchwyt (ślimak), body _ html (opis), sprzedawca, produkt _ type, tagi
  • Warianty: Każdy wariant ma własną cenę, porównaj _ w cenie, SKU, stan inwentarza i wartości opcji (rozmiar, kolor, itp.)
  • Obrazy: URL dla wszystkich obrazów produktów z tekstem alt
  • Daty: created _ at, updated _ at, published _ at

Ograniczenie stawki

Shopify stosuje limity stawek w celu ochrony wydajności sklepu. Publiczne punkty końcowe JSON zazwyczaj pozwalają na 2- 4 wnioski na sekundę na IP przed wciśnięciem. To tutaj. proxy mieszkaniowe stają się niezbędne - rozpowszechnianie wniosków w wielu IP pozwala utrzymać przepustowość bez przekraczania limitów prędkości na każdym IP.

Konfiguracja Proxy dla Shopify

Ograniczenie szybkości Shopify opiera się na IP-, co czyni rotację proxy podstawową strategią dla skrobania na skalę.

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

Do skrobania Shopify użyj rotacji na żądanie podczas skrobania różnych sklepów i lepkich sesji podczas przeglądania katalogu produktów jednego sklepu. Ten wzór naśladuje naturalne zachowanie przeglądania.

Wdrażanie Pythona

Oto gotowy do produkcji skrobacz Shopify za pomocą Python SDK ProxyHat.

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

Monitorowanie zmian cen w poszczególnych sklepach

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

Wdrażanie Node.js

Wersja Node.js przy użyciu Węzeł ProxyHat 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");
});

Specyficzne strategie rozdrabniania

Odkrywanie sklepów sklepowych

Przed drapaniem, należy zidentyfikować, które strony konkurencyjne działają na Shopify. Wspólne wskaźniki obejmują:

  • W /products.json punkt końcowy zwraca ważny JSON
  • Źródło HTML zawiera Shopify.theme lub cdn.shopify.com
  • W x-shopify-stage nagłówek jest obecny w odpowiedziach

Postępowanie ze składami passwordowanymi

Niektóre sklepy Shopify wymagają hasła do dostępu. Są to zazwyczaj sklepy przedstartowe lub hurtowe. Punkty końcowe JSON powrócą do strony z hasłem. Pomiń te sklepy w swoim rurociągu, chyba że masz autoryzowany dostęp.

Radzenie sobie z domenami Custom

Sklepy często używają domen niestandardowych zamiast .myshopify.com. API JSON działa w ten sam sposób na niestandardowych domen. Po prostu użyj domeny sklepu w swoich prośbach.

Śledzenie zapasów

Warianty produktów obejmują available pole wskazujące stan zapasów. Śledząc to pole w czasie, można monitorować poziom zapasów konkurentów i określić, kiedy produkty wychodzą z zapasów - przydatna inteligencja dla ustalania cen i ponownego zarybiania decyzji.

Uniknięcie bloków i wartości granicznych

Podczas gdy Shopify jest bardziej przyjazne dla złomu niż Amazon, to nadal wzmacnia ochronę.

OchronaSzczegółyŁagodzenie
Ograniczenie stawki IP~ 2- 4 req / sek na IP dla punktów końcowych JSONObróć proxy mieszkaniowe w zależności od zapotrzebowania
Ochrona przed chmuramiNiektóre sklepy używają CloudflareIP mieszkalne z nagłówkami przypominającymi przeglądarki
Wykrywanie botówMonitorowane wzorce behawioralneRandomizuj opóźnienia i agentów User-
Strony hasełPrzed uruchomieniem / hurtowe sklepy zablokowanePomiń lub skorzystaj z autoryzowanego dostępu

Więcej na temat obsługi systemów anty-bot, przeczytaj nasz przewodnik na jak zeskrobać strony internetowe bez blokowania.

Klucz na wynos: Szopify JSON API jest najbardziej efektywnym podejściem do skrobania - daje uporządkowane dane bez udziału HTML. Użyj go przed powrotem do skanowania HTML.

Przypadki wykorzystania danych

Po zebraniu danych o produktach Shopify, oto najcenniejsze aplikacje:

  • Konkurencyjne ceny: Śledź konkurencyjne ceny w różnych kategoriach produktów i dostosować swoją strategię cenową w czasie rzeczywistym.
  • Badania produktów: Identyfikacja produktów trendujących, nowych uruchomień i luki rynkowe poprzez monitorowanie wielu sklepów.
  • Analiza rynku: Zagregowane dane dotyczące setek sklepów typu Shopify, aby zrozumieć tendencje rynkowe, dystrybucję cen i wzrost kategorii.
  • Ubogacenie katalogów: Użyj konkurencyjnych opisy produktów, obrazy i specyfikacje, aby poprawić swoje własne listy.
  • Monitorowanie marki: Śledź nieautoryzowanych sprzedawców swoich produktów i monitoruj zgodność MAP w sklepach Shopify.

Key Takeaways

  • Szopify /products.json punkt końcowy jest najbardziej efektywną metodą skrobania - użyj jej przed przeparowaniem HTML.
  • Architektura jednego scrapera działa we wszystkich sklepach Shopify ze względu na standardową strukturę.
  • Proxy mieszkaniowe z rotacją pokonały ograniczenie IP- oparte na Shopify.
  • Używaj lepkich sesji podczas przeglądania katalogów jednego sklepu.
  • Wyceny na różnych poziomach toru i dostępność dla wszechstronnej, konkurencyjnej inteligencji.
  • Zacznij od ProxyHat 's residential proxy Aby wyskalować skrobanie Shopify niezawodnie.

Gotowy na skrobanie sklepów ze skorupkami? Poznaj nasze Przewodnik do zeskrobywania danych e-commerce dla pełnej strategii, i sprawdzić nasze Przewodnik proxy Pythona oraz Node.js przewodnik proxy szczegóły wdrażania. Odwiedź nasz Strona cenowa Na początek.

Gotowy, aby zacząć?

Dostęp do ponad 50 mln rezydencjalnych IP w ponad 148 krajach z filtrowaniem AI.

Zobacz cenyProxy rezydencjalne
← Powrót do Bloga