# Etsy Product Listings & Shop Research Scraper (`nimbryxo-studio/etsy-product-listings-and-shop-research-scraper`) Actor

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.

- **URL**: https://apify.com/nimbryxo-studio/etsy-product-listings-and-shop-research-scraper.md
- **Developed by:** [Nimbryxo-studio](https://apify.com/nimbryxo-studio) (community)
- **Categories:** E-commerce, Automation, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.49 / 1,000 results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Etsy Product Listings & Shop Research Scraper

Pull product listings straight off Etsy — search results for any keyword, a category page, or a single seller's shop — without logging in. Point the actor at URLs or just type search terms, pick a regional market, and get structured rows with prices, ratings, seller badges, and (optionally) full listing detail pages.

### What this actor does

- Accepts Etsy search URLs, listing URLs, shop URLs, and category or market URLs, or plain keyword queries
- Returns price, original price, discount, rating, review count, and shop info for each listing card
- Detects Star Seller, Free Shipping, Bestseller, Etsy's Pick, and sponsored-ad badges on each card
- Optionally opens each listing page to add description, materials, tags, variations, and seller location/rating
- Runs keyword searches in one of ten Etsy regional markets so currency, language, and ranking match the selected country
- Numbers each row with its `position` in the collected result set and stamps a `scrapedAt` timestamp
- Card fields Etsy's page doesn't expose for a given listing (e.g. `shopId` on a shop page, or `originalPrice` on a full-price item) come back as an empty string rather than being left out of the record; detail fields from `includeDetails` are simply left off when missing

### Output per listing

- `listingId` — numeric Etsy listing ID
- `shopId` — numeric Etsy shop ID; usually empty outside search-result cards
- `url` — listing page URL
- `title` — listing title
- `price`, `originalPrice`, `currency`, `discountPercent` — pricing; `originalPrice`/`discountPercent` are empty strings except on sale items
- `imageUrl` — primary listing image
- `shopName`, `shopUrl` — seller shop name and URL
- `rating`, `reviewCount` — listing rating and review count; often empty on shop/category cards
- `badges` — object of true/false flags: `starSeller`, `freeShipping`, `bestseller`, `etsyChoice` (Etsy's Pick), `ad`
- `position` — the row's position in the collected result set for that URL/query
- `scrapedAt` — ISO 8601 timestamp of collection

#### Additional fields when `includeDetails` is enabled (and for listing URLs)

These are added only for listings whose page could be opened; if Etsy starts blocking listing pages, enrichment stops and the remaining rows keep just the card fields. A listing URL in `startUrls` always returns one row with these fields (badges are all `false` there, since they come from search cards).

- `description` — full listing description
- `category` — Etsy category breadcrumb
- `images` — array of all listing image URLs
- `variations` — array of selectable options (size, color, material, etc.)
- `materials` — materials text as listed by the seller
- `listedDate` — date the listing was posted
- `availability` — stock status
- `sellerName`, `sellerRating`, `sellerReviewCount`, `sellerLocation` — shop-level seller details
- `tags` — array of the listing's search tags

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `startUrls` | array | – | Etsy search, listing, shop, or category URLs to scrape |
| `searchQueries` | array | – | Keywords to search on Etsy; each query runs as a separate search |
| `maxItems` | integer | `100` | Maximum items to extract per URL or query (1–1,000) |
| `includeDetails` | boolean | `false` | Visit each listing page found on search, shop, or category pages for description, materials, variations, and seller detail |
| `country` | string | `US` | Target Etsy market (`US`, `DE`, `GB`, `FR`, `AU`, `CA`, `IT`, `ES`, `NL`, `JP`). Keyword searches run on that market's site; URLs in `startUrls` keep the market they point to |

At least one of `startUrls` or `searchQueries` must be provided.

#### Example: keyword search in the default US market

```json
{
  "searchQueries": ["handmade jewelry"],
  "maxItems": 50
}
```

#### Example: a shop's catalog with details

```json
{
  "startUrls": [{ "url": "https://www.etsy.com/shop/GlassHouseDesignsUS" }],
  "maxItems": 200,
  "includeDetails": true
}
```

#### Example: category search targeting the UK market

```json
{
  "startUrls": [{ "url": "https://www.etsy.com/c/jewelry-and-accessories" }],
  "country": "GB",
  "maxItems": 100
}
```

#### Example: multiple keyword queries across stores

```json
{
  "searchQueries": ["personalized gifts", "wedding favors", "vintage rings"],
  "maxItems": 30
}
```

### Use cases

- **Product research** — survey pricing, discounts, and bestseller badges for a niche before listing a competing product
- **Market monitoring** — track a shop's catalog and prices over time across multiple regional markets
- **Trend discovery** — run broad keyword searches to see which styles and materials are trending
- **Competitor analysis** — pull a competitor shop's listings with descriptions, materials, and tags
- **Price comparison tools** — feed listing prices and currencies into a comparison or alert service

### FAQ

**Does this need an Etsy account or API key?**
No. It scrapes publicly visible listing pages and requires no login or API credentials.

**What's the difference between search results and shop/category pages?**
All three return the same listing fields. Search results additionally expose `rating`, `reviewCount`, and sponsored-ad badges that aren't always present on shop or category cards.

**How do I get more than one page of results?**
Raise `maxItems` beyond a single search page. The actor follows further result pages, and for keyword searches it can also add listings from other sort orders (newest, price, top-reviewed) and price bands to reach your target, so later rows aren't strictly in relevance order. Duplicates are removed by listing ID.

**Why are `originalPrice` and `discountPercent` missing on most listings?**
Those fields are only populated for listings currently on sale. Full-price items omit them.

**What does `includeDetails` add?**
It visits each listing's own page to add description, category, images, materials, tags, variations, listing date, availability, and seller-level name/rating/location — fields that search, shop, and category cards don't expose. It makes runs slower, and if Etsy blocks listing pages partway through, later rows come back without these fields.

**Can I target a market other than the US?**
Yes, set `country` to any of the ten supported markets for keyword searches; it changes the currency, site language, and which listings rank first. For pasted URLs, use the market-specific URL itself (for example `https://www.etsy.com/de/search?q=...`).

**Can I scrape a single product page directly?**
Yes — put the listing URL in `startUrls`. You get one row with the detail fields for that listing whether or not `includeDetails` is on.

**Is this affiliated with Etsy?**
No. This is an independent, third-party actor that reads Etsy's public pages; it isn't affiliated with or endorsed by Etsy, Inc.

# Actor input Schema

## `startUrls` (type: `array`):

Etsy URLs to scrape. Supports search results, shop pages, and category pages.

## `searchQueries` (type: `array`):

Keywords to search on Etsy. Each query generates a separate search.

## `maxItems` (type: `integer`):

Maximum number of items to extract per URL or search query.

## `includeDetails` (type: `boolean`):

When enabled, attempts to visit each product page for additional details. Note: Etsy's anti-bot may block product page access in some sessions.

## `country` (type: `string`):

Target Etsy market. Sets the proxy exit country, browser locale, and search URL prefix so results match the selected region (currency, ranking, availability).

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://www.etsy.com/search?q=handmade+jewelry"
    }
  ],
  "maxItems": 10,
  "includeDetails": false,
  "country": "US"
}
```

# Actor output Schema

## `listings` (type: `string`):

Dataset containing all scraped Etsy product listings

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "startUrls": [
        {
            "url": "https://www.etsy.com/search?q=handmade+jewelry"
        }
    ],
    "maxItems": 10,
    "country": "US"
};

// Run the Actor and wait for it to finish
const run = await client.actor("nimbryxo-studio/etsy-product-listings-and-shop-research-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "startUrls": [{ "url": "https://www.etsy.com/search?q=handmade+jewelry" }],
    "maxItems": 10,
    "country": "US",
}

# Run the Actor and wait for it to finish
run = client.actor("nimbryxo-studio/etsy-product-listings-and-shop-research-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "startUrls": [
    {
      "url": "https://www.etsy.com/search?q=handmade+jewelry"
    }
  ],
  "maxItems": 10,
  "country": "US"
}' |
apify call nimbryxo-studio/etsy-product-listings-and-shop-research-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,nimbryxo-studio/etsy-product-listings-and-shop-research-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/B47SmyQ83rDLAqzH1/builds/nf4WIUM4xHKuS4NRS/openapi.json
