# Etsy Scraper (`ef12/etsy-scraper`) Actor

Scrape Etsy product listings by search query or shop URL. Get titles, prices, images, sellers, ratings, review counts, tags, and shipping info.

- **URL**: https://apify.com/ef12/etsy-scraper.md
- **Developed by:** [Daniel Wilson](https://apify.com/ef12) (community)
- **Categories:** E-commerce
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).


# README

## Etsy Scraper — Product & Shop Listings

Extract product listings from **Etsy search results** and **shop pages** at scale. Get structured data — titles, prices, ratings, reviews, seller info, tags, images, and more — delivered as a clean JSON dataset you can download as CSV, Excel, JSON, or HTML.

Powered by **Crawlee** and **BeautifulSoup** for fast, efficient static HTML parsing. Runs on **Apify** — no infra to manage, built-in proxy rotation, scheduling, and webhook integrations.

### Why use Etsy Scraper?

- **Market research** — Track pricing trends, popular products, and bestseller badges across categories
- **Competitor monitoring** — Watch specific shops for new listings, price changes, and inventory
- **Product catalog building** — Build a searchable database of Etsy products with structured metadata
- **Price comparison** — Compare prices across sellers for identical or similar products
- **SEO & keyword analysis** — Extract listing tags to understand how top sellers optimize their products
- **Data enrichment** — Augment your own datasets with real-time Etsy product information

### How to use Etsy Scraper

1. **Set up locally** — Clone this repo and install dependencies: `pip install -r requirements.txt`
2. **Run a search** — Create a test input file with `search_query` set to what you want to find, then run `apify run --input-file=test-input.json`
3. **Scrape a shop** — Provide a `shop_url` like `https://www.etsy.com/shop/ShopName` instead of a search query
4. **Adjust the limits** — Set `max_results` to cap output (default 25, max 200). First 10 results are free per run; subsequent results use PPE billing at $0.004/result
5. **Sort the results** — Choose from relevance, newest, price ascending/descending, or best selling
6. **Filter by price** — Set `min_price` and `max_price` to narrow results
7. **Deploy to Apify** — Run `apify login`, then `apify push` to deploy. Schedule runs, set up webhooks, and integrate with Zapier, Make, or Google Drive

### What data does it extract?

Each scraped product listing includes:

| Field | Type | Description |
| --- | --- | --- |
| `title` | string | Product listing title |
| `url` | string | Full Etsy listing URL |
| `price` | string | Current price (e.g. "$24.99") |
| `original_price` | string or null | Original price if on sale |
| `currency` | string | Currency code (USD, EUR, GBP, etc.) |
| `image_url` | string | Main product image URL |
| `seller` | string | Shop name |
| `seller_url` | string | Full shop URL |
| `rating` | number or null | Average rating (0.0–5.0) |
| `reviews_count` | number or null | Number of reviews |
| `tags` | array of strings | Listing tags/keywords |
| `is_bestseller` | boolean | Whether the listing has a bestseller badge |
| `free_shipping` | boolean | Whether the listing offers free shipping |

### Example output

```json
{
  "title": "Handmade Sterling Silver Ring with Moonstone",
  "url": "https://www.etsy.com/listing/1234567890",
  "price": "$48.00",
  "original_price": null,
  "currency": "USD",
  "image_url": "https://i.etsystatic.com/xxx/il/xxx.jpeg",
  "seller": "MoonstoneJewelryCo",
  "seller_url": "https://www.etsy.com/shop/MoonstoneJewelryCo",
  "rating": 4.8,
  "reviews_count": 234,
  "tags": ["moonstone ring", "sterling silver", "handmade jewelry", "birthstone"],
  "is_bestseller": true,
  "free_shipping": true
}
````

### Input parameters

| Parameter | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `search_query` | string | No\* | — | Etsy search query (e.g. "handmade jewelry") |
| `shop_url` | string | No\* | — | Full Etsy shop URL (e.g. `https://www.etsy.com/shop/ShopName`) |
| `max_results` | integer | No | 25 | Max results to return (1–200) |
| `sort` | string | No | `relevance` | Sort order: `relevance`, `newest`, `price_asc`, `price_desc`, `bestselling` |
| `min_price` | number | No | — | Minimum price filter |
| `max_price` | number | No | — | Maximum price filter |
| `proxyConfiguration` | object | No | disabled | Apify proxy configuration for anti-bot protection |

\*Either `search_query` or `shop_url` is required.

### Pricing / How much does it cost to scrape Etsy?

This Actor uses **pay-per-event (PPE)** billing on the Apify platform. You get **10 free results per run** — ideal for testing and small-scale scraping. Beyond that, each result costs **$0.004**. The Actor start event costs $0.00005.

**Example cost estimate:** A run with 50 results costs 40 × $0.004 = $0.16 (after the 10 free results). With 200 max results: 190 × $0.004 = $0.76 per run.

Running locally on your machine costs nothing beyond your own bandwidth.

### Tips / Advanced options

