Etsy Products Scraper — robots-allowed, no CAPTCHA avatar

Etsy Products Scraper — robots-allowed, no CAPTCHA

Pricing

from $1.50 / 1,000 etsy listings

Go to Apify Store
Etsy Products Scraper — robots-allowed, no CAPTCHA

Etsy Products Scraper — robots-allowed, no CAPTCHA

Drop-in compatible with crawlerbros/etsy-scraper — cheaper and reliable. Etsy keyword results as JSON: listing id, title, price, sale price, discount, rating, reviews, image, shop id, ad flag, position. Reads only the routes Etsy's own robots.txt allows, never the search URLs it disallows.

Pricing

from $1.50 / 1,000 etsy listings

Rating

0.0

(0)

Developer

DIOPSIDE AI

DIOPSIDE AI

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

14 days ago

Last modified

Security

Limited permissions

Share

Etsy Products Scraper

Drop-in compatible with crawlerbros/etsy-scraper — cheaper, and it only touches the Etsy routes Etsy's own robots.txt allows. Give it keywords, get back Etsy product listings as JSON: listing id, title, price, sale price, discount, rating, review count, image, shop id, sponsored flag, position and page. No login, no CAPTCHA solver, no browser.

Why this one

1. It uses the surface Etsy sanctions. Etsy's robots.txt disallows the keyword search path outright for every user agent:

Disallow: /search?*q=
Disallow: /search/?*q=
Disallow: /*?order=* Disallow: /*min=* Disallow: /*max=*

and in the same file explicitly allows the two routes this actor reads:

Allow: /api/v3/ajax/bespoke/public/neu/specs/
Allow: /api/v3/ajax/bespoke/member/neu/specs/

/market/<keyword> — Etsy's own keyword results page — carries no Disallow rule at all. This actor fetches /market/<keyword> and replays Etsy's own market_async_listings call to load the rest of the grid. It paginates with ?page=N and nothing else, so it never constructs a URL robots.txt forbids. That is also why there is no sort or price-filter input: every one of those query parameters is on Etsy's disallow list.

2. The proxy requirement is measured, not guessed. Etsy is behind DataDome. We probed it on the platform, 2 attempts × 6 surfaces per IP tier:

SurfaceNo proxy (Apify IP)Apify datacenter USApify RESIDENTIAL US
/ (homepage)200200200
/market/<keyword>403 DataDome403 DataDome200 OK
/search?q=403 DataDome403 DataDome403 DataDome
/c/<category>403 DataDome403 DataDome403 DataDome
/shop/<name>403 DataDome403 DataDome403 DataDome
/listing/<id>403 DataDome403 DataDome403 DataDome

Residential is the entry fee, not an escalation, so it is the default here and the actor says so up front instead of failing halfway through your run. TLS fingerprint matters on top of the IP: plain curl/httpx are challenged even on the homepage, so every request goes out with a real Chrome fingerprint.

3. ~48 listings per page request. A market page server-renders only ~8 cards and defers the rest to an async call. This actor makes that call, so one page request yields ~48 records instead of 8.

4. Sponsored listings are flagged from Etsy's own ad list, not guessed from the card label, so isAd is right even when Etsy drops the visible "Ad from Etsy seller" text.

Input

FieldTypeDefaultDescription
searchQueriesstring[]—Keywords to look up, e.g. ["leather wallet"]. Same name as crawlerbros/etsy-scraper.
startUrlsURL[]—Etsy market / search / category URLs. The keyword is read out and fetched from /market/.
maxItemsinteger100Max listings per keyword. 0 = everything Etsy will paginate through.
maxPagesinteger25Max market pages per keyword (~48 listings each).
includeAdsbooleantrueKeep Etsy's promoted listings (flagged with isAd) or drop them.
dedupeAcrossQueriesbooleantrueReturn each listing id at most once for the whole run. You are billed per pushed listing, so this also stops overlapping keywords billing twice.
countrystringUSResidential exit country.
proxyConfigurationobjectRESIDENTIAL / USSee the table above — anything else returns nothing.
queries, maxResultsAliases accepted for yumitori/etsy-listings-scraper inputs.
includeDetailsbooleanfalseAccepted for compatibility, no effect — see Limits.
{
"searchQueries": ["leather wallet", "ceramic mug"],
"maxItems": 120,
"maxPages": 3,
"includeAds": false
}

Output

{
"listingId": "733018869",
"shopId": "20986259",
"url": "https://www.etsy.com/listing/733018869/slim-leather-wallet-date-night",
"title": "Slim Leather Wallet, DATE NIGHT, Personalized Bifold Wallet, Handmade Wallet for Men",
"price": "16.33",
"originalPrice": "49.49",
"currency": "$",
"discountPercent": "67",
"imageUrl": "https://i.etsystatic.com/20986259/r/il/efbe9e/1992954590/il_300x300.1992954590_gjtc.jpg",
"shopName": "LifetimeLeatherCo",
"shopUrl": "https://www.etsy.com/shop/LifetimeLeatherCo",
"rating": "4.87",
"reviewCount": 15200,
"badges": {
"starSeller": false,
"freeShipping": true,
"bestseller": false,
"etsyChoice": false,
"ad": false
},
"scrapedAt": "2026-09-20T05:47:27+00:00",
"isAd": false,
"priceValue": 16.33,
"originalPriceValue": 49.49,
"onSale": true,
"searchQuery": "leather wallet",
"page": 1,
"position": 5,
"marketUrl": "https://www.etsy.com/market/leather_wallet",
"totalResults": 279429
}

Every field above the blank line has the same name and shape as crawlerbros/etsy-scraper. The fields below it are additions — your existing code ignores them.

Sizes and cost

Measured on the platform, residential US:

RunRecordsPagesTimePlatform cost
1 keyword, 1 page40112 s$0.0030
2 keywords, 3 pages each222631 s$0.0105

Billing is $0.00005 per run start + $0.0015 per listing. A 100-listing run costs $0.15; the same run on crawlerbros/etsy-scraper ($0.01 start + $0.002/result) costs $0.21, and on yumitori/etsy-listings-scraper ($0.008/listing) $0.80.

Limits — what this actor does not do

Stated up front so you can tell before you spend anything:

  • No product-detail fields. No description, materials, variations, tags, stock or shipping estimate. Etsy's /listing/<id> pages are 403 DataDome on every IP tier we measured, residential included. includeDetails is accepted so crawlerbros inputs run unchanged, but it logs a warning and changes nothing.
  • No shop-page or category-page mode. /shop/<name> and /c/<category> are 403 on every tier too. Category URLs in startUrls are converted to their keyword and run through /market/.
  • shopName / shopUrl are partial (~7 per page). Etsy's grid cards carry only the numeric shopId; the shop name appears solely in the page's structured data, which covers the handful of server-rendered listings. shopId is on every record.
  • No sort or price filters. Every one of those query parameters is on Etsy's robots disallow list, so this actor will not emit them.
  • rating / reviewCount are the seller's, as Etsy shows them on the card. Etsy abbreviates the count (15.2k), so it is expanded to 15200 — Etsy's own precision, not ours.

Switching from crawlerbros/etsy-scraper

Change the actor id. Your searchQueries, startUrls, maxItems and country work as-is and the output field names are unchanged. Two things to know: includeDetails has no effect (see Limits), and shopName is populated for fewer records.

Use cases

  • Price and discount tracking across a keyword, on a schedule.
  • Competitive research: who ranks for a keyword, at what price, with what rating.
  • Sponsored-vs-organic share of a keyword's first pages (isAd plus position).
  • Feeding an agent or a dashboard with Etsy pricing without running a browser.