Douyin Search Scraper
Pricing
$4.99 / 1,000 videos
Douyin Search Scraper
Search Douyin (抖音, Chinese TikTok) videos by keyword, signed out. One row per video with caption, hashtags, likes, comments, collects, shares, publish time, duration, cover, author and a link, plus the related searches Douyin suggests. Each keyword says whether its results were complete.
Pricing
$4.99 / 1,000 videos
Rating
0.0
(0)
Developer
Lantern Lab
Maintained by CommunityActor stats
0
Bookmarked
5
Total users
4
Monthly active users
3 days ago
Last modified
Categories
Share
A Lantern Lab Actor. Search Douyin (抖音, the Chinese TikTok) by keyword and get one row per video: caption, hashtags, likes, comments, collects, shares, publish time, duration, cover, the author and a link to the video. It also writes the searches Douyin suggests for each keyword ("大家还在搜", people also search). No Douyin login, no cookies, no account of your own.
Every keyword gets a summary row that says whether its search was complete. A keyword that could not be searched is marked failed with the reason - it is never reported as "0 results".
Where the data comes from
- Douyin web search, signed out (
dataSource: "guest_web", the default). The Actor opens Douyin's mobile web search (so.douyin.com) the way a visitor without an account does, in a fresh browser session for each keyword, and reads the result list page after page. Only what any signed-out visitor can see is read. - Backup search API (
dataSource: "tikhub"). Used for a keyword only when you set a filter (web search has none) or when web search could not read that keyword at all. Its rows have the same fields, plus follower counts and IP location.
The results are Douyin's web search ranking for a signed-out visitor. They are not the same list the Douyin app shows a signed-in user, and not the same list the backup API returns; the order can also change between sessions and regions. Expect the same topic, not the same videos in the same order.
What it does
- Searches each keyword until it reaches your limit or Douyin has no more results.
- Writes the related searches Douyin shows under the results (
includeRelatedSearches, on by default, free). - Optional sort and filters (publish time, video length, post type) through the backup API.
- One row per video. A video found by two of your keywords is written and charged once, under the first keyword. Douyin's result pages overlap a little; repeats are dropped.
What it does not do
- No video files, no comments, no full author profiles. For comments, use our Douyin Comments Scraper.
- No follower counts or IP location in web search results: Douyin does not show them to signed-out visitors, so these fields are
null(never 0). - No play counts: Douyin does not show them publicly, so
playCountis almost alwaysnull. - No search volume for related searches, and no multi-level keyword expansion.
- No scheduling or monitoring built in; use Apify schedules.
Input
| Field | Default | Meaning |
|---|---|---|
keywords | - | One search per keyword. Required. |
maxResultsPerKeyword | 100 | Search results to read per keyword (1-1000). Videos already written under an earlier keyword count toward the limit but are not written again. |
includeRelatedSearches | true | Also write the searches Douyin suggests for each keyword. |
sort | general | general (relevance, 综合排序), latest or mostLiked. |
publishedWithin | any | any, day, week or halfYear. |
duration | any | any, under1min, from1to5min or over5min. |
contentType | all | all, video or image (图文). |
maxUpstreamRequests | derived from your input | Hard ceiling on the requests this run may send to the backup data source. Counted in HTTP attempts, so an internal retry uses one up. 0 switches the backup data source off for the run. Leave it empty and the Actor uses keywords x ceil(maxResultsPerKeyword / 10) x 2 + 2, which is enough to finish the run you asked for; your own value always wins. |
Douyin web search has no sort or filters. If you set sort, publishedWithin, duration or contentType to anything other than the default, every keyword is read from the backup API. If the backup API is not available at the time, the run stops at once with a message - it does not return unfiltered results in their place. Nothing is charged.
Example:
{"keywords": ["水溶肥", "雅苒"],"maxResultsPerKeyword": 100}
An empty keyword list or an unknown option stops the run at once with a message that says what to fix. Nothing is searched or charged.
Output
One dataset; recordType tells the rows apart. Three table views are predefined: Videos, Related searches and Keyword summaries. A RUN_SUMMARY record in the key-value store has the run totals and the status of each keyword.
Video rows (recordType: "video"):
| Field | Meaning |
|---|---|
dataSource | guest_web (signed-out web search) or tikhub (backup API). |
keyword, rank | The keyword that found the video and its position in the results (from 1). |
videoId | Douyin video (aweme) ID, as a string. |
videoUrl | https://www.douyin.com/video/<videoId>, or https://www.douyin.com/note/<videoId> for image posts. |
postType | video or image (图文). |
description | The caption, with hashtags as written. |
hashtags | Hashtags in the caption, without #. |
likeCount, commentCount, collectCount, shareCount | Counts at collection time. |
playCount | Usually null (Douyin does not show it). |
publishedAt | When the post was published (UTC). |
durationSeconds | Video length; null for image posts. |
coverUrl | Cover image link. Douyin signs these links; they expire after some days. |
authorId, authorSecUid, authorNickname, authorDouyinId | The author as shown in the search result. authorSecUid opens the profile at https://www.douyin.com/user/<authorSecUid>; authorDouyinId is the Douyin ID (抖音号). |
authorFollowerCount | Followers. null for guest_web rows (not shown to signed-out visitors). |
ipLocation | IP location (IP 属地). null for guest_web rows; for tikhub rows, when Douyin includes it. |
collectedAt | When we collected the row (UTC). |
Related-search rows (recordType: "related_search"):
| Field | Meaning |
|---|---|
keyword | Your keyword. |
relatedKeyword | A search Douyin suggests for it. |
rank | Position in the suggestions, in the order they appeared (from 1). |
source, sourceLabel | people_also_search, shown on Douyin under the heading 大家还在搜. |
sourceCard | Which suggestion card on the result pages (from 1). Douyin shows several cards as you scroll. |
collectionStatus | complete. |
dataSource, collectedAt | As for videos. |
Related searches are Douyin's own suggestions for the keyword. They come with no search volume, and Douyin may suggest different words to different visitors, regions and times. They are free.
Keyword summary rows (recordType: "keyword_summary"), one per keyword:
| Field | Meaning |
|---|---|
dataSource | The source that read the keyword. |
collectionStatus | complete: Douyin had no more results. partial: stopped before the end, see stopReason. empty: no results for this keyword and filters. failed: nothing could be read - not the same as empty. |
stopReason | end_of_results, limit_reached (your maxResultsPerKeyword), refused (Douyin refused signed-out search on every fresh session tried), upstream_error, pagination_stopped (Douyin said it had more but the next page did not load), charge_limit (your maximum charge for the run), data_source_unavailable or not_searched (the run did not reach this keyword). |
statusReason | Why the keyword is not complete, in words. |
videosCollected | Video rows written and charged for this keyword. |
foundUnderEarlierKeyword | Results already written under an earlier keyword. |
resultsSeen, pagesRead | Distinct results read and result pages read. |
relatedSearchStatus | complete, failed (none could be read; relatedSearchReason says why - this does not mean there are none) or not_requested. |
relatedSearchesCollected | Related-search rows written. |
guestSessions, guestRefusals | Fresh signed-out sessions used, and how many Douyin refused. |
fallbackFrom, fallbackReason | When web search failed: why, and whether the backup API read the keyword instead. |
sort, publishedWithin, durationFilter, contentTypeFilter | The options used. |
Counts are what Douyin showed at collectedAt and change over time.
Was the backup data source used? (RUN_SUMMARY)
Three fields in RUN_SUMMARY answer that, and a program should read them in this order:
| Field | Meaning |
|---|---|
backupConfigured | true when this Actor has a backup data source at all. When it is false there is nothing to be unavailable: stop here. |
backupUnavailableKind | null when the backup source was available. Otherwise not_configured, cap_zero (you set maxUpstreamRequests to 0), no_credential (the backup account was rejected or out of credit) or upstream_error. The first two are configuration, the last two mean collection that needed the backup source is short. |
backupUnavailable | The same reason in a sentence, for a person to read. The wording can change between builds; do not match on it. |
A non-empty backupUnavailable is not a failure by itself. A run that reads every keyword
through signed-out web search reports backupConfigured: false,
backupUnavailableKind: "not_configured" and still has allComplete: true. Whether a keyword is
short is told by its own collectionStatus and stopReason, not by these three fields.
Pricing
Pay per event, no start fee:
| Event | Price | Charged for |
|---|---|---|
video | $4.99 per 1,000 videos ($0.00499 each) | Each video row written. |
Related-search rows and summary rows are free. A video found by several keywords is charged once. Set a maximum charge for the run and the Actor stops before going over it; the keyword's summary says charge_limit.
Limits
- Douyin decides how many results a search returns. A search can end before your limit; the summary then says
end_of_results. - Web search depth varies by keyword and session. If Douyin stops loading more pages, the keyword is
partialwithpagination_stoppedand keeps what was read. - Douyin sometimes asks a signed-out session for a verification check. The Actor then tries a fresh session (at most three per keyword); if every one is refused, the keyword falls back to the backup API, or is marked
failedwithrefused. - The backup API has its own quota. When it is used up, keywords that need it are marked
partialorfailedwithdata_source_unavailable, the status message says so, and keywords that web search can read still run. maxUpstreamRequestsis a hard ceiling, not a target: the run sends at most that many requests to the backup data source, counted in HTTP attempts, so an internal retry of a request that timed out uses one up. Reaching it gives you incomplete results: collection stops where it is, every row already written is kept, and the keyword's summary ispartial(when it had results) orfailed(when it had none) withstopReasonupstream_request_capand astatusReasonthat says which ceiling stopped it, not Douyin.- Every run has this ceiling, including one that does not ask for it. When you leave
maxUpstreamRequestsempty, the Actor works it out from the rest of your input:keywords x ceil(maxResultsPerKeyword / 10) x 2 + 2. That is the pages the run has to read (the backup source returns at least 10 results per page), doubled so a retried request does not cut collection short, plus two spare - so the default is enough to finish the run you asked for, and a single run cannot send an unbounded number of backup requests. One keyword and the default 100 results give 22. A value you pass yourself always wins, whether it is larger or smaller.RUN_SUMMARYreports which of the two was used inbackupCapSource(inputorderived) and the number itself inbackupCap. maxUpstreamRequests: 0switches the backup data source off for the whole run. Keywords that signed-out web search cannot read are thenfailedand say the backup source was off because you set the limit to 0. Runs that need filters are refused before anything is searched, and no request leaves the Actor.RUN_SUMMARYthen saysbackupUnavailableKind: "cap_zero", which is your input, not a broken source.- The ceiling applies to the whole run, so with several keywords the last ones can be the incomplete ones.
RUN_SUMMARYreportsbackupAttempts(HTTP attempts, the number the ceiling counts),backupRequests(attempts the backup source answered),backupCap,backupCapSourceandbackupCapped. - The ceiling covers every request to the backup data source except one: a run that uses filters checks the backup account once before it starts, so it can refuse the filters instead of failing on the first page. That check reads no search results and is never billed, and it is skipped when
maxUpstreamRequestsis 0, so a run capped at 0 sends no request at all. - Results are what Douyin returned at the time of the run.
Feedback
Open an issue on this Actor with the keyword, the options you used and the output you expected.