# TikTok Shop Scraper: Products, Prices, Sales (`bonpleincapital/tiktok-shop-playwright-scraper`) Actor

TikTok Shop scraper using a real browser: collects public seller stores, product prices and sold counts from store, product and keyword pages. No login.

License: personal use only; resale and redistribution prohibited.
Created with the help of artificial intelligence.

- **URL**: https://apify.com/bonpleincapital/tiktok-shop-playwright-scraper.md
- **Developed by:** [Bon Plein Capital](https://apify.com/bonpleincapital) (community)
- **Categories:** E-commerce, Social media
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.80 / 1,000 result records

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
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

## TikTok Shop Scraper: Products, Prices & Sales Counts (Playwright)

**TikTok Shop scraper** that opens public TikTok Shop pages in a real Chromium browser (Playwright) and returns clean,
structured records: product titles, prices, units sold, ratings and seller details. Because pages are rendered the way a
visitor sees them, it handles dynamic content and lazy-loaded product lists that simple HTTP scrapers miss. Paste a
seller store URL, a product URL or a keyword, and download the results as JSON, CSV or Excel, or call the Actor from the
Apify API. It needs no login and no TikTok account.

### What can this Actor do?

- Scrape a **TikTok Shop seller store**: shop name, seller ID, the public **units sold** counter and the number of
  product links found on the rendered page.
- Scrape **product listings** of a store or keyword page: the browser scrolls and clicks "load more" (pagination), then
  reads each product card for **title, price, units sold and rating**, with several selector strategies so that a small
  markup change does not break the run.
- Scrape a **TikTok Shop product page**: title, price, currency, rating, review count, image and description, from the
  page markup, the embedded JSON and the JSON the page loads.
- Search by **keyword** in a market (US, UK, Indonesia, Malaysia, Philippines, Singapore, Thailand, Vietnam).
- Track sales counters and prices over time: each record has a `scrapedAt` timestamp, so you can schedule runs and
  compare them.
- Fields that TikTok does not show publicly are returned as `null`, never invented.

### How to use it

1. Click **Try for free** and open the **Input** tab.
2. Add one or more TikTok Shop URLs, or keywords (or keep the prefilled store URL to see an example).
3. Set the pagination depth (`scrollRounds`) and the maximum number of results, then click **Start**.
4. Download the results from the **Output** tab, or call the Actor from the API, Make, Zapier or n8n.

If TikTok answers 403 or 429, or serves an empty page, the Actor retries once through Apify Proxy, then falls back to a
plain read of the page, then skips it: you are not charged for pages that give no record. It does not log in, does not
open private accounts and does not try to bypass captchas: a page that asks for a captcha is skipped.

### Technical improvements (v0.2)

- **Playwright and Chromium** render each page like a visitor, instead of fragile raw HTTP reads.
- **Pagination**: infinite scroll plus "load more" clicks, stopping when no new products appear.
- **Several selector strategies** for product cards, combined with embedded JSON, JSON-LD and the JSON the page loads.
- **Proxy handling**: a direct read first, then one retry through Apify Proxy on 403/429, empty shells or timeouts.
- **Reliable fields**: price, currency, units sold and rating are parsed from cards, product pages and JSON, and set to
  `null` when absent. Records are deduplicated by URL.
- **Time budget** so that runs end well inside the daily 5-minute test; captcha pages are skipped, never bypassed.

### Input

```json
{
  "startUrls": [
    { "url": "https://shop.tiktok.com/us/store/kiki-jewelrry/8652028833300779170" }
  ],
  "keywords": ["neck massager"],
  "country": "us",
  "followLinks": true,
  "scrollRounds": 6,
  "maxItems": 20
}
```

- `startUrls`: seller store, product (`/pdp/`) or keyword (`/k/`) pages of TikTok Shop.
- `keywords`: optional list; each keyword is turned into the public keyword page of the chosen `country`.
- `followLinks`: also open product pages when price or sales count is missing from the listing card.
- `scrollRounds`: how many times the browser scrolls / clicks "load more" to paginate (0 to 30).
- `maxItems`: hard limit on the number of results (and on your bill).

### Output

Each result is one dataset item. Example:

```json
{
  "type": "seller",
  "url": "https://shop.tiktok.com/us/store/kiki-jewelrry/8652028833300779170",
  "productId": null,
  "title": "KiKi Jewelrry",
  "price": null,
  "currency": null,
  "soldCount": 3853,
  "rating": null,
  "reviewCount": null,
  "sellerName": "KiKi Jewelrry",
  "sellerId": "8652028833300779170",
  "imageUrl": null,
  "description": "Shop KiKi Jewelrry on TikTok Shop! 3853 sold, Join the trend!",
  "productLinksFound": 0,
  "country": "US",
  "scrapedAt": "2026-10-15T10:26:35+00:00"
}
```

### How much does it cost?

This Actor uses **pay per event** pricing: you pay a small amount for each result record, and nothing for pages that
could not be read. So 1,000 results cost the price of 1,000 `result` events shown in the **Pricing** tab, plus the
usual Apify compute units for the browser. Apify's free plan gives you monthly credits to try the Actor before you pay.
Use `maxItems` to cap spending.

### FAQ

#### Is it legal to scrape TikTok Shop?

The Actor only reads public pages, like a browser would, and collects no private data. You are responsible for using
the results lawfully and respecting TikTok's terms. Seller names are business names, but if your data contains personal
data of individuals, the GDPR applies to you: have a lawful basis and keep only what you need.

#### Why a browser instead of plain requests?

TikTok Shop builds many pages with JavaScript and loads product lists while you scroll. A browser sees what a visitor
sees, so listings, prices and sales counters are far more reliable than with raw HTTP requests.

#### Why are some fields empty?

TikTok shows different information to anonymous visitors depending on the market and the page. Missing fields are
returned as `null`.

#### Can I get reviews, followers or private analytics?

No. Only what is visible on public pages without logging in is collected.

#### What if something does not work?

Open an issue in the **Issues** tab with your input and the run link. Issues are answered as fast as possible.

#### Can I use it through the API?

Yes. Every run can be started and read through the Apify API and its Python and JavaScript clients.

***

Created with the help of artificial intelligence.

# Changelog

This Actor's version history is a separate document: https://apify.com/bonpleincapital/tiktok-shop-playwright-scraper/changelog.md

# Actor input Schema

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

Public TikTok Shop URLs: seller stores (shop.tiktok.com/us/store/...), product pages (.../pdp/...) or keyword pages (.../k/...).

## `keywords` (type: `array`):

Optional. Each keyword opens the public TikTok Shop keyword page and collects the products listed there.

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

TikTok Shop market used for keywords (two-letter code, e.g. us, gb, id).

## `followLinks` (type: `boolean`):

On seller and keyword pages, also open the product pages when price or sales count is missing from the listing card.

## `scrollRounds` (type: `integer`):

How many times the browser scrolls and clicks 'load more' on store and keyword pages to load more products.

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

Stop after this many results. Keep it low to test the Actor cheaply.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://shop.tiktok.com/us/store/kiki-jewelrry/8652028833300779170"
    }
  ],
  "keywords": [
    "neck massager"
  ],
  "country": "us",
  "followLinks": true,
  "scrollRounds": 2,
  "maxItems": 1
}
```

# Actor output Schema

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

One dataset item per result, shown in the Overview view.

# 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://shop.tiktok.com/us/store/kiki-jewelrry/8652028833300779170"
        }
    ],
    "scrollRounds": 2,
    "maxItems": 1
};

// Run the Actor and wait for it to finish
const run = await client.actor("bonpleincapital/tiktok-shop-playwright-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://shop.tiktok.com/us/store/kiki-jewelrry/8652028833300779170" }],
    "scrollRounds": 2,
    "maxItems": 1,
}

# Run the Actor and wait for it to finish
run = client.actor("bonpleincapital/tiktok-shop-playwright-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://shop.tiktok.com/us/store/kiki-jewelrry/8652028833300779170"
    }
  ],
  "scrollRounds": 2,
  "maxItems": 1
}' |
apify call bonpleincapital/tiktok-shop-playwright-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,bonpleincapital/tiktok-shop-playwright-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/RHcEbkRoHP7PwqTAB/builds/hWsDLGRDkkF33fnq5/openapi.json
