Etsy Scraper - Listings, Prices and Shops avatar

Etsy Scraper - Listings, Prices and Shops

Pricing

Pay per event

Go to Apify Store
Etsy Scraper - Listings, Prices and Shops

Etsy Scraper - Listings, Prices and Shops

Scrape Etsy category listings: item name, price, currency, availability, seller shop, image and URL. Reads the JSON-LD the category page publishes and pages through automatically.

Pricing

Pay per event

Rating

0.0

(0)

Developer

SR

SR

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

9 hours ago

Last modified

Share

Etsy Scraper

Scrape Etsy category listings: item title, price, currency, availability, the seller's shop name, image and listing URL. Point it at a category and it pages through automatically.

Etsy was on our "closed" list, and that was wrong

Worth saying because it may match your own experience. Etsy has a reputation for refusing scrapers, and a plain request often does get a 403.

eight consecutive fetches of a category page: seven returned about 1.07 MB carrying a clean JSON-LD ItemList of 56 to 62 listings. One returned a 777-byte 403.

That ratio is the whole story. Etsy refuses roughly one request in eight, and the refusal is not progressive, does not get worse with pacing, and clears on the next attempt because each retry leaves from a different IP. Retries are the mechanism here, not damage control. If you see fetch_failed, raise retries rather than concluding the site has closed.

Categories work; search and shops do not

This distinction was measured, six retries per surface, not assumed:

SurfaceResult
/c/jewelry200, 56 listings
/c/jewelry?page=2200, 61 listings
/search?q=leather+bag403 on all six attempts
/shop/<name>403 on all six attempts

A 403 that survives six rotating exits is a wall. A single 403 among eight successes is luck. They look identical in a log, which is exactly why the difference has to be measured rather than guessed.

So this Actor refuses a search or shop URL up front, with a message telling you why, instead of spending five retries discovering it for you.

What comes back

FieldWhat it is
listing_idEtsy's own id, from the URL. Stable, use it to join runs
nameListing title
shopThe seller's shop
price, currencyPrice as a number, plus its currency
availabilityInStock, OutOfStock and similar
rating, rating_countWhen the listing publishes them
imageListing image
urlListing page, tracking parameters stripped

A note on shop: Etsy publishes the seller in the schema.org brand field. Calling that "brand" in the output would imply a manufacturer, which is wrong for a handmade marketplace where the seller is the maker. It is returned as shop, under what it actually means.

A note on ratings: category ItemList entries frequently carry no rating at all. Those come back null rather than zero, because "not published" and "rated zero" are different facts and a zero would poison any average you compute.

Input reference

FieldTypeDefault
category_urlEtsy category pagehttps://www.etsy.com/c/jewelry
limit1-2000120
retries1-105

Pagination is Etsy's own ?page=N and stops when a page yields nothing.

Typical uses

  • Competitor and price research. A category run gives you the going rate for a product type across dozens of sellers in one go. One test run over three pages of jewellery returned 120 listings from 94 distinct shops.
  • Seller discovery. Group by shop to find who is active in a niche and how many listings each one is running.
  • Price positioning. Distribution of price within a category is the quickest read on where a new listing should sit.
  • Assortment monitoring. Schedule it and join on listing_id to watch prices and availability move.

Notes on behaviour

Pages are paced with a short randomised gap, which matters more here than on most sites: the refusal rate is per-IP, and burning through the pool quickly makes it worse for everyone sharing it.

A page that loads but carries no ItemList is reported as no_listings rather than returned as an empty result. A run that looks successful and quietly returns nothing is the failure mode worth being loud about.

Prices come from the US site in the currency Etsy shows there, which for most listings is USD but is set by the seller and is returned per row rather than assumed.

Finding a category URL

Etsy category URLs are https://www.etsy.com/c/<category>, optionally with sub-paths: /c/jewelry, /c/clothing, /c/home-and-living, /c/craft-supplies-and-tools, /c/jewelry/rings. Browse to the category in a browser and copy the address.

Facet parameters that appear in the URL as you filter (price bands, shipping options, colour) are passed through unchanged and paginated the same way, so filtering on Etsy first is usually cheaper than filtering the output afterwards: the facet is applied before pagination, so you spend fewer requests to get the rows you actually wanted.

What this Actor does not do

No search results. Covered above: 403 on every exit, six retries each. This is a hard wall rather than a rate limit, and the Actor refuses those URLs instead of pretending.

No shop pages. Same wall. If you need one seller's full catalogue, the practical route today is to run the categories they sell in and filter the output on shop.

No reviews or favourites. Those live on the listing page, which is a separate surface this Actor does not fetch. Category ItemList entries carry rating fields only sometimes, and they are returned when present.

No historical prices. Each run is a snapshot. listing_id is stable, so scheduling the Actor and joining snapshots on it gives you a price history.