Jak scrapować Etsy — przewodnik po badaniu nisz dla POD i e-commerce

Praktyczny przewodnik scrapowania Etsy dla zespołów POD i badaczy nisz: struktura strony, omijanie Cloudflare, rotacyjne proxy residential, przykłady w Python i etyka wobec małych sprzedawców.

Jak scrapować Etsy — przewodnik po badaniu nisz dla POD i e-commerce

Dlaczego warto scrapować Etsy — i dlaczego to trudniejsze niż się wydaje

Etsy to jedna z najbogatszych baz danych o niszach produktowych w internecie. Ponad 7 milionów sprzedawców, miliony aktywnych listingów i publiczne dane o sprzedaży, cenach i recenzjach — wszystko to kopalnia wiedzy dla zespołów print-on-demand (POD) i narzędzi do badania rynku. Ale scrapowanie Etsy nie jest proste. Strona chroni się przed botami za pomocą Cloudflare, wewnętrznych limitów żądań i śledzenia sesji.

W tym przewodniku pokażę Ci:

  • Jak jest zbudowane Etsy — od wyszukiwania po strony sklepów
  • Jakie technologie anti-bot stosuje i jak je omijać
  • Konkretne wzorce scrapowania do odkrywania nisz (trending, seller count, avg price)
  • Pełny przykład w Python — od wyszukiwania po detale listingów z rotacją IP
  • Analitykę sklepów — listingi, sprzedaż, recenzje
  • Etykę — dlaczego scrapowanie dla badań to nie kopiowanie designów
Ważne: Ten przewodnik jest przeznaczony do badań rynkowych i analizy trendów. Nie służy do kopiowania czyichś prac ani naruszania praw autorskich.

Struktura Etsy — co i jak scrapować

Zanim zaczniesz pisać kod, musisz zrozumieć, jak Etsy organizuje dane. To nie jest płaska strona — to złożony marketplace z kilkoma kluczowymi typami stron.

Strona wyszukiwania

URL: https://www.etsy.com/search?q=QUERY

Wyniki wyszukiwania to główny punkt wejścia. Każda strona zwraca do 48 listingów (tzw. listing cards). Parametry URL pozwalają filtrować:

  • min_price / max_price — zakres cenowy
  • ship_to — kraj dostawy
  • locationQuery — lokalizacja sprzedawcy
  • item_type — typ przedmiotu (handmade, vintage, supplies)

Selektory CSS listing card na stronie wyszukiwania:

  • Kontener karty: div.v2-listing-card
  • Tytuł: h3.v2-listing-card__info__title
  • Cena: span.currency-value
  • Link do listingu: a.listing-link (atrybut href)
  • URL obrazu: img.wt-width-full (atrybut src lub data-src-img)

Strona listingu (detail page)

URL: https://www.etsy.com/listing/LISTING_ID/SLUG

To strona konkretnego produktu. Znajdziesz tu:

  • Pełny opis produktu
  • Cenę i opcje wariantów
  • Liczbu sprzedanych sztuk ("X people have this in their cart")
  • Recenzje z ocenami
  • Nazwa sklepu i link do profilu

Strona sklepu

URL: https://www.etsy.com/shop/SHOP_NAME

Profil sklepu ujawnia:

  • Liczba sprzedaży — badge "X Sales" (Etsy pokazuje przybliżoną wartość)
  • Liczba listingów
  • Oceny i recenzje
  • Rok dołączenia
  • Lokalizację

Drzewo kategorii

Etsy organizuje produkty w hierarchię kategorii:

  • https://www.etsy.com/c/jewelry → biżuteria
  • https://www.etsy.com/c/clothing → odzież
  • https://www.etsy.com/c/home-and-living → dom i ogród

Każda kategoria ma podkategorie. Możesz rekursywnie przechodzić drzewo, wyciągając linki z nawigacji boczej (nav.category-nav).

Anti-bot Etsy — Cloudflare i limity żądań

Etsy korzysta z Cloudflare jako pierwszej linii obrony. Oznacza to:

  • Wyzwanie JS — pierwsze żądanie z nowego IP często trafia na stronę challenge'ową Cloudflare
  • Rate limiting — z jednego IP możesz wysłać około 60–80 żądań na minutę, zanim dostaniesz 429
  • Session tracking — cookies i fingerprinting przeglądarki; nagłe zmiany zachowania flagują sesję
  • Canvas/WebGL fingerprinting — zaawansowane wykrywanie headless browserów

Jakie proxy do Etsy?

Dla Etsy residential proxy to praktycznie wymóg. Datacenter IP są masowo blokowane przez Cloudflare. Mobile proxy działają świetnie (wyższy trust score), ale są droższe.

