Etsy Product Listings & Shop Research Scraper
Pricing
from $0.49 / 1,000 results
Etsy Product Listings & Shop Research Scraper
Collect Etsy product listings from keyword searches, category pages, and individual shops, with prices, ratings, seller badges, and optional full product detail across ten regional markets.
Pricing
from $0.49 / 1,000 results
Rating
0.0
(0)
Developer
Nimbryxo-studio
Maintained by CommunityActor stats
0
Bookmarked
3
Total users
2
Monthly active users
14 days ago
Last modified
Categories
Features
Share
Collect Etsy listing data from Etsy's keyword market pages without a login, API key, or proxy setup. Give the actor a keyword or a market URL, choose one of ten regional markets, and get structured rows for pricing research, assortment tracking, and shop comparisons.
How it works
Etsy's keyword market pages (https://www.etsy.com/market/<slug>) are the most reliable public route. The actor converts every search query into that route, reads the page's JSON-LD ItemList and listing cards, and follows pages until it reaches your limit or the source ends. When Etsy redirects a keyword to a category page, the actor follows the redirect with a fresh request instead of treating the redirect as a dead end.
Category URLs such as https://www.etsy.com/c/jewelry are also supported directly and normally expose about 64 cards per page. Legacy /search?q= URLs are converted to the equivalent market URL. Shop and individual listing URLs are accepted for backward compatibility, but Etsy protects those with DataDome; the actor reports them as blocked instead of returning an empty result.
What you get per listing
Card-level fields:
listingId- numeric Etsy listing IDurl- listing page URLtitle- listing titleprice,originalPrice- plain decimal strings (no thousands separators)priceValue,originalPriceValue- numeric values for calculationscurrency- Etsy's display label or symbol (USD,EUR,GBP,JPY,AU$,CA$)currencyCode- ISO 4217 code (USD,EUR,GBP,JPY,AUD,CAD, ...)discountPercent- discount as a string, kept for compatibilitydiscountPercentValue- discount as an integer percentageimageUrl- primary card imageimageCount- number of images exposed in the card (usually 1)shopId- Etsy shop ID when the card exposes itshopName,shopUrl- shop name and URL (from the page's brand data or shop link)rating,reviewCount- shop-level rating and review count when the card shows themshopRating,shopReviewCount- numeric shop-level copies of the same valuesratingScope-shopwhen the supplied rating is shop-levellistingRating,listingReviewCount- listing-level rating only when the page's structured data suppliesaggregateRating(usually it does not)availability- stock status from the page's structured databadges- compatibility object withstarSeller,freeShipping,bestseller,etsyChoice,adisAd- present andtruefor sponsored cards (omitted for organic cards)freeShipping,starSeller,bestseller,etsyChoice- present andtruewhen the badge is visiblehasVariations- present andtruewhen variations are visiblepage- source market or category page numberposition- row position within the task's collected resultssourceQuery- keyword or slug that produced the rowsourceUrl- exact market or category page URL the row came fromrecordType-listingfor card recordsscrapedAt- ISO 8601 collection timestamp
Fields the page does not expose are omitted rather than emitted as empty strings, nulls, or placeholders. isAd, badge flags, and hasVariations are only present when true; absence means the page did not show that signal. rating is a shop-level rating on market cards, which is why ratingScope is shop.
When includeDetails is enabled
The actor attempts to open each listing page and add:
description,category,materials,listedDate,availabilityimages- all listing image URLsvariations- selectable optionstags- listing tagssellerName,sellerRating,sellerReviewCount,sellerLocationlistingRating,listingReviewCount- listing-level rating when the listing page supplies itdetailsStatus-enriched,blocked,not_found,partial, orno_url
Etsy frequently blocks listing pages with DataDome. When that happens, the row keeps its card data, detailsStatus is blocked, and no detail fields are invented. A circuit breaker stops detail attempts after three consecutive blocks so a site-wide block cannot stall the run.
Input
At least one of startUrls or searchQueries is required for a normal run. A truly empty input uses the documented handmade jewelry fallback for the scheduled test. Apify's validator cannot express "one of", so the actor enforces it.
| Field | Type | Default | Description |
|---|---|---|---|
startUrls | array | - | Etsy market URLs are reliable; /c/ category URLs work and return more cards per page. Legacy /search?q= URLs are converted to market URLs. Shop URLs use the 10-item public RSS feed; listing URLs are reported as blocked. |
searchQueries | array | - | Keywords mapped to Etsy market pages, with automatic category follow when Etsy redirects. Each query is a separate task. |
maxItems | integer | 100 | Maximum rows per URL or query (1-1,000). Keyword markets cap at 25 pages; categories can go deeper. |
includeDetails | boolean | false | Attempt listing-page enrichment and report detailsStatus honestly. |
sortBy | select | any | most_relevant, price_asc, price_desc, date_desc, highest_reviews. |
minPrice | number | - | Lower price bound in the market currency. Etsy min is used server-side and a local safeguard follows. |
maxPrice | number | - | Upper price bound in the market currency. |
freeShippingOnly | boolean | false | Use Etsy's free_shipping=1 market filter. |
starSellerOnly | boolean | false | Use Etsy's is_star_seller=1 market filter. |
country | string | US | Market locale: US, DE, GB, FR, AU, CA, IT, ES, NL, JP. |
If no input is supplied, the actor uses handmade jewelry as a safe fallback so a scheduled test run still produces data. At least one of startUrls or searchQueries is normally provided.
Examples
Keyword search in the default US market:
{"searchQueries": ["handmade jewelry"],"maxItems": 50}
Multi-page collection in Germany:
{"searchQueries": ["keramik tasse"],"country": "DE","maxItems": 120}
Direct market URL:
{"startUrls": [{ "url": "https://www.etsy.com/uk/market/wedding_ring" }],"maxItems": 80}
Category URL with 64 cards per page:
{"startUrls": [{ "url": "https://www.etsy.com/c/jewelry/necklaces" }],"maxItems": 200}
Details requested, with honest fallback:
{"searchQueries": ["personalized necklace"],"includeDetails": true,"maxItems": 20}
Pagination, deduplication, and limits
- Pages are followed until
maxItemsis reached, no new listing IDs appear for two consecutive pages, or Etsy's explicitmax_page_exceededmarker is hit. - A short page is not treated as the end. Etsy market pages normally show about eight cards, and category pages about 64; the old "fewer than 64 cards means stop" shortcut would have stopped after page one.
- Rows are deduplicated by listing ID across pages and across tasks; sponsored cards can repeat.
- Etsy serves at most 25 market pages per query (roughly 200 listings). Larger
maxItemsvalues return what exists and set a partial status message instead of pretending the request was complete. - Category pages can be deeper, but DataDome may rate-limit very deep or rapid page walks. The actor retries, then reports a partial result with the reason.
- Some keywords have no market page, return 404, or redirect to a category page. The actor tries alternate slug spellings, follows a working category redirect, and reports the specific reason for any task that still fails.
FAQ
Do I need an Etsy account, API key, or proxy? No. The actor reads public market pages and works without credentials or proxy configuration. It chooses its proxy automatically and only after a direct request is blocked.
Why do I sometimes get fewer rows than maxItems?
Etsy's market route exposes up to 25 pages per query. The actor reports the ceiling and returns the available rows. Shop RSS is limited to 10 recent items. Category pages can go deeper but may rate-limit.
Which filters and sorts work?
sortBy, freeShippingOnly, starSellerOnly, minPrice and maxPrice are supported. Sorting and the two badges are server-side; price bounds use Etsy's min/max parameters and a local safeguard. Views, favorites, carts and bought-in-last-24h are not present on market/category pages; listing pages expose some of them only through a browser, so they are not shipped.
What happens with shop and listing URLs?
Shop URLs use Etsy's public shop RSS feed, which returns the 10 most recent listings with title, description, image and price. It is honest about being a recent-items feed and does not paginate. Listing detail pages remain DataDome-blocked for plain HTTP; browser/proxy enrichment is not used in production because it is slow and unreliable. Keyword market pages and /c/ category pages are the reliable bulk routes.
Why is ratingScope set to shop?
The rating shown on an Etsy listing card is the shop's aggregate rating. This was verified by finding the same shop's separate listings carrying an identical rating and review count. Listing-level ratings are only claimed through listingRating when structured data on the page supplies them, or through includeDetails when the listing page is readable.
Why are some shop names or ratings missing? Etsy's card markup does not always expose a shop name or rating. The actor fills them from the page's JSON-LD brand and visible rating controls, and omits them when the page genuinely does not show them. Missing fields are never replaced with placeholders.
Are prices strings or numbers?
Both are provided. price and originalPrice remain decimal strings for backward compatibility; priceValue and originalPriceValue are numeric for calculations.
Why do output listing/shop URLs return 403? Etsy's DataDome protection blocks clean clients even for URLs the actor collected from public market/RSS pages. The URLs are valid for a browser; this is an Etsy anti-bot caveat, not a broken URL. Image URLs were verified HTTP 200.
Is this affiliated with Etsy? No. This is an independent third-party actor that reads publicly visible pages and is not affiliated with or endorsed by Etsy, Inc.