CommunityResearch & Data Analysisgithub.com

Douyin Benchmark

Analyze Douyin accounts: input a Douyin account, collect all public post data, and generate a competitive analysis report (raw data + Markdown + light magazine-style HTML). Agent-friendly skill.

What is Douyin Benchmark?

The `douyin-benchmark` skill is an AI-agent-compatible tool for analyzing public data from Douyin (TikTok China) accounts. It automates the collection of profile information, posts, and collections via a dedicated browser session, then produces a structured `report_data.json` plus a beautifully styled HTML report and a detailed Markdown analysis. The skill enforces strict ethical and technical boundaries: it only accesses publicly visible web data, does not bypass captchas or authentication, and stops on any form of soft blocking (e.g., service errors, login prompts, or security challenges). It is designed for agentic workflows, meaning the AI agent reads the status files (`run_status.json`, `capture` diagnostics) to determine next steps and writes the final Markdown report using a nine-section template, clearly distinguishing facts, observations, and inferences with confidence levels. The tool supports custom profiles, headless or headed Chrome, and configurable scroll intervals, ensuring reliable, reproducible analysis while respecting platform policies.

Works with~Claude Code~Codex CLI~Cursor
npx skills add 9398-haha/douyin-benchmark

Installed? Explore more Research & Data Analysis skills: affaan-m/uspto-database, affaan-m/scholar-evaluation, affaan-m/literature-review · View all 6 →

Ask in your favorite AI

Open a new chat with this agent skill pre-loaded.

Documentation

What does Douyin Benchmark do?

Let the script handle public account data collection, aggregation, and HTML rendering; the agent writes a Markdown report with evidence boundaries based on report_data.json.

Boundaries

  • Only collect publicly visible web data; do not crack signatures, bypass CAPTCHAs, or circumvent access controls.
  • Only use the ~/.douyin-benchmark/chrome-profile dedicated login state. Do not read, copy, or directly point to the user's daily Chrome user directory; do not output cookie values.
  • Keep missing values as missing; do not rewrite them as 0. Likes can only serve as a proxy for public engagement, not as a measure of play performance, interaction rate, or follower conversion.
  • Distinguish between a regular login form, real security verification, and page service errors. Stop on encountering a security challenge, page service error, or empty response soft block; do not retry in a loop, auto-switch IPs, create delayed tasks, or promise to complete later.

Initial Setup

Run the following commands in this Skill's directory:

npm ci
node scripts/login.js

login.js opens a dedicated browser, authenticates to a real account entry point, then automatically saves and closes. To check an existing login state, run node scripts/login.js --check.

One-Command Execution

Prefer to ask the user for the Douyin App "Share Profile" short link. A numeric Douyin ID is not the same as sec_uid; directly concatenating /user/<number> may silently redirect to the feed.

OUT="$HOME/douyin-benchmark-output/<account-identifier>"
node scripts/run_benchmark.js "<profile-share-link/sec_uid/douyin-id/nickname>" "$OUT" \
  --expected-id "<douyin-id, optional>"

By default, it uses headed Chrome for better observability and a real browser UA. Only explicitly add --headless in headless environments. The script executes in order:

  1. Resolve the short link or sec_uid; only use in-app search when given a nickname or Douyin ID.
  2. Collect profile info, posts, and collections, writing them to account_full_raw.json.
  3. If posts exist, generate report_data.json and report.html.
  4. Update run_status.json throughout; do not continue analysis after a failure.

Check Status First, Then Write Conclusions

Read run_status.json and account_full_raw.json.capture:

  • complete: The API returned has_more=0. A full account-level report can be written; still compare the homepage post count with the collected count.
  • partial: Only write a "sampled post report"; indicate the sample size, total homepage post count, and coverage near the title. Do not use terms like "full" or "account's max."
  • blocked_empty_body: The posts endpoint returned HTTP 200 with an empty body. Stop requests, deliver only the profile snapshot and diagnostics; any retry must be user-initiated, and at most once.
  • challenge: Ask the user to complete the verification in the dedicated browser before retrying; do not attempt to bypass.
  • login_required: The page shows a regular login form, not a security challenge. Run the login script, then retry only once after success.
  • page_service_error: The posts area explicitly shows "Service error, please refresh." Stop refreshing; after verifying the login state, retry at most once.
  • no_post_response: May be an incorrect input or a page/API change. First check the sec_uid and the headed page; do not blindly increase scroll count.
  • endpoint_error: The posts endpoint returned an HTTP/API error or non-JSON content. Keep diagnostics and stop analysis; first check for page/API changes.

Writing the Markdown Report

Only when report_data.json exists and contains analyzable posts, fully read the references/report-template.md and write $OUT/report.md following the nine-section structure.

Classify content into three types and use precise wording:

  • Facts: Public fields from the JSON and their computed results.
  • Observations: Titles, bios, collection names, cover images, or content of videos actually opened.
  • Inferences: Persona, monetization path, content formula; write down evidence and confidence level, do not present as fact.

Do not write "popular comment sentiment" without comment text; do not claim camera work, voiceover, acting, or edit details without having watched the video. If the user specifies their own niche, then selectively transfer the replicable list.

Verification

  • account_full_raw.json, run_status.json, report_data.json, report.html, and report.md must have consistent statuses.
  • Both HTML and Markdown should display the actual collected sample size, total homepage post count, coverage, and capture_status.
  • On an error, check capture.diagnostics.page: only record the title, path, login/challenge/service-error boolean flags, and video link count; do not save full page content or cookies.
  • Numbers must match report_data.json item by item; missing values display —/Unknown.
  • The HTML file must be openable offline; external text must be escaped. Failed cover images do not affect the main content.
  • No horizontal overflow on the HTML page; the latest post titles must be readable. Posting frequency should show the last 12 months based on individual posts; only fill missing months with 0 if a full capture was performed.
  • The Markdown report must have all nine sections, including data sources, evidence boundaries, a replicable list, and items that should not be blindly copied.

Configuration

  • DOUYIN_PROFILE_DIR: Dedicated login state directory; default is ~/.douyin-benchmark/chrome-profile.
  • DOUYIN_BROWSER_CHANNEL: Default is chrome; set to chromium to install Playwright Chromium first.
  • DOUYIN_HEADLESS=true: Explicitly enable headless mode; default is headed.
  • DOUYIN_SCROLL_WAIT_MS: Minimum scroll interval, default 1600ms; do not use it for high-frequency scraping.

Related Skills