- **Proxy for large scrapes** — If you're scraping many pages, enable Apify proxy to avoid rate limiting. Configure it in the input under `proxyConfiguration` or via the Apify Console.
- **Limited by results, not pages** — The `max_results` limit counts individual products, not page views. Each search page contains ~48 products, so a run with `max_results: 50` typically only needs 2 page requests.
- **Search vs shop mode** — Only one of `search_query` or `shop_url` should be provided. If both are present, search takes priority.
- **Price filters work with search** — `min_price` and `max_price` only apply to search queries, not shop URLs.
- **Running locally** — Use `apify run --input-file=test-input.json` to test. Data lands in the local `storage/` directory.
- **Deploying to the cloud** — Run `apify push` to deploy. Your Actor will appear at [console.apify.com](https://console.apify.com) under My Actors.

### FAQ, disclaimers, and support

**Is scraping Etsy legal?** Web scraping publicly available data is generally legal, but you should review Etsy's Terms of Service and robots.txt before scraping at scale. This Actor respects robots.txt by default and is designed for responsible data collection.

**Does this scrape individual product detail pages?** No — this scraper extracts data from search result cards and shop listing pages, which contain all the fields listed in the output schema. Individual product pages provide additional data (descriptions, variations, shipping details) but are not covered in this version.

**What if a field comes back null?** Some fields like `rating`, `reviews_count`, and `original_price` may be null for listings that don't have reviews, aren't on sale, or whose cards use a different HTML structure. The scraper uses multiple selector fallbacks to maximize coverage.

**Rate limits and blocking** — Etsy may rate-limit aggressive scraping. For production use at scale, enable Apify proxy and keep `max_results` reasonable. The scraper uses retry-on-blocked behavior by default.

**Found a bug or need a custom solution?** Open an issue in this repository or contact us for custom Actor development. We can extend this scraper to handle individual listing pages, more detailed shop data, or integrate with your specific workflow.

**Data accuracy** — This scraper extracts data as it appears on Etsy's public pages at the time of scraping. Etsy may change its HTML structure, which could affect parsing. We maintain multiple fallback selectors to stay resilient, but no guarantee of 100% uptime is made.

# Actor input Schema

## `search_query` (type: `string`):

Search for products on Etsy (e.g., "handmade jewelry", "vintage furniture")

## `shop_url` (type: `string`):

Full URL of an Etsy shop to scrape products from (e.g., https://www.etsy.com/shop/ShopName)

## `max_results` (type: `integer`):

Maximum number of product results to return (10 free, then PPE charged per result)

## `sort` (type: `string`):

Sort order for search results

## `min_price` (type: `number`):

Minimum product price filter

## `max_price` (type: `number`):

Maximum product price filter

## `proxyConfiguration` (type: `object`):

Proxy settings for anti-bot protection (recommended for large scrapes)

## Actor input object example

```json
{
  "search_query": "handmade jewelry",
  "max_results": 25,
  "sort": "relevance",
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `results` (type: `string`):

No description

# 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 = {
    "search_query": "handmade jewelry",
    "shop_url": ""
};

// Run the Actor and wait for it to finish
const run = await client.actor("ef12/etsy-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 = {
    "search_query": "handmade jewelry",
    "shop_url": "",
}

# Run the Actor and wait for it to finish
run = client.actor("ef12/etsy-scraper").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{
  "search_query": "handmade jewelry",
  "shop_url": ""
}' |
apify call ef12/etsy-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=ef12/etsy-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Etsy Scraper",
        "description": "Scrape Etsy product listings by search query or shop URL. Get titles, prices, images, sellers, ratings, review counts, tags, and shipping info.",
        "version": "0.0",
        "x-build-id": "vMy5RyRY6uccK0IJs"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/ef12~etsy-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-ef12-etsy-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/ef12~etsy-scraper/runs": {
            "post": {
                "operationId": "runs-sync-ef12-etsy-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/ef12~etsy-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-ef12-etsy-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "properties": {
                    "search_query": {
                        "title": "Search Query",
                        "type": "string",
                        "description": "Search for products on Etsy (e.g., \"handmade jewelry\", \"vintage furniture\")"
                    },
                    "shop_url": {
                        "title": "Shop URL",
                        "type": "string",
                        "description": "Full URL of an Etsy shop to scrape products from (e.g., https://www.etsy.com/shop/ShopName)"
                    },
                    "max_results": {
                        "title": "Max Results",
                        "minimum": 1,
                        "maximum": 200,
                        "type": "integer",
                        "description": "Maximum number of product results to return (10 free, then PPE charged per result)",
                        "default": 25
                    },
                    "sort": {
                        "title": "Sort Order",
                        "enum": [
                            "relevance",
                            "newest",
                            "price_asc",
                            "price_desc",
                            "bestselling"
                        ],
                        "type": "string",
                        "description": "Sort order for search results",
                        "default": "relevance"
                    },
                    "min_price": {
                        "title": "Minimum Price",
                        "type": "number",
                        "description": "Minimum product price filter"
                    },
                    "max_price": {
                        "title": "Maximum Price",
                        "type": "number",
                        "description": "Maximum product price filter"
                    },
                    "proxyConfiguration": {
                        "title": "Proxy Configuration",
                        "type": "object",
                        "description": "Proxy settings for anti-bot protection (recommended for large scrapes)",
                        "default": {
                            "useApifyProxy": false
                        }
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