Typ proxy Trust score przy Cloudflare Sukces scrapowania Etsy Koszt Zalecenie
Datacenter Niski 10–30% (częste CAPTCHA) Niski Tylko do testów
Residential Wysoki 85–95% Średni Zalecane do Etsy
Mobile Bardzo wysoki 95%+ Wysoki Dla dużych wolumenów

Rotacja IP na każde żądanie (per-request rotation) jest kluczowa przy masowym scrapowaniu wyszukiwania. Do pobierania detail pages używaj sticky sessions — jedno IP na całą sesję przeglądania sklepu.

Wzorce scrapowania do odkrywania nisz

Dla zespołów POD i badaczy rynku, Etsy to złota kopalnia danych o niszach. Oto konkretne wzorce:

1. Trending search terms — popularne zapytania

Etsy nie ma publicznego API do trending terms, ale możesz wyciągnąć sugestie z autouzupełniania:

import requests
from urllib.parse import quote

def get_etsy_suggestions(keyword, proxy_url):
    url = f"https://www.etsy.com/api/v3/ajax/member/search-suggestions?query={quote(keyword)}"
    headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"}
    resp = requests.get(url, headers=headers, proxies={"http": proxy_url, "https": proxy_url})
    return resp.json()  # zwraca listę sugestii

proxy = "http://user-country-US:pass@gate.proxyhat.com:8080"
print(get_etsy_suggestions("mug", proxy))

Wysyłaj zapytania dla różnych seed keywords i buduj mapę trendów. Powtarzaj codziennie, żeby wyłapać trendy sezonowe.

2. Seller count per niche — ile sklepów sprzedaje w danej niszy

Scrapuj stronę wyszukiwania dla słowa kluczowego i licz unikalne nazwy sklepów:

import requests
from bs4 import BeautifulSoup
from urllib.parse import quote

def count_sellers_for_niche(keyword, pages=3, proxy_url=None):
    unique_shops = set()
    proxies = {"http": proxy_url, "https": proxy_url} if proxy_url else None
    headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"}

    for page in range(1, pages + 1):
        url = f"https://www.etsy.com/search?q={quote(keyword)}&page={page}"
        resp = requests.get(url, headers=headers, proxies=proxies, timeout=30)
        soup = BeautifulSoup(resp.text, "html.parser")
        cards = soup.select("div.v2-listing-card")
        for card in cards:
            shop_el = card.select_one("span.v2-listing-card__shop-name")
            if shop_el:
                unique_shops.add(shop_el.get_text(strip=True))

    return {"keyword": keyword, "unique_shops": len(unique_shops), "shops": list(unique_shops)}

proxy = "http://user-country-US:pass@gate.proxyhat.com:8080"
result = count_sellers_for_niche("funny coffee mug", pages=5, proxy_url=proxy)
print(result)

3. Average price points — średnia cena w niszy

Wyciągnij ceny ze strony wyszukiwania i policz średnią, medianę i rozkład:

import re
import statistics

def extract_prices(keyword, pages=3, proxy_url=None):
    prices = []
    proxies = {"http": proxy_url, "https": proxy_url} if proxy_url else None
    headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"}

    for page in range(1, pages + 1):
        url = f"https://www.etsy.com/search?q={quote(keyword)}&page={page}"
        resp = requests.get(url, headers=headers, proxies=proxies, timeout=30)
        soup = BeautifulSoup(resp.text, "html.parser")
        cards = soup.select("div.v2-listing-card")
        for card in cards:
            price_el = card.select_one("span.currency-value")
            if price_el:
                price_text = price_el.get_text(strip=True)
                match = re.search(r'[\d.,]+', price_text)
                if match:
                    price = float(match.group().replace(',', '.'))
                    prices.append(price)

    if not prices:
        return None
    return {
        "keyword": keyword,
        "count": len(prices),
        "avg": round(statistics.mean(prices), 2),
        "median": round(statistics.median(prices), 2),
        "min": min(prices),
        "max": max(prices),
    }

proxy = "http://user-country-US:pass@gate.proxyhat.com:8080"
print(extract_prices("custom pet portrait", pages=5, proxy_url=proxy))

Pełny przykład — od wyszukiwania po detale listingów

Poniższy skrypt łączy wszystko w jeden pipeline: scrapuje wyniki wyszukiwania, wyciąga linki do listingów, a potem odwiedza każdą stronę detail z rotacyjnym residential proxy.

import requests
from bs4 import BeautifulSoup
from urllib.parse import quote, urljoin
import time
import json
import random

# --- Konfiguracja ProxyHat ---
PROXY_GATEWAY = "http://user-country-US:pass@gate.proxyhat.com:8080"
PROXIES = {"http": PROXY_GATEWAY, "https": PROXY_GATEWAY}

