Web scraping · E-commerce product data
E-commerce product data scraping: attributes, GTINs and variants
E-commerce product data scraping builds a catalogue, not a price chart: what each retailer lists, under which identifiers, with which attributes, variants and availability. Read the structured data first, collect each storefront from its own country, and match products on GTIN before anything else.
Pay per GB · No subscription · Prices in EUR, excl. VAT
- €0.75
- per GB on ARC Basic, excl. VAT
- −21%
- at 1 TB (€0.59 / GB)
- 185+
- countries, city targeting
- Never
- expires — no subscription
Written for
- PIM and catalogue teams
- Marketplace operators
- Retail analytics teams
- Brand content and syndication teams
The short answer
- Most product pages carry schema.org markup. Read
ProductandProductGroupJSON-LD before parsing HTML; it is smaller, stabler and already names the GTIN, brand and variant axes. - Store GTINs as 14 digits. GS1 recommends padding shorter GTINs with leading zeros, which turns an EAN-13 and a UPC-A for the same item into one key.
- Assortment, language and availability differ by country storefront. Collect each from an exit in its market.
- Attributes change slowly, availability changes daily. Refresh them on different schedules and the bandwidth bill drops by an order of magnitude.
- Since December 2024, EU product listings must show manufacturer details, product identification and safety warnings, which makes those fields collectable on EU storefronts.
The problem
What goes wrong without the right IPs
Variants hide behind one URL
A shirt in five sizes and four colours is often one page, with the selected variant's GTIN, stock and image swapped in by script. A crawler that reads only the default state captures one variant out of twenty.
GTINs are missing, wrong or reused
Marketplaces list items without a GTIN, sellers enter the wrong one, and the same code appears on bundles. Matching on GTIN alone produces false merges and missed matches in roughly equal measure.
Attribute names are not a schema
One retailer's 'Colour' is another's 'Farbe' and a third's free text in the title. Without a mapping to your own taxonomy, the collected attributes cannot be compared.
Each storefront has its own assortment
The same retailer sells a different range, under different titles, in each country. A catalogue built from one storefront misrepresents the others.
Full refreshes are mostly waste
Re-crawling every product page every day re-downloads descriptions and specifications that have not changed in months. Billing is per gigabyte, so the waste shows up on the invoice.
What to collect
What you can collect
- GTIN, normalised to 14 digits
- The primary matching key across retailers. Validate the check digit before trusting it.
- Brand and manufacturer part number
- The fallback key where the GTIN is missing or suspect. Normalise case and punctuation in the MPN.
- Title and description
- Content quality and search analysis. Store a hash so you can tell when the copy changed without diffing full text every day.
- Category path
- The retailer's own taxonomy, mapped to yours. Shows where a product is placed and how assortments are structured.
- Attributes as key–value pairs
- Size, colour, material, dimensions, energy class. Map keys to a controlled vocabulary and keep units explicit.
- Variant group and variant axes
- Which products belong together and what distinguishes them. schema.org calls these
ProductGroupandvariesBy. - Availability per variant
- In stock, out of stock, pre-order or discontinued, with the date. The fast-moving field; refresh it more often than the rest.
- Manufacturer details and safety information (EU)
- Name and contact of the manufacturer or EU responsible person and any warnings, shown on EU listings under the General Product Safety Regulation.
How it runs
How a collection run works
- 01
Discover product URLs from sitemaps and categories
Read each storefront's product sitemaps where they exist and fill gaps from category listings. Keep one URL list per country storefront.
- 02
Parse structured data before HTML
Extract JSON-LD from the product page and read
Product,ProductGroup,hasVariant,gtinandoffers.availability. Fall back to HTML selectors only for fields the markup omits.Read schema.org product data through a country exit24 linesimport jsonimport httpxfrom selectolax.parser import HTMLParserGATEWAY, PASSWORD = "proxy.arcproxies.io:8000", "PASSWORD"def fetch_product(url: str, country: str) -> list[dict]: user = f"USERNAME_pool-arc_country-{country}" with httpx.Client(proxy=f"http://{user}:{PASSWORD}@{GATEWAY}", timeout=30) as c: html = c.get(url).text items = [] for node in HTMLParser(html).css('script[type="application/ld+json"]'): try: data = json.loads(node.text()) except ValueError: continue for d in data if isinstance(data, list) else [data]: if d.get("@type") in ("Product", "ProductGroup"): items.append(d) return itemsdef gtin14(code: str) -> str: digits = "".join(ch for ch in code if ch.isdigit()) return digits.zfill(14) # GS1: store every GTIN as 14 digits - 03
Resolve variants explicitly
Where variants are not listed in the markup, request each variant's own URL or parameter, holding one sticky session per product so the variant selector and stock state stay consistent.
- 04
Match products across retailers
Match on validated GTIN first, then on brand plus normalised MPN, then on title and attribute similarity for review. Keep match confidence as a field rather than forcing every product into a group.
- 05
Refresh by field, not by page
Recheck availability daily from category or search listings, which show many products per request. Revisit full product pages weekly, or when the listing shows a new title or image.
Setup
Recommended setup
Catalogue crawls are large and steady. Keep them on the cheapest pool that each storefront accepts and reserve residential exits for variant sessions and the strictest sites.
| Plan | Role | Session | Targeting | Price |
|---|---|---|---|---|
ARC Basic Rotating ISP | Default for product pages and category listings Our lowest price per GB for the bulk of the crawl. Country targeting puts you on the storefront, language and assortment of the market you are cataloguing. | Rotating | Country | €0.75 / GB €0.59 at 1 TB (−21%) |
ARC Fast Rotating residential | For variant resolution and rendered storefronts Residential exits held for one product while you step through its variants, so stock and selection state stay on one visitor. | Sticky, 10 minutes per product | Country + city | €2.00 / GB €1.12 at 1 TB (−44%) |
ARC Ultra Premium residential | For the storefront your catalogue depends on Premium residential for the one retailer where a failed refresh leaves a visible hole. Route that source only. | Sticky per product | Country + city | €3.50 / GB €2.17 at 1 TB (−38%) |
Prices are list prices in EUR, excl. VAT. Volume discounts apply automatically at checkout — full ladder on the pricing page.
Connect
One connection string per market
The country, city and sticky session are tokens in the username. Change the token, change the market; keep the session handle, keep the IP.
http://USERNAME_pool-arcfast_country-de_session-k3f9a1x2_sesstime-10:PASSWORD@proxy.arcproxies.io:8000Swap _country-de for any market you quote. The full grammar is on the residential proxies page.
Illustration
What a 200,000-product catalogue across five storefronts costs
An illustration with round numbers — your pages, payloads and retry rate will differ. The arithmetic is the real price ladder.
Assumptions
- Products
- 200,000 in total
- Full product page refresh
- weekly, 200 KB with images blocked
- Availability via listing pages
- 2,000 listing pages a day at 150 KB
- Images
- URLs stored, files not downloaded
- Bandwidth per month
- ≈ 183 GB
On ARC Basic
€124.44per month, excl. VAT
183 GB bought in one purchase at €0.68 / GB (−9% volume rung, applied automatically).
The same 183 GB on ARC Fast: €248.88 at €1.36 / GB. Route only the jobs that need it through the pricier pool.
Refreshing every product page daily instead of weekly would multiply the larger term by about seven. Reading availability from listing pages is what keeps a daily stock signal affordable.
Bandwidth never expires, so a bigger single purchase is only ever cheaper per GB. See the ladder.
In depth
E-commerce product data, in depth
Product data vs price monitoring
Both crawl product pages, but they answer different questions and are built differently. Price monitoring needs a few fields on a known set of products as often as possible. Catalogue collection needs many fields on as many products as possible, refreshed when they change.
| Product catalogue data | Price monitoring | |
|---|---|---|
| Question | What is listed, how is it described, is it in stock | What does it cost, and when did that change |
| Fields | GTIN, attributes, variants, content, availability | Price, promotion, shipping, seller |
| Breadth | Whole assortments | A defined product set |
| Cadence | Weekly content, daily availability | Hourly to daily |
| Typical buyer | PIM, marketplace and content teams | Pricing and revenue teams |
If the question is price, start on price monitoring or the deep dive on marketplace sellers. For prices in search results rather than on retailer pages, see shopping results.
Getting GTIN matching right
A GTIN is the GS1 key that identifies a trade item, and it comes in four lengths: GTIN-8, GTIN-12 (UPC), GTIN-13 (EAN) and GTIN-14, the last used for groupings such as a case rather than a consumer unit. GS1 recommends storing every GTIN as a 14-digit number, padded with leading zeros, so different lengths of the same code compare equal.
- Validate the check digit. A GTIN with a wrong check digit is a typing error, not a product. Drop it to the fallback key.
- Watch packaging levels. Each traded packaging level has its own GTIN. A six-pack and a single can are different items, even though their titles look alike.
- Treat duplicates as a signal. One GTIN on two very different titles usually means a seller error. Flag it for review rather than merging.
- Keep the variant level. Each size and colour normally has its own GTIN, so match at variant level and roll up to the product group afterwards.
Variants, ProductGroup and availability markup
schema.org models variants with ProductGroup: a group of products that vary only in well-described ways. The group lists members with hasVariant, names the distinguishing properties with variesBy (size, colour and so on), and carries an identifier in productGroupID. Where a storefront publishes this markup, it gives you the variant tree without clicking through selectors.
Availability usually sits in each variant's offers. Store it per variant with the date, because product-level availability hides the difference between 'sold out in your size' and 'sold out'.
EU listings and the General Product Safety Regulation
Since 13 December 2024, the EU's General Product Safety Regulation (2023/988) requires online offers to show the manufacturer's name and contact details, an EU responsible person where the manufacturer is outside the EU, information identifying the product, including a picture, and any warnings or safety information.
For catalogue teams that turns previously scattered information into fields you can collect on EU storefronts and check for completeness, for example to see which of a brand's listings lack the required details. Collect what the public listing shows; it is not a substitute for the information a manufacturer holds itself.
Product photos and written descriptions are usually protected by copyright. Store image URLs and text hashes for analysis, and check rights before republishing anything. Our acceptable use policy covers what the network may be used for.
Works with anything that takes a proxy URL
- Python requests / httpx
- Scrapy
Crawlee
Playwright
- Crawl4AI
- Docker
FAQ
Questions
Something not covered? Write to contact@arcproxies.io.
Is product data scraping the same as price scraping?
No. Price scraping tracks a few fields on known products frequently. Product data collection builds the catalogue itself: identifiers, attributes, variants, content and availability across whole assortments, refreshed when they change.
How should I store GTINs from different retailers?
As 14-digit strings, padded with leading zeros, which is what GS1 recommends. That makes an EAN-13 and the same code as GTIN-14 compare equal. Validate the check digit and keep the original string alongside the normalised one.
Why collect product data per country storefront?
Because assortment, titles, language, attributes and stock differ by country even for the same retailer. Collecting each storefront from an exit in its market records what customers there are offered.
Can I read variant data without a browser?
Often yes. Many storefronts publish schema.org ProductGroup markup that lists every variant with its GTIN and availability. Where variants are only loaded by script, request each variant's own URL or use a headless browser on a sticky session.
What does an EU product listing have to show?
Under the General Product Safety Regulation, applicable since 13 December 2024, online offers in the EU must show manufacturer name and contact, an EU responsible person where relevant, product identification including a picture, and warnings or safety information.
Sources & review
Last reviewed by the ARC Proxies team. Prices are read from the live catalog at build time.
- [1]GS1 US: An Introduction to the Global Trade Item Number (GTIN)
- [2]schema.org: ProductGroup
- [3]EUR-Lex: General product safety regulation (2023): summary
- [4]EUR-Lex: Regulation (EU) 2023/988 on general product safety
Web scraping
More on web scraping
Get started
Buy a gigabyte and try it on your own targets.
No subscription, no sales call. Code WELCOME15 takes 15% off your first purchase, and whatever you do not use is still there next quarter.