Tony Wang7 min readHow to Scrape Zalando in 2026 (API & Python)
Three ways to scrape Zalando search, product, and category data across 25 European markets in 2026 — DIY Python, no-code tools, or a structured API.
The fastest way to scrape Zalando in 2026 is to call a structured API that returns normalized JSON — keyword search, category and brand browsing, product detail, and search-box autocomplete — instead of parsing Zalando's HTML yourself. You can build a DIY scraper in Python, but Zalando's per-country storefronts, GraphQL-hydrated pages, and anti-bot defenses make it expensive to keep working.
Zalando does not offer a public, self-serve API for reading its product catalog. It does run a Partner Program (zDirect) for brands and retailers that already sell on Zalando, letting them manage listings, prices, and orders — but that's an onboarding-gated merchant tool, not a way for outside teams to search or research the storefront. A structured scraping API is the practical route for price monitoring, assortment research, and cross-market comparisons.
Why scrape Zalando data?
- Price monitoring — track how a specific SKU's price, discount, and availability move over time on one storefront.
- Cross-market price comparison — the same product can be priced differently across Zalando's 25 country domains; compare de vs. fr vs. gb for the same brand.
- Category and trend research — watch which brands, silhouettes, and categories gain listing volume or discount depth.
- Competitor and assortment tracking — see which brands a competitor category carries and how their catalog changes over a season.
- AI and data pipelines — feed normalized fashion-retail listings into pricing models, assortment tools, or retail-intelligence dashboards.
Is it legal to scrape Zalando?
Zalando's standard terms and conditions reserve the right to refuse or cancel an order "placed by the use of software, robot, crawler, spider or any automated system or scripted behavior" — that clause targets automated checkout (bots buying limited drops), not a blanket prohibition on browsing or reading public pages. Zalando's robots.txt disallows a specific set of paths — /api/*, /cart/*, /wardrobe/*, /myaccount/*, /reco-catalog/, /assistant, /opinions* — but does not carry a blanket disallow on catalog, search, or product pages, and it has no AI-crawler-specific rules. In the US, courts have repeatedly held that scraping publicly accessible pages does not violate the Computer Fraud and Abuse Act, even when a site's terms restrict it (see hiQ Labs v. LinkedIn, cited below) — but a terms-of-service breach can still get an account or IP banned, and EU users are additionally covered by GDPR when personal data is involved.
Practically:
- Collect only public search, category, product, and autocomplete data — no login-gated pages like cart, wardrobe, or account.
- Respect robots.txt and rate limits; don't hammer a single market's storefront with concurrent requests.
- Zalando prices and stock vary by country domain and currency — treat each market as a separate dataset rather than assuming one price applies everywhere.
- Don't reuse product photos or marketing copy beyond what your use case and copyright law allow; price, brand, SKU, and size availability are facts, but images and descriptions are Zalando's or the brand's content.
Option 1: DIY in Python (and why it breaks)
The naive approach fetches a search results page and parses product cards:
import csv, requests
from bs4 import BeautifulSoup
resp = requests.get(
"https://en.zalando.de/catalogue/",
params={"q": "running shoes"},
headers={"User-Agent": "Mozilla/5.0", "Accept-Language": "en-US,en;q=0.9"},
)
soup = BeautifulSoup(resp.text, "html.parser")
rows = []
for card in soup.select("article[data-testid='catalog-article']"):
name = card.select_one("h3")
price = card.select_one("[data-testid='price-formatted']")
rows.append({"name": name.get_text(strip=True) if name else None,
"price": price.get_text(strip=True) if price else None})
with open("zalando.csv", "w", newline="") as f:
w = csv.DictWriter(f, fieldnames=["name", "price"]); w.writeheader(); w.writerows(rows)
# ...then keep these selectors alive, handle GraphQL-hydrated content, and pick the right market domain
It works once, then the maintenance starts:
- Client-side and GraphQL-hydrated rendering. Search and suggest results are backed by an internal GraphQL API (
/api/graphql/), so a plainrequests.get()often returns a shell — you need a headless browser or the exact GraphQL payload to get real product data. - 25 separate country storefronts.
en.zalando.de,www.zalando.fr,www.zalando.co.uk,www.zalando.it, and 21 more each run their own domain, currency, and — for many categories — their own local-language URL slug for the same category. - Anti-bot defenses. Datacenter IPs get rate-limited or blocked, so you need rotating residential proxies and realistic headers.
- Multi-size variants. A single product page covers several sizes, each with its own SKU, GTIN, price, and stock status — parsing "the price" means picking the right variant for your use case.
- Selector churn. Zalando redesigns its grid and product pages periodically, breaking hand-written CSS selectors without notice.
Option 2: No-code / ready-made tools
Browser extensions and point-and-click scrapers can export one page of search results, but price monitoring and cross-market comparison mean re-running the same query on a schedule across multiple country domains and storing history. That's a recurring pipeline job, better served by an API you can call from a script or cron job than a manual export tool.
Option 3: A structured Zalando API
Crawlora's Zalando API wraps request handling, rendering, and parsing behind documented endpoints for search, category and brand browsing, product detail, autocomplete, and the supported market list. Every catalog endpoint requires an explicit market.
Start with the market list, since it's the reference for every other call:
curl "https://api.crawlora.net/api/v1/zalando/markets" \
-H "x-api-key: $CRAWLORA_API_KEY"
{"code":200,"msg":"OK","data":{"count":25,"markets":[
{"code":"de","domain":"en.zalando.de"},
{"code":"fr","domain":"www.zalando.fr"},
{"code":"gb","domain":"www.zalando.co.uk"},
{"code":"it","domain":"www.zalando.it"}
]}}
Then search a specific market by keyword:
import requests
BASE = "https://api.crawlora.net/api/v1/zalando"
headers = {"x-api-key": "YOUR_API_KEY"}
resp = requests.get(f"{BASE}/search", headers=headers, params={"q": "running shoes", "market": "de"})
for p in resp.json()["data"]["products"]:
print(p["sku"], p["brand"], p["name"], p["price"], p["currency"])
A response is normalized JSON (confirm the exact fields in the docs):
{
"code": 200,
"msg": "OK",
"data": {
"query": "running shoes",
"market": "de",
"count": 24,
"total_count": 4911,
"source_url": "https://en.zalando.de/catalogue/?q=running+shoes",
"fetched_at": "2026-07-01T12:00:00Z",
"products": [
{
"sku": "N1241A1HR-I11",
"name": "PEGASUS 42 SE - Road running shoes",
"brand": "Nike Performance",
"url": "https://en.zalando.de/nike-performance-pegasus-42-se-road-running-shoes-n1241a1hr-i11.html",
"image": "https://img01.ztat.net/article/spp-media-p1/example.jpg?imwidth=400",
"silhouette": "LOW_SHOE",
"price": 97.95,
"original_price": 149.95,
"discount_percent": 52,
"currency": "EUR"
}
]
}
}
From a search or category result, pass the same sku and market to product for full detail, including per-size variants:
product = requests.get(f"{BASE}/product", headers=headers, params={"sku": "N1241A1HR-I11", "market": "de"}).json()["data"]["product"]
for v in product["variants"]:
print(v["size"], v["sku"], v["price"], v["availability"])
{"sku":"ONM11A03W-A12","name":"CLOUD 6 - Trainers - white white","brand":"On","color":"white white/white",
"price":160,"currency":"EUR",
"variants":[{"size":"36","sku":"ONM11A03W-A120005000","gtin":"7615537206202","price":160,"currency":"EUR","availability":"InStock"}]}
Browse a category or brand slug (slugs are market-specific — shoes on de/gb, chaussures on fr, scarpe on it), and autocomplete a partial query:
category = requests.get(f"{BASE}/category", headers=headers, params={"category": "shoes", "market": "de"}).json()["data"]
suggest = requests.get(f"{BASE}/suggest", headers=headers, params={"q": "running sho", "market": "de"}).json()["data"]["suggestions"]
# suggest -> ["running shoes", "running shoes nike", "running shoes adidas", ...]
search and category both return total_count, the upstream's full match count, alongside the first page of results — deeper pagination isn't available yet, so treat total_count as a trend signal rather than something you can page through in full.
What you can collect
- Search results: SKU, name, brand, price, original price, discount percent, silhouette, and image, scoped to one market
- Category and brand listings, plus the upstream
total_countfor that category - Product detail: brand, color, description, all images, and per-size variants (SKU, GTIN, price, currency, availability)
- Search-box autocomplete completions for a partial query
- The full list of 25 supported markets with their domains
Limitations
- No public catalog API. Zalando's Shop Public API was archived without a public launch; its zDirect Partner API is merchant-only, so full outside catalog access still means scraping.
- Market fragmentation. Price, currency, and even category slugs are per-country; comparing markets means querying each one separately and normalizing currency yourself.
- First-page results only. Search and category calls return the first page Zalando renders plus
total_count— deeper pagination isn't supported yet. - Anti-bot and GraphQL-hydrated rendering. Plain HTTP requests against Zalando's storefront are unreliable; a structured API handles headers, rendering, and retries behind one key.
- Media is copyrighted. Prices, brands, SKUs, and stock status are facts you can collect; product photos and marketing copy carry copyright — don't republish beyond what your use case and law allow.
Where this gets used
- Price and discount monitoring for a specific brand or category on one or more storefronts
- Cross-market fashion price comparison and arbitrage research
- Assortment and trend tracking segmented by brand, category, or silhouette
- Enrichment pipelines feeding normalized apparel and footwear data into pricing or retail-intelligence tools
Sources
Start collecting
Try it first, free: run any public URL through the Free Web Scraper, or check whether a site blocks bots with the Anti-Bot Checker — no signup.
Zalando data pairs well with other fashion-marketplace APIs for cross-platform research — see how to scrape Vinted for secondhand fashion pricing, how to scrape Etsy for handmade and vintage goods, or how to scrape Target for a US general-merchandise comparison. Get started by testing the endpoint in the Playground, reading the request and response schema in the API docs, and reviewing credit costs on the pricing page. Not sure this is legal for your use case? Read Is web scraping legal in 2026? first.
Part of our how-to-scrape guide series — every platform we cover, in one index.
Frequently asked questions
Does Zalando have a public API for product or search data?
No. Zalando's Shop Public API was archived without ever being opened to the public, and its zDirect Partner Program API is scoped to merchants that already sell on Zalando managing their own listings, prices, and orders — not to outside teams searching or researching the catalog.
How do I search Zalando products with an API?
Send a keyword and a market code (e.g. de, fr, gb) to Crawlora's /zalando/search endpoint and get normalized product results — SKU, name, brand, price, discount, and image — as structured JSON.
Why does every Zalando endpoint need a market parameter?
Zalando runs a fully separate storefront per European country — 25 markets in total — each with its own domain, currency, and often its own local-language category slugs. There is no default storefront, so search, category, and product calls all require an explicit market, and prices for the same product can differ by market.
Can I compare Zalando prices across different countries?
Yes, but each market has to be queried separately. Call the same search or product endpoint once per market code (e.g. de, fr, it) and compare the returned price and currency fields yourself — Crawlora doesn't merge markets into one response.
Is it legal to scrape Zalando?
Zalando's terms reserve the right to refuse or cancel orders placed by bots or scripted automation, and its robots.txt disallows a specific set of paths (like /api/*, /cart/*, and /myaccount/*) without a blanket disallow on catalog or product pages. Collecting public search, category, and product data is a lower-risk starting point than anything login-gated, but this isn't legal advice — read Is Web Scraping Legal in 2026? for the fuller picture.
Does the Zalando API require a Zalando account or API key?
No Zalando account or API key is required from the caller — only your Crawlora API key.
Can I get every size and price variant for a Zalando product?
Yes. The /zalando/product endpoint returns a variants array with one entry per available size, each carrying its own SKU, GTIN, price, currency, and availability status.