HEADERS = {
    "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",
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
    "Accept-Language": "en-US,en;q=0.5",
}

def fetch_search_results(keyword, max_pages=3):
    """Scrap strony wyszukiwania i wyciągnij linki do listingów."""
    listing_urls = []
    for page in range(1, max_pages + 1):
        url = f"https://www.etsy.com/search?q={quote(keyword)}&page={page}"
        resp = requests.get(url, headers=HEADERS, proxies=PROXIES, timeout=30)
        resp.raise_for_status()
        soup = BeautifulSoup(resp.text, "html.parser")

        links = soup.select("a.listing-link")
        for link in links:
            href = link.get("href", "")
            if "/listing/" in href:
                full_url = urljoin("https://www.etsy.com", href.split("?")[0])
                listing_urls.append(full_url)

        time.sleep(random.uniform(2, 4))  # uszanuj serwer
    return list(set(listing_urls))

def fetch_listing_detail(url):
    """Scrap stronę detail listingu."""
    # Sticky session — to samo IP na kilka żądań w ramach jednego sklepu
    session = requests.Session()
    session.headers.update(HEADERS)
    session.proxies = PROXIES

    resp = session.get(url, timeout=30)
    resp.raise_for_status()
    soup = BeautifulSoup(resp.text, "html.parser")

    # Tytuł
    title_el = soup.select_one("h1[data-buy-box-label='title']") or soup.select_one("h1")
    title = title_el.get_text(strip=True) if title_el else ""

    # Cena
    price_el = soup.select_one("span.currency-value")
    price = price_el.get_text(strip=True) if price_el else ""

    # Opis
    desc_el = soup.select_one("div[data-product-description]") or soup.select_one("#description-text")
    description = desc_el.get_text(strip=True)[:500] if desc_el else ""

    # Nazwa sklepu
    shop_el = soup.select_one("a.shop-name") or soup.select_one("span.shop-name")
    shop_name = shop_el.get_text(strip=True) if shop_el else ""

    return {
        "url": url,
        "title": title,
        "price": price,
        "shop_name": shop_name,
        "description": description,
    }

def main():
    keyword = "funny coffee mug"
    print(f"Scrapowanie wyników wyszukiwania dla: {keyword}")
    urls = fetch_search_results(keyword, max_pages=3)
    print(f"Znaleziono {len(urls)} unikalnych listingów")

    results = []
    for i, url in enumerate(urls[:10]):  # limit do 10 dla przykładu
        print(f"[{i+1}/10] {url}")
        try:
            detail = fetch_listing_detail(url)
            results.append(detail)
        except Exception as e:
            print(f"  Błąd: {e}")
        time.sleep(random.uniform(3, 6))

    print(json.dumps(results, indent=2, ensure_ascii=False))

if __name__ == "__main__":
    main()
Tip: Do pobierania detail pages używaj sticky sessions — dodaj flagę session do username w ProxyHat: user-country-US-session-abc123:pass@gate.proxyhat.com:8080. To zapewni, że wszystkie żądania w ramach jednej sesji pójdą z tego samego IP, co wygląda naturalniej dla Cloudflare.

Analityka sklepów — co możesz wyciągnąć

Etsy ujawnia więcej danych o sklepach niż większość marketplace'ów. Oto co możesz systematycznie zbierać:

Liczba sprzedaży — badge "X Sales"

Etsy wyświetla przybliżoną liczbę sprzedaży jako badge na stronie sklepu. Selektor: span.shop-sold-badge lub tekst zawierający "Sales". Wartość jest zaokrąglona (np. "5,000 Sales", "234 Sales"), ale wciąż użyteczna do szacowania skali sprzedawcy.

Liczba listingów

Na stronie sklepu znajdziesz informację o liczbie aktywnych listingów. To wskaźnik tego, jak aktywny jest sprzedawca — sklep z 5 listingami to inna kategoria niż sklep z 500.

Recenzje i oceny

