Etsy Listings Scraper - Price, Shop & Badges
Pricing
from $1.50 / 1,000 results
Etsy Listings Scraper - Price, Shop & Badges
Scrape Etsy search results into structured rows: listing ID and URL, title, numeric price with its currency code, shop name, shop rating and review count, Bestseller and free-shipping flags, and the card image. Feed it search terms, get up to 240 listings per term. No Etsy account or API key.
Pricing
from $1.50 / 1,000 results
Rating
0.0
(0)
Developer
String
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
0
Monthly active users
15 days ago
Last modified
Categories
Share
What does the Etsy Listings Scraper do?
It turns Etsy search results into rows. Give it the phrase you would type into Etsy's own search
box, such as handmade jewelry, and every listing in that grid comes back as a record: Etsy's
listing ID and URL, the title, the price as a number, the shop behind it, and the badges the card
carries. Export it as JSON, CSV or Excel, or read it straight from the dataset API.
The Actor reads public search pages the way a logged-out visitor sees them. No Etsy account, no API key, no cookie jar to keep alive.
pricearrives as24.99with the currency code in its own column, so it sorts and averages without any string cleanuplistingIdis Etsy's own identifier, which makes de-duplication and joins across runs trivial- Up to 240 listings per search term: Etsy server-renders 12 per page and stops serving fresh results after its twentieth page
- The Bestseller badge and the free-shipping promise are booleans, not scraped label text
- A search page that cannot be read is written into the run's
SUMMARYas a failure instead of quietly shrinking the dataset
What data does it extract?
| Field | Type | Description |
|---|---|---|
listingId | string | Etsy's listing ID. Stable across runs, so use it as your key |
title | string | The listing title as it appears on the card |
price | number | Numeric price, e.g. 24.99 |
currency | string | ISO code Etsy priced the page in, e.g. USD |
shopName | string | The shop's Etsy handle |
shopRating | number | The shop's rating out of 5, e.g. 4.8 |
shopReviewCount | number | Review count for the shop, e.g. 12400 |
isBestseller | boolean | true when the card shows Etsy's Bestseller badge |
freeShipping | boolean | true when the card advertises free shipping |
imageUrl | string | The listing's card image |
listingUrl | string | Direct link to the listing on Etsy |
searchTerm | string | The term that produced this row |
sourceUrl | string | The Etsy search page the row was read from |
collectedAt | string | ISO timestamp, set once per run |
Two notes on the shop columns. shopRating and shopReviewCount describe the shop, not the
individual listing, because a shop-level score is what an Etsy search card publishes. And Etsy
abbreviates a large review count on the card as "12.4k", which the Actor expands to 12400: counts
below a thousand are exact, and above that you get the precision the card printed. Anything the card
omits comes back as null rather than an empty string.
Why scrape Etsy?
- Price a niche before you list in it. Pull 240 listings for the phrase you plan to sell under and you have the real distribution of asking prices, not the handful Etsy chose to show you first.
- Watch competitors on numbers.
priceis numeric andlistingIdis stable, so re-running the same terms weekly gives you a price history per listing with no fuzzy matching. - Track who holds the Bestseller badge. The badge moves.
isBestsellerover time tells you which listings are gaining traction in a category and which are fading. - Find shops worth studying. Filter on
shopRatingandshopReviewCountto pick out the established sellers in a niche, then look at what they charge and how they title their listings. - Check whether free shipping is table stakes. In some categories almost every card offers it and in others almost none do, which changes how you price.
- Feed a dashboard. Schedule the Actor, point a BI tool at the dataset, and keep a keyword-to-price map current without touching it again.
How to use it
- Open the Actor and click Try for free.
- Put your search terms into Search terms, one per line. These are ordinary Etsy search phrases; 1 to 50 of them per run.
- Set Maximum results to the number of rows you want. This also decides how deep each term is paged, so a larger number means more pages per term rather than just a bigger slice of page one.
- Leave Concurrency alone unless you have a reason to change it. The default fetches five targets at a time.
- Click Start. Watch the log if you like; it names every target that failed.
- When the run finishes, open the Storage tab and export the dataset as CSV, JSON or Excel, or pull it over the API with the snippet further down.
- To build a time series, put the run on a Schedule and key later joins on
listingId.
Input
| Field | Type | Default | Description |
|---|---|---|---|
searches | string[] | required | Etsy search terms, 1 to 50 per run. Duplicates collapse to one fetch |
maxItems | integer | 1000 | Cap on dataset rows, 1 to 50000. Also sets paging depth per term |
concurrency | integer | 5 | Targets fetched in parallel, 1 to 10 |
{"searches": ["handmade jewelry", "leather wallet", "ceramic mug"],"maxItems": 720,"concurrency": 5}
maxItems is split evenly across your search terms and rounded up to whole pages of 12, capped at
Etsy's own twentieth page. The example above budgets 240 rows per term, which is 20 pages each, the
deepest Etsy will go. Ask for fewer rows and each term is paged more shallowly rather than some terms
being dropped, so every phrase you supply is represented in the output.
Output
One row per listing. This is the shape, with plausible values rather than a captured run:
{"listingId": "1482930571","title": "Personalized Birth Flower Necklace, Gold Filled Custom Gift for Her","price": 34.5,"currency": "USD","shopName": "MeadowAndOakStudio","shopRating": 4.9,"shopReviewCount": 12400,"isBestseller": true,"freeShipping": true,"imageUrl": "https://i.etsystatic.com/48210933/r/il/9c1f7a/6284915073/il_340x270.6284915073_k8vq.jpg","listingUrl": "https://www.etsy.com/listing/1482930571/personalized-birth-flower-necklace-gold","searchTerm": "handmade jewelry","sourceUrl": "https://www.etsy.com/search?q=handmade+jewelry&page=3","collectedAt": "2026-08-19T09:14:02.771Z"}
The run also writes a SUMMARY record to the key-value store with the item count, the failure count
and every target that failed with its error message.
Reliability and limitations
Listings are read from Etsy's server-rendered search grid rather than from the ld+json block on the
same page. That block looks like the obvious source and is not: it is a promotional subset, usually
six of the twelve rendered cards, and it drops the rating, the review count, the badges and shipping
entirely. Each card's markup is isolated before any field is read, so the "Free shipping" option in
the filter sidebar is never mistaken for a shipping promise on a listing that makes none.
Etsy also runs two card renderers at once and a session lands in either. They agree on everything but
the rating, which one publishes as attributes on a web component and the other folds into an
aria-label sentence. Both are handled, so the rating does not depend on which renderer you drew.
Measured yield is 11.67 listings per request after de-duplication, against the 12 a page renders. Promoted listings repeat inside a grid and across a term's pages; those are removed. The same listing found under two different search terms is returned once per term, because that is a row you asked for twice.
Search results only. There are no listing detail pages, so no description, variations, materials,
stock level, processing time or per-listing reviews, and no shop pages. Etsy prices a page in the
currency it infers for the viewer, so currency reports what it chose rather than a currency you can
select.
There are no retries, deliberately. The String Unblocker owns proxy rotation and anti-bot solver selection, so a retry loop here would only re-roll the same block.
How much does it cost?
The Actor uses Apify's pay-per-event pricing and charges once per result row written to the dataset. Rows are what you pay for, not run time, memory or the number of pages it had to fetch to find them. A run that returns nothing charges nothing. The current per-result price is on this Actor's pricing tab, above.
Because charging happens on the push, a spend limit on your account trims the write rather than overrunning it: a row that could not be charged for is never written.
Runs started from an Apify free plan stop at 250 requests and 250 results, and the run reports
that it reached the limit. Any paid plan runs the full input and whatever maxItems you set. The
limit exists because this Actor fetches through our own infrastructure, which Apify does not cover
for free-plan runs, and it binds on requests as well as rows so a large input cannot spend those
fetches on rows the run will not return.
Using it with the Apify API
import { ApifyClient } from "apify-client";const client = new ApifyClient({ token: "YOUR_APIFY_TOKEN" });const run = await client.actor("usestring/etsy-listings").call({searches: ["handmade jewelry", "leather wallet"],maxItems: 480});const { items } = await client.dataset(run.defaultDatasetId).listItems();console.log(items.length, items[0]);
The same call works from the Python client, and any language can hit the
Apify REST API directly. To read the failure list, fetch the
SUMMARY record from the run's key-value store.
Is it legal to scrape Etsy?
This Actor reads pages that Etsy serves to anyone, with no login and no paywall in the way. It does not sign in, does not touch buyer accounts, order history or messages, and does not collect personal data beyond the shop handle that Etsy itself prints on a public search card.
Scraping public data is broadly lawful in the US and the EU, and courts have repeatedly said so, but what you then do with the data is a separate question governed by copyright, database rights and privacy law. Listing photos and titles belong to the sellers who wrote them. If you plan to republish, retrain on, or otherwise redistribute what you collect, talk to a lawyer first. Nothing here is legal advice.
Related actors
- Amazon Search Scraper for the same keyword-to-results shape on Amazon
- Amazon Product Scraper when you have ASINs and want detail rather than search cards
- Walmart Product Scraper for a second US marketplace to price against
- Home Depot Product Scraper for home and craft supply pricing
- Fiverr Gig Scraper if you are researching handmade services rather than handmade goods
FAQ
How many listings do I get per search term? 240 at most. Etsy server-renders 12 listings per search page, and past its twentieth page it silently re-serves page 1, so the Actor stops there rather than collecting duplicates. Use narrower terms, or more of them, to cover a category more deeply.
Can I scrape one shop, or a single listing page? No. This Actor works from search terms and reads search results only. It does not open listing detail pages or shop pages, so descriptions, variations, stock levels and per-listing reviews are out of scope.
Which currency are the prices in?
Whichever one Etsy picked for the page, reported per row in currency. There is no country input:
Etsy infers a currency for the viewer and prices the whole grid in it. Prices are never converted, so
compare within a currency or convert them yourself downstream.
How fresh is the data?
It is read live when the run starts. Nothing is cached or replayed from an earlier run, and
collectedAt records the moment the run began. For a time series, schedule the Actor and join on
listingId.
What happens when Etsy blocks a page?
That page is recorded under failures in the run's SUMMARY with its URL and error, and the run
continues with the rest. If every page failed, the run exits with an error rather than reporting a
successful run that produced nothing. The Actor never retries: the String Unblocker behind it already
handles proxy rotation and solver selection, so retrying out here would just re-roll the same block.
Do I need an Etsy account, API key or proxies of my own? None of the three. The Actor reads logged-out search pages and brings its own fetching infrastructure, so there is no Apify proxy configuration to set up either.
Feedback
Found a field parsed wrong, a badge missing, or a search term that consistently fails? Open an issue from this Actor's Issues tab on the Store page and include the input you ran. Requests for extra fields are welcome there too.