# TikTok Hashtag Scraper (`shahidirfan/tiktok-hashtag-scraper`)

Meet the TikTok Hashtag Scraper! This actor quickly scrapes and downloads videos from any hashtag. It provides high-quality videos without watermarks. For the fastest possible download speeds, it is highly recommended to disable proxies. Get all the TikTok content you need, fast and clean.

- **URL**: https://apify.com/shahidirfan/tiktok-hashtag-scraper.md
- **Developed by:** [Shahid Irfan](https://apify.com/shahidirfan) (community)
- **Categories:** Videos, Social media, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, NaN bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

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

# README

## TikTok Hashtag Scraper

> Extract TikTok video URLs by hashtag and download original quality videos without watermarks

### What does this actor do?

This Apify actor searches TikTok by hashtag and extracts video URLs from hashtag pages. It can download the actual video files in their original quality (without TikTok watermarks) or just collect comprehensive metadata. Videos are stored in the key-value store with direct download links provided in the dataset.

#### Features

- 🔍 **Hashtag Search**: Find videos by any TikTok hashtag
- 📥 **Original Quality Downloads**: Download videos in their original quality without TikTok watermarks
- 📊 **Metadata Extraction**: Collect comprehensive video information
- 🔒 **Authentication Support**: Use cookies for restricted content
- ⚡ **Proxy Support**: Built-in proxy rotation for reliable scraping
- 🎯 **Quality Selection**: Choose from best, 720p, 1080p, or audio-only
- 📈 **Batch Processing**: Download multiple videos from hashtag results

### Input

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `queryInput` | string | Required | Hashtag to search for (without ## symbol, e.g., "fyp", "viral", "dancing") |
| `maxVideos` | integer | Optional | Maximum number of videos to process (1-100). Default: `10` |
| `downloadMode` | string | Optional | Choose download mode. Options: `videos` (download original videos without watermarks) or `metadata_only` (metadata only). Default: `videos` |
| `quality` | string | Optional | Video quality preference. Options: `best`, `720p`, `1080p`, `audio_only`. Default: `best` |
| `useProxy` | boolean | Optional | Enable proxy for scraping. Default: `true` |
| `maxDownloadSpeed` | integer | Optional | Maximum download speed in KB/s (0 = unlimited). Default: `0` |
| `cookies` | string | Optional | TikTok cookies for authentication (JSON or Netscape format) |
| `proxyConfiguration` | object | Optional | Custom proxy configuration |

### Usage

#### Basic Hashtag Search

To scrape videos from a hashtag, simply provide the hashtag name:

```json
{
  "queryInput": "fyp"
}
```

#### Advanced Configuration

For more control over the scraping process:

```json
{
  "queryInput": "cooking",
  "maxVideos": 25,
  "downloadMode": "videos",
  "quality": "720p",
  "useProxy": true,
  "maxDownloadSpeed": 500
}
```

#### Metadata Only Mode

To collect video information without downloading files (useful for getting URLs to original videos without watermarks):

```json
{
  "queryInput": "travel",
  "downloadMode": "metadata_only",
  "maxVideos": 50
}
```

#### With Authentication

For accessing restricted or region-locked content:

```json
{
  "queryInput": "private_hashtag",
  "cookies": "{\"name\": \"sessionid\", \"value\": \"your_session_id\", \"domain\": \".tiktok.com\"}",
  "useProxy": true
}
```

### How it works

1. **Hashtag Search**: The actor navigates to `https://www.tiktok.com/tag/{hashtag}`
2. **Content Discovery**: Uses advanced scraping techniques to find video URLs
3. **Video Processing**: Downloads original quality videos (without TikTok watermarks) or extracts metadata as requested
4. **Storage**: Saves videos to key-value store with download URLs
5. **Results**: Outputs comprehensive dataset with all collected information

### Output

The actor returns a dataset containing metadata for each processed video. When downloading videos, additional fields are included.

#### Sample Output

```json
[
  {
    "video_id": "7123456789012345678",
    "title": "Amazing cooking tutorial #fyp #cooking",
    "author": "chef_master",
    "url": "https://www.tiktok.com/@chef_master/video/7123456789012345678",
    "download_url": "https://api.apify.com/v2/key-value-stores/abc123/records/7123456789012345678.mp4",
    "file_size": 15432000,
    "file_extension": "mp4",
    "quality_requested": "best",
    "downloaded_format": "h264",
    "duration": 45,
    "view_count": 2500000,
    "like_count": 150000,
    "publish_date": "2024-03-15",
    "description": "Quick and easy pasta recipe! 🍝 #pasta #recipe #cooking",
    "thumbnail": "https://p16-sign-va.tiktokcdn.com/...",
    "collected_at": "2024-03-20T10:30:00Z"
  }
]
```

#### Output Schema

| Field | Type | Description |
|-------|------|-------------|
| `video_id` | string | Unique TikTok video identifier |
| `title` | string | Video title/caption |
| `author` | string | Creator username |
| `url` | string | Original TikTok video URL |
| `download_url` | string | Direct download link (when videos are downloaded) |
| `file_size` | integer | File size in bytes (when downloaded) |
| `file_extension` | string | File format (mp4, webm, etc.) |
| `quality_requested` | string | Quality setting used |
| `downloaded_format` | string | Actual format downloaded |
| `duration` | integer | Video duration in seconds |
| `view_count` | integer | Number of views |
| `like_count` | integer | Number of likes |
| `publish_date` | string | Upload date (YYYY-MM-DD) |
| `description` | string | Full video description |
| `thumbnail` | string | Thumbnail image URL |
| `collected_at` | string | ISO timestamp of collection |

### Tips and best practices

#### Choosing Hashtags

- Start with popular hashtags like "fyp", "viral", "trending"
- Use specific niche hashtags for targeted content
- Test with small `maxVideos` count first

#### Performance Optimization

- **Disable proxy** for faster downloads when not needed
- **Use metadata-only mode** for quick data collection
- **Set download speed limits** to prevent hanging on slow connections
- **Batch processing** with reasonable video counts

#### Authentication

- Export cookies from a logged-in TikTok session
- Use JSON format for multiple cookies
- Required for private accounts or geo-restricted content

### Troubleshooting

#### "No videos found for hashtag"

**Possible causes:**

- Hashtag doesn't exist or has no public videos
- Content requires authentication
- TikTok rate limiting or geographic restrictions

**Solutions:**

1. Try a different, more popular hashtag
2. Provide TikTok cookies for authentication
3. Enable proxy settings
4. Reduce `maxVideos` parameter

#### "Download failed" errors

**Possible causes:**

- Video is private, deleted, or region-locked
- Network connectivity issues
- TikTok anti-bot measures

**Solutions:**

1. Check if video is still available on TikTok
2. Use proxy configuration
3. Add authentication cookies
4. Reduce concurrent downloads

**Note:** Downloads are of original videos without TikTok watermarks, so some videos may not be available if they have specific licensing restrictions.

#### Slow performance

**Solutions:**

1. Set `useProxy: false` for direct connections
2. Configure `maxDownloadSpeed` to prevent timeouts
3. Use `metadata_only` mode for faster data collection
4. Reduce `maxVideos` for quicker results

#### Authentication issues

**How to get TikTok cookies:**

1. Open TikTok in your web browser and log in
2. Open Developer Tools (F12)
3. Go to Application/Storage → Cookies → `https://www.tiktok.com`
4. Copy cookies in JSON format or export as Netscape format
5. Paste into the `cookies` input field

### Resources

- [Apify Platform Documentation](https://docs.apify.com/platform)
- [Apify Actor Development](https://docs.apify.com/academy)
- [TikTok Developer Documentation](https://developers.tiktok.com/)

### Support

For issues or questions:

- Check the [Apify Community Forum](https://community.apify.com/)
- Review [Apify Status](https://status.apify.com/) for platform issues
- Create an issue in the actor's repository

# Actor input Schema

## `queryInput` (type: `string`):

Enter hashtag to search for (without # symbol).

## `maxVideos` (type: `integer`):

Maximum number of videos to download from hashtag search results.

## `downloadMode` (type: `string`):

Choose whether to download full videos or extract metadata only.

## `quality` (type: `string`):

Preferred video quality/format. Only applies when downloading videos. The actor automatically falls back to lower or best available qualities if the requested one is missing.

## `useProxy` (type: `boolean`):

Whether to use proxy for downloading. Disable for faster downloads if you don't need proxy protection.

## `maxDownloadSpeed` (type: `integer`):

Limit download speed in KB/s to prevent extremely slow downloads. Set to 0 for unlimited speed.

## `cookies` (type: `string`):

Optional cookies to bypass TikTok authentication. Accepts both JSON format (from browser dev tools) and Netscape format. JSON cookies will be automatically converted. Leave empty if videos are publicly accessible.

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

Proxy settings for downloading TikTok videos. Only used when 'Use Proxy' is enabled. Recommended to use Apify Proxy to avoid potential rate limiting or IP blocking.

## Actor input object example

```json
{
  "queryInput": "funny cats",
  "maxVideos": 10,
  "downloadMode": "videos",
  "quality": "best",
  "useProxy": true,
  "maxDownloadSpeed": 0,
  "proxyConfiguration": {}
}
```

# Actor output Schema

## `overview` (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 = {
    "queryInput": "funny cats"
};

// Run the Actor and wait for it to finish
const run = await client.actor("shahidirfan/tiktok-hashtag-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 = { "queryInput": "funny cats" }

# Run the Actor and wait for it to finish
run = client.actor("shahidirfan/tiktok-hashtag-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 '{
  "queryInput": "funny cats"
}' |
apify call shahidirfan/tiktok-hashtag-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "TikTok Hashtag Scraper",
        "description": "Meet the TikTok Hashtag Scraper! This actor quickly scrapes and downloads videos from any hashtag. It provides high-quality videos without watermarks. For the fastest possible download speeds, it is highly recommended to disable proxies. Get all the TikTok content you need, fast and clean.",
        "version": "0.0",
        "x-build-id": "jElkf2aBGLe65VwUU"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/shahidirfan~tiktok-hashtag-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-shahidirfan-tiktok-hashtag-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/shahidirfan~tiktok-hashtag-scraper/runs": {
            "post": {
                "operationId": "runs-sync-shahidirfan-tiktok-hashtag-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/shahidirfan~tiktok-hashtag-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-shahidirfan-tiktok-hashtag-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",
                "required": [
                    "queryInput"
                ],
                "properties": {
                    "queryInput": {
                        "title": "Hashtag",
                        "type": "string",
                        "description": "Enter hashtag to search for (without # symbol)."
                    },
                    "maxVideos": {
                        "title": "Maximum Videos to Download",
                        "minimum": 1,
                        "maximum": 100,
                        "type": "integer",
                        "description": "Maximum number of videos to download from hashtag search results.",
                        "default": 10
                    },
                    "downloadMode": {
                        "title": "Download Mode",
                        "enum": [
                            "videos",
                            "metadata_only"
                        ],
                        "type": "string",
                        "description": "Choose whether to download full videos or extract metadata only.",
                        "default": "videos"
                    },
                    "quality": {
                        "title": "Video Quality",
                        "enum": [
                            "best",
                            "720p",
                            "1080p",
                            "audio_only"
                        ],
                        "type": "string",
                        "description": "Preferred video quality/format. Only applies when downloading videos. The actor automatically falls back to lower or best available qualities if the requested one is missing.",
                        "default": "best"
                    },
                    "useProxy": {
                        "title": "Use Proxy",
                        "type": "boolean",
                        "description": "Whether to use proxy for downloading. Disable for faster downloads if you don't need proxy protection.",
                        "default": true
                    },
                    "maxDownloadSpeed": {
                        "title": "Maximum Download Speed (KB/s)",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Limit download speed in KB/s to prevent extremely slow downloads. Set to 0 for unlimited speed.",
                        "default": 0
                    },
                    "cookies": {
                        "title": "TikTok Cookies (optional)",
                        "type": "string",
                        "description": "Optional cookies to bypass TikTok authentication. Accepts both JSON format (from browser dev tools) and Netscape format. JSON cookies will be automatically converted. Leave empty if videos are publicly accessible."
                    },
                    "proxyConfiguration": {
                        "title": "Proxy Configuration",
                        "type": "object",
                        "description": "Proxy settings for downloading TikTok videos. Only used when 'Use Proxy' is enabled. Recommended to use Apify Proxy to avoid potential rate limiting or IP blocking.",
                        "default": {}
                    }
                }
            },
            "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