Etsy pokazuje recenzje na dwóch poziomach:

  • Recenzje produktu — na stronie listingu
  • Recenzje sklepu — na stronie sklepu (https://www.etsy.com/shop/SHOP_NAME/reviews)
def fetch_shop_stats(shop_name, proxy_url=None):
    """Wyciągnij statystyki sklepu z Etsy."""
    proxies = {"http": proxy_url, "https": proxy_url} if proxy_url else None
    headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"}

    url = f"https://www.etsy.com/shop/{shop_name}"
    resp = requests.get(url, headers=headers, proxies=proxies, timeout=30)
    soup = BeautifulSoup(resp.text, "html.parser")

    # Sprzedaże
    sales = ""
    sales_el = soup.select_one("[data-sales]") or soup.find(string=re.compile(r'\d+[,.]?\d*\s*Sales?'))
    if sales_el:
        sales = sales_el.get_text(strip=True) if hasattr(sales_el, 'get_text') else str(sales_el)

    # Liczba listingów
    listing_count = len(soup.select("a.listing-link"))

    # Ocena
    rating_el = soup.select_one("span.screen-reader-only")
    rating = rating_el.get_text(strip=True) if rating_el else ""

    return {
        "shop": shop_name,
        "sales": sales,
        "listing_count": listing_count,
        "rating": rating,
    }

proxy = "http://user-country-US:pass@gate.proxyhat.com:8080"
print(fetch_shop_stats("SmallBusinessExample", proxy_url=proxy))

Co z tych danych wyciągnąć?

  • Stosunek sprzedaży do listingów — jeśli sklep ma 10 listingów i 50 000 sprzedaży, to znak, że nisza ma duży popyt
  • Średnia cena w niszy — czy rynek premium czy budżetowy
  • Rozkład ocen — niska ocena = szansa na lepszy produkt
  • Trendy sezonowe — śledź, kiedy listingi zyskują na popularności

Etyka — Etsy to małe biznesy, nie korporacje

To najważniejsza sekcja tego przewodnika. Etsy to platforma dla małych, niezależnych twórców. Kiedy scrapujesz Etsy, masz dostęp do danych o prawdziwych ludziach, którzy często inwestują oszczędności życia w swój sklep.

Czego NIE robić

  • Nie kopiuj designów — scrapowanie po to, żeby skopiować czyjeś projekty mugów, koszulek czy plakatów, to kradzież intelektualna
  • Nie masowo pobieraj obrazów — pobieranie tysięcy zdjęć produktów do trenowania AI bez zgody to naruszenie praw autorskich
  • Nie spamuj sprzedawców — nie używaj danych kontaktowych do masowego cold emailingu
  • Nie obciążaj serwerów — zachowaj rozsądne opóźnienia między żądaniami (3–6 sekund)

Co JEST w porządku

  • Badanie trendów — analizowanie, które kategorie rosną i które słabną
  • Analiza cenowa — zrozumienie, jak kształtują się ceny w niszy
  • Identyfikacja luk w rynku — znajdowanie podnisz z popytem, ale słabą ofertą
  • Monitorowanie własnej marki — śledzenie, czy ktoś nie narusza Twoich praw autorskich
  • Budowanie narzędzi analitycznych — SaaS do researchu rynku (podobnie jak eRank czy Marmalead)
Złota zasada: Scrapuj Etsy po to, żeby lepiej zrozumieć rynek i stworzyć lepszy produkt — nie po to, żeby ukraść czyjeś pomysły.

Najlepsze praktyki — podsumowanie techniczne

  • Używaj residential proxy — datacenter IP są masowo blokowane na Etsy. ProxyHat oferuje residential IP z geo-targetingiem — sprawdź dostępne lokalizacje.
  • Rotuj IP na każde żądanie do stron wyszukiwania; używaj sticky sessions do detail pages
  • Dodaj opóźnienia — 3–6 sekund między żądaniami, 10–15 sekund po otrzymaniu 429
  • Używaj realistycznych nagłówków — User-Agent, Accept-Language, Referer
  • Obsługuj błędy — 403 (Cloudflare block), 429 (rate limit), 503 (temporary)
  • Cache'uj wyniki — nie scrapuj tej samej strony dwa razy bez powodu
  • Szacuj limity — przy 60 żądań/minutę/IP i rotacji residential proxy, możesz realistycznie pobrać ~3 600 stron na godzinę

Kluczowe wnioski

  • Etsy jest chronione przez Cloudflare — residential proxy to wymóg, nie opcja
  • Struktura Etsy: wyszukiwanie → listing detail → shop page — każdy poziom daje inne dane
  • Dla odkrywania nisz: scrapuj sugestie wyszukiwania, licz sprzedawców w niszy, analizuj ceny
  • Dla analityki sklepów: wyciągaj badge sprzedaży, licz listingów, recenzje
  • Używaj ProxyHat z flagą country i session w username dla geo-targetingu i sticky sessions
  • Etyka jest kluczowa — scrapuj dla researchu, nie dla kopiowania designów
  • Zacznij od małej skali, dodaj opóźnienia, i dopiero potem zwiększaj wolumen

Jeśli szukasz reliable residential proxy do scrapowania Etsy, sprawdź plany ProxyHat — z geo-targetingiem w ponad 190 krajach i rotacją IP na każde żądanie. Więcej o scrapowaniu w praktyce znajdziesz w naszym przewodniku po residential proxy.

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