DEV Community

publicrecords
publicrecords

Posted on Edited on

Find bestselling Etsy listings in a niche: 10 rows for $0.04

Disclosure: I maintain these Actors on Apify Store (publicrecords).

Etsy sellers and product researchers keep asking how to export Etsy search results for a niche and see which listings are already marked Bestseller. Today's walkthrough does that with Etsy Search Scraper — a different path from sorting by price.

Price (matches the live listing)

Pay-per-event on Apify Store:

  • Actor start: $0.00005
  • Listing row: $0.004 per delivered listing (free plan; lower on paid plans, down to $0.0034)
  • 10 rows: $0.00005 + 10 × $0.004 = $0.04005 (about $0.04)

Prices as of Oct 27, 2026 — see the Store pricing page.

Blocked pages are not charged.

Paste-ready input (bestsellers in a niche)

{
  "queries": ["personalized dog collar"],
  "sort": "relevance",
  "is_best_seller": true,
  "maxItems": 10,
  "maxPages": 1,
  "fillLazyCards": true,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": ["RESIDENTIAL"],
    "apifyProxyCountry": "US"
  }
}
Enter fullscreen mode Exit fullscreen mode

Swap the keyword for your niche. is_best_seller: true keeps only listings Etsy marks Bestseller.

Run it

  1. Open the Actor: publicrecords/etsy-search-scraper
  2. Paste the JSON into Input → Start
  3. Download the dataset (CSV/JSON)

Or from the CLI:

apify call publicrecords/etsy-search-scraper --input '{
  "queries": ["personalized dog collar"],
  "sort": "relevance",
  "is_best_seller": true,
  "maxItems": 10,
  "maxPages": 1,
  "fillLazyCards": true,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": ["RESIDENTIAL"],
    "apifyProxyCountry": "US"
  }
}'
Enter fullscreen mode Exit fullscreen mode

curl (replace $APIFY_TOKEN):

curl -sS -X POST "https://api.apify.com/v2/acts/publicrecords~etsy-search-scraper/runs?token=$APIFY_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{
    "queries": ["personalized dog collar"],
    "sort": "relevance",
    "is_best_seller": true,
    "maxItems": 10,
    "maxPages": 1,
    "fillLazyCards": true,
    "proxyConfiguration": {
      "useApifyProxy": true,
      "apifyProxyGroups": ["RESIDENTIAL"],
      "apifyProxyCountry": "US"
    }
  }'
Enter fullscreen mode Exit fullscreen mode

What you get

Each row is a live search listing: id, title, price, rating, reviews, badges (including Bestseller), shop, and rank in Etsy's order for that query.

Example repo for the price-sort path: GeminiGeorge22/etsy-search-example.

Again: disclosure — I maintain publicrecords/etsy-search-scraper on Apify Store.

Top comments (2)

Collapse
 
yuhehe profile image
Yuhe He •

Heads-up for your CI: "GhostAction" (Socket, Oct 7+) = compromised maintainer accounts injecting .github/workflows/security-audit.yml, harvesting secrets from full git history, POSTing cleartext to 193.32.204.199. Deleting a secret from HEAD proves nothing. Full 5-step self-audit brief (defanged IOCs): on request — free.

Collapse
 
yuhehe profile image
Yuhe He •

The $0.065 framing is the most useful sentence in scraping content: price the row, not the tool. Our Telegram snapshot pipeline does the same math per channel-day, and the honest number includes the rows that cost nothing to fetch and everything to trust - a channel's shop-card view count drifts +100k/week when a clone ring starts, so the cheap fetch is exactly where the expensive lie lives. Budget row-level freshness by claim-risk: rows that back a purchase decision need a timestamped series, rows that fill a chart can be one-shot. The unit price of data is the unit price of believing it.