End-to-end FastMoss creative material ranking scraper + analyzer. Uses kimi-webbridge to drive the user's logged-in browser, extracts rows into CSVs, and ships an aggregation script + Markdown report template that produces an analysis report. Scope: the Videos & Materials section of fastmoss.com (3 table-based rankings; the AI Sales Video Ranking is card-based and noted below). For products, shops, creators, ads, or live streams, use the corresponding sister skill.
Prerequisites
-
Kimi WebBridge daemon healthy:
~/.kimi-webbridge/bin/kimi-webbridge status # expect: {"running": true, "extension_connected": true}If not healthy: invoke
Skill(kimi-webbridge)and followreferences/operations.md. -
User is logged in to fastmoss.com in their browser (this skill reuses their session — no auth).
-
Read
references/environment.mdbefore writing new shell orevaluateJS.
Creative ranking URLs
| Ranking key | Chinese | URL | Schema |
|---|---|---|---|
video |
Popular Videos | https://www.fastmoss.com/zh/media-source/video |
table |
song |
Popular Music | https://www.fastmoss.com/zh/media-source/song |
table |
hashtag |
Popular Hashtags | https://www.fastmoss.com/zh/media-source/hashtag |
table |
top-ai-videos |
AI Sales Video Ranking | https://www.fastmoss.com/zh/media-source/top-ai-videos |
cards (not scripted) |
Use /zh/ (Chinese) locale. Site is a NUXT/Vue SPA — always wait for hydration (--nav-sleep 6+).
Per-ranking column schemas
| Ranking | Header columns |
|---|---|
video |
Video Content, Creator Info, Creator Followers, Publish Time, Views, Likes, Engagement Rate |
song |
Music, Creator, Views |
hashtag |
Hashtag, Preview, Impressions, Related Video Count |
The Video Content/Music/Hashtag columns are multi-line text; the scraper pre-parses the primary entity name into entity_name and keeps the raw cell under its original header.
Quick start
# Step 1: Scrape one ranking (Top N pages)
python <path-to-skill>/scripts/creative_scraper.py \
--ranking video --pages 5 --out <out-dir>/videos.csv
python <path-to-skill>/scripts/creative_scraper.py \
--ranking song --pages 3 --out <out-dir>/songs.csv
python <path-to-skill>/scripts/creative_scraper.py \
--ranking hashtag --pages 3 --out <out-dir>/hashtags.csv
# Step 2: Multi-country comparison on one ranking
python <path-to-skill>/scripts/creative_filtered.py \
--ranking video --country 美国,印度尼西亚,泰国,马来西亚 \
--pages 3 \
--out <out-dir>/videos_by_country.csv
# Step 3: Aggregate the per-ranking CSVs into a Markdown report
python <path-to-skill>/scripts/analyze.py \
--video <out-dir>/videos.csv \
--song <out-dir>/songs.csv \
--hashtag <out-dir>/hashtags.csv \
--out-md <report>.md
<path-to-skill> is wherever this skill is installed (typically .claude/skills/fastmoss-creatives inside the project, or ~/.claude/skills/fastmoss-creatives for a user-level install). Run any script with --help for the full arg list.
Scripts
| Script | Purpose |
|---|---|
scripts/creative_scraper.py |
Top-N paginating scraper, any of the 3 table rankings (schema auto-detected from <thead>) |
scripts/creative_filtered.py |
Multi-country filter + paginate |
scripts/analyze.py |
Aggregate CSVs → crosstabs (stdout) or full Markdown report (template-driven) |
References (read on demand)
| File | When to read |
|---|---|
references/environment.md |
Before writing any new shell or evaluate JS — Windows/bash/jq/heredoc rules (mirrors fastmoss-products' version) |
references/analysis_recipe.md |
The Markdown template analyze.py fills. Read to understand the report structure or to extend it |
Filter label vocabularies
Countries (16 markets)
--country <中文,comma-separated>: 全部, 美国, 印度尼西亚, 英国, 越南, 泰国, 马来西亚, 菲律宾, 西班牙, 墨西哥, 德国, 法国, 意大利, 巴西, 日本, 新加坡.
Same vocabulary as fastmoss-products / fastmoss-creators.
Critical gotchas (each cost real time on first run)
Full details in references/environment.md. Summary:
- @e refs from
snapshotgo stale after every navigation →"No node with given id found". Bundled scripts click by text viaevaluate, never @e refs. - Bash heredoc + JS regex =
"Invalid regular expression: missing /"— heredoc eats a backslash layer. Use.split('\n')over.replace(/\n+/g, ...). <thead>headers may report empty viainnerTexton first render. The bundledEXTRACT_JSreadsinnerText || textContentand falls back to thetitleattribute.- SPA hydration lag — pages may need slightly longer waits than product pages (6s default). Too fast → 0 rows.
- Schema differs between rankings —
creative_scraper.pyreads<thead>dynamically. Don't assume a fixed schema in downstream code; iterate overdict.keys(). jqmay not be installed — decode screenshots manually withpython -c+base64.- Python defaults to a locale-specific encoding on Windows — always
open(..., encoding='utf-8-sig')when reading the produced CSVs. - The AI Sales Video Ranking has no
<table>— it's a card grid. Not covered by the bundled scraper. Write a custom evaluate perreferences/environment.mdif needed.
CSV output schema
Base columns (always present):
page, ranking, rank, entity_name, country
Plus one column per <thead> header (Chinese, kept as-is). All CSVs are utf-8-sig (BOM) for Excel.
When using creative_filtered.py, one extra column is prepended:
filter_country
Session hygiene
- Default session
"fastmoss-creatives"for all calls (isolated from sister skills' sessions). Override via--sessionif needed. - At task end:
curl -d '{"action":"close_session","args":{},"session":"fastmoss-creatives"}' http://127.0.0.1:10086/command. - All bundled scripts use
newTab:Trueon first navigate so they work whether or not the session pre-exists.