Douyin Search Scraper avatar

Douyin Search Scraper

Pricing

$4.99 / 1,000 videos

Go to Apify Store
Douyin Search Scraper

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

Lantern Lab

Maintained by Community

Actor 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 playCount is almost always null.
  • No search volume for related searches, and no multi-level keyword expansion.
  • No scheduling or monitoring built in; use Apify schedules.

Input

FieldDefaultMeaning
keywords-One search per keyword. Required.
maxResultsPerKeyword100Search results to read per keyword (1-1000). Videos already written under an earlier keyword count toward the limit but are not written again.
includeRelatedSearchestrueAlso write the searches Douyin suggests for each keyword.
sortgeneralgeneral (relevance, 综合排序), latest or mostLiked.
publishedWithinanyany, day, week or halfYear.
durationanyany, under1min, from1to5min or over5min.
contentTypeallall, video or image (图文).
maxUpstreamRequestsderived from your inputHard 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"):

FieldMeaning
dataSourceguest_web (signed-out web search) or tikhub (backup API).
keyword, rankThe keyword that found the video and its position in the results (from 1).
videoIdDouyin video (aweme) ID, as a string.
videoUrlhttps://www.douyin.com/video/<videoId>, or https://www.douyin.com/note/<videoId> for image posts.
postTypevideo or image (图文).
descriptionThe caption, with hashtags as written.
hashtagsHashtags in the caption, without #.
likeCount, commentCount, collectCount, shareCountCounts at collection time.
playCountUsually null (Douyin does not show it).
publishedAtWhen the post was published (UTC).
durationSecondsVideo length; null for image posts.
coverUrlCover image link. Douyin signs these links; they expire after some days.
authorId, authorSecUid, authorNickname, authorDouyinIdThe author as shown in the search result. authorSecUid opens the profile at https://www.douyin.com/user/<authorSecUid>; authorDouyinId is the Douyin ID (抖音号).
authorFollowerCountFollowers. null for guest_web rows (not shown to signed-out visitors).
ipLocationIP location (IP 属地). null for guest_web rows; for tikhub rows, when Douyin includes it.
collectedAtWhen we collected the row (UTC).

Related-search rows (recordType: "related_search"):

FieldMeaning
keywordYour keyword.
relatedKeywordA search Douyin suggests for it.
rankPosition in the suggestions, in the order they appeared (from 1).
source, sourceLabelpeople_also_search, shown on Douyin under the heading 大家还在搜.
sourceCardWhich suggestion card on the result pages (from 1). Douyin shows several cards as you scroll.
collectionStatuscomplete.
dataSource, collectedAtAs 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:

FieldMeaning
dataSourceThe source that read the keyword.
collectionStatuscomplete: 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.
stopReasonend_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).
statusReasonWhy the keyword is not complete, in words.
videosCollectedVideo rows written and charged for this keyword.
foundUnderEarlierKeywordResults already written under an earlier keyword.
resultsSeen, pagesReadDistinct results read and result pages read.
relatedSearchStatuscomplete, failed (none could be read; relatedSearchReason says why - this does not mean there are none) or not_requested.
relatedSearchesCollectedRelated-search rows written.
guestSessions, guestRefusalsFresh signed-out sessions used, and how many Douyin refused.
fallbackFrom, fallbackReasonWhen web search failed: why, and whether the backup API read the keyword instead.
sort, publishedWithin, durationFilter, contentTypeFilterThe 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:

FieldMeaning
backupConfiguredtrue when this Actor has a backup data source at all. When it is false there is nothing to be unavailable: stop here.
backupUnavailableKindnull 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.
backupUnavailableThe 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:

EventPriceCharged 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 partial with pagination_stopped and 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 failed with refused.
  • The backup API has its own quota. When it is used up, keywords that need it are marked partial or failed with data_source_unavailable, the status message says so, and keywords that web search can read still run.
  • maxUpstreamRequests is 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 is partial (when it had results) or failed (when it had none) with stopReason upstream_request_cap and a statusReason that says which ceiling stopped it, not Douyin.
  • Every run has this ceiling, including one that does not ask for it. When you leave maxUpstreamRequests empty, 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_SUMMARY reports which of the two was used in backupCapSource (input or derived) and the number itself in backupCap.
  • maxUpstreamRequests: 0 switches the backup data source off for the whole run. Keywords that signed-out web search cannot read are then failed and 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_SUMMARY then says backupUnavailableKind: "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_SUMMARY reports backupAttempts (HTTP attempts, the number the ceiling counts), backupRequests (attempts the backup source answered), backupCap, backupCapSource and backupCapped.
  • 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 maxUpstreamRequests is 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.