Jelajahi Sumber

初始化创作知识项目:M0 脚手架 + M1 DB 层 + M2 拉取 + M3 多模态提取

- 业务/架构/开发顺序文档 + 数据接口与来源 + DDL(sql/)
- creation_knowledge 包:config / models / integrations(crawler, extractor, db)
- 测试:test_crawler(离线,5 fixture)、test_extractor(离线,假 http)
- 脚本:validate_db、smoke_extract
- M0/M1/M2 已在真实环境验证;M3 待云端真实 Gemini 验收

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
lisihan 1 bulan lalu
melakukan
e24ebaae9c
88 mengubah file dengan 16521 tambahan dan 0 penghapusan
  1. 22 0
      .gitignore
  2. 7 0
      creation_knowledge/__init__.py
  3. 118 0
      creation_knowledge/config.py
  4. 1 0
      creation_knowledge/integrations/__init__.py
  5. 150 0
      creation_knowledge/integrations/crawler.py
  6. 169 0
      creation_knowledge/integrations/db.py
  7. 155 0
      creation_knowledge/integrations/extractor.py
  8. 82 0
      creation_knowledge/models.py
  9. 17 0
      pyproject.toml
  10. 46 0
      scripts/smoke_extract.py
  11. 79 0
      scripts/validate_db.py
  12. 48 0
      sql/creation_knowledge.sql
  13. 0 0
      tests/fixtures/xhs_case_67e2e39b0000000003028ff0.json
  14. 0 0
      tests/fixtures/xhs_case_67e4bdf50000000006028a59.json
  15. 0 0
      tests/fixtures/xhs_case_680659e8000000001a007a11.json
  16. 0 0
      tests/fixtures/xhs_case_698481e1000000000a02a7c1.json
  17. 0 0
      tests/fixtures/xhs_case_699308fa0000000016009697.json
  18. 66 0
      tests/test_crawler.py
  19. 80 0
      tests/test_extractor.py
  20. 436 0
      创作知识-重构设计.md
  21. 125 0
      技术文档/开发顺序.md
  22. 180 0
      技术文档/技术架构.md
  23. 786 0
      数据接口与来源/00_数据接口总览.md
  24. 484 0
      数据接口与来源/01_DemandAgent输入合同.md
  25. 35 0
      数据接口与来源/captures/_run_log.txt
  26. 74 0
      数据接口与来源/captures/bili_detail.json
  27. 2932 0
      数据接口与来源/captures/bili_search.json
  28. 9 0
      数据接口与来源/captures/bili_video_dl.json
  29. 676 0
      数据接口与来源/captures/douyin_blogger.json
  30. 85 0
      数据接口与来源/captures/douyin_detail.json
  31. 1379 0
      数据接口与来源/captures/douyin_profile_author.json
  32. 12 0
      数据接口与来源/captures/douyin_profile_content.json
  33. 788 0
      数据接口与来源/captures/douyin_search.json
  34. 10 0
      数据接口与来源/captures/douyin_video_dl.json
  35. 331 0
      数据接口与来源/captures/github_search.json
  36. 41 0
      数据接口与来源/captures/gzh_account_info.json
  37. 21 0
      数据接口与来源/captures/gzh_detail.json
  38. 178 0
      数据接口与来源/captures/gzh_search.json
  39. 45 0
      数据接口与来源/captures/kuaishou_account_info.json
  40. 63 0
      数据接口与来源/captures/kuaishou_detail.json
  41. 431 0
      数据接口与来源/captures/kuaishou_search.json
  42. 10 0
      数据接口与来源/captures/kuaishou_video_dl.json
  43. 13 0
      数据接口与来源/captures/sph_account_info.json
  44. 13 0
      数据接口与来源/captures/sph_blogger.json
  45. 13 0
      数据接口与来源/captures/sph_search.json
  46. 524 0
      数据接口与来源/captures/sph_search_retry.json
  47. 9 0
      数据接口与来源/captures/sph_video_dl.json
  48. 14 0
      数据接口与来源/captures/toutiao_search.json
  49. 13 0
      数据接口与来源/captures/toutiao_search_retry.json
  50. 9 0
      数据接口与来源/captures/xhs_blogger.json
  51. 0 0
      数据接口与来源/captures/xhs_case_67e2e39b0000000003028ff0.json
  52. 0 0
      数据接口与来源/captures/xhs_case_67e4bdf50000000006028a59.json
  53. 0 0
      数据接口与来源/captures/xhs_case_680659e8000000001a007a11.json
  54. 0 0
      数据接口与来源/captures/xhs_case_698481e1000000000a02a7c1.json
  55. 0 0
      数据接口与来源/captures/xhs_case_699308fa0000000016009697.json
  56. 62 0
      数据接口与来源/captures/xhs_detail.json
  57. 561 0
      数据接口与来源/captures/xhs_search.json
  58. 21 0
      数据接口与来源/captures/youtube_detail.json
  59. 472 0
      数据接口与来源/captures/youtube_search.json
  60. 12 0
      数据接口与来源/captures/zhihu_search.json
  61. 14 0
      数据接口与来源/captures/zhihu_search_retry.json
  62. 994 0
      数据接口与来源/crawler_endpoints.registry.json
  63. 630 0
      数据接口与来源/external_data_sources_registry.json
  64. 113 0
      数据接口与来源/platform_profiles/bilibili.json
  65. 52 0
      数据接口与来源/platform_profiles/douyin.json
  66. 30 0
      数据接口与来源/platform_profiles/github.json
  67. 127 0
      数据接口与来源/platform_profiles/kuaishou.json
  68. 47 0
      数据接口与来源/platform_profiles/shipinhao.json
  69. 12 0
      数据接口与来源/platform_profiles/toutiao.json
  70. 93 0
      数据接口与来源/platform_profiles/weixin.json
  71. 113 0
      数据接口与来源/platform_profiles/xiaohongshu.json
  72. 94 0
      数据接口与来源/platform_profiles/youtube.json
  73. 12 0
      数据接口与来源/platform_profiles/zhihu.json
  74. 150 0
      数据接口与来源/walk_graph.json
  75. 39 0
      数据接口与来源/walk_policy.json
  76. 204 0
      数据接口与来源/接口台账/B站.md
  77. 93 0
      数据接口与来源/接口台账/github.md
  78. 167 0
      数据接口与来源/接口台账/youtube.md
  79. 189 0
      数据接口与来源/接口台账/公众号.md
  80. 76 0
      数据接口与来源/接口台账/头条.md
  81. 185 0
      数据接口与来源/接口台账/小红书.md
  82. 230 0
      数据接口与来源/接口台账/快手.md
  83. 337 0
      数据接口与来源/接口台账/抖音.md
  84. 63 0
      数据接口与来源/接口台账/知乎.md
  85. 194 0
      数据接口与来源/接口台账/视频号.md
  86. 80 0
      数据接口与来源/游走图谱.md
  87. 235 0
      数据接口与来源/跨平台字段映射.json
  88. 41 0
      数据接口与来源/跨平台字段映射.md

+ 22 - 0
.gitignore

@@ -0,0 +1,22 @@
+# 密钥/环境 —— 绝不入库
+.env
+.env.*
+*.pem
+
+# Python
+__pycache__/
+*.py[cod]
+.venv/
+venv/
+.pytest_cache/
+*.egg-info/
+
+# Node / web
+node_modules/
+dist/
+.next/
+.vite/
+
+# 杂项
+.DS_Store
+*.log

+ 7 - 0
creation_knowledge/__init__.py

@@ -0,0 +1,7 @@
+"""创作知识 · 从帖子拆出可指导创作的知识。
+
+流水线:fetch -> extract(多模态) -> screen -> split -> deconstruct -> assemble -> [ingest]
+详见 技术文档/技术架构.md 与 技术文档/开发顺序.md。
+"""
+
+__version__ = "0.1.0"

+ 118 - 0
creation_knowledge/config.py

@@ -0,0 +1,118 @@
+"""配置加载:从 .env 文件或环境变量读取,风格对齐 ContentFindAgentNew。
+
+只读环境变量,不硬编码密钥。PG 是 M1 唯一必填项;其余环节配置随里程碑推进逐步使用。
+"""
+from __future__ import annotations
+
+import os
+from dataclasses import dataclass
+from pathlib import Path
+
+# 我们自己的过程库 schema(与 OPEN_AIGC_PG_SCHEMA=public 区分开)
+DEFAULT_PG_SCHEMA = "creation_knowledge"
+
+
+def load_env_file(env_path: str | Path = ".env") -> dict[str, str]:
+    """解析 .env 为 dict;文件不存在则返回空。与 crawapi_http._load_env_file 同款。"""
+    path = Path(env_path)
+    if not path.exists():
+        return {}
+    env: dict[str, str] = {}
+    for line in path.read_text(encoding="utf-8").splitlines():
+        stripped = line.strip()
+        if not stripped or stripped.startswith("#") or "=" not in stripped:
+            continue
+        key, value = stripped.split("=", 1)
+        env[key.strip()] = value.strip().strip('"').strip("'")
+    return env
+
+
+def env_value(
+    key: str,
+    file_env: dict[str, str],
+    default: str | None = None,
+    required: bool = False,
+) -> str:
+    """取值优先级:os.environ > .env 文件 > default。required 缺失时报错。"""
+    value = os.getenv(key) or file_env.get(key) or default
+    if required and not value:
+        raise RuntimeError(f"missing required env: {key}")
+    return value or ""
+
+
+@dataclass
+class PgConfig:
+    """过程库(Greenplum open_aigc,schema creation_knowledge)连接配置。"""
+
+    host: str
+    port: int
+    user: str
+    password: str
+    database: str
+    schema: str = DEFAULT_PG_SCHEMA
+    timeout: int = 10
+
+    @classmethod
+    def from_env(cls, env_file: str | Path = ".env") -> "PgConfig":
+        file_env = load_env_file(env_file)
+        return cls(
+            host=env_value("OPEN_AIGC_PG_HOST", file_env, required=True),
+            port=int(env_value("OPEN_AIGC_PG_PORT", file_env, "5432")),
+            user=env_value("OPEN_AIGC_PG_USER", file_env, required=True),
+            password=env_value("OPEN_AIGC_PG_PASSWORD", file_env, required=True),
+            database=env_value(
+                "OPEN_AIGC_PG_DB_NAME", file_env, "open_aigc"
+            ),
+            schema=env_value("CK_PG_SCHEMA", file_env, DEFAULT_PG_SCHEMA),
+        )
+
+
+@dataclass
+class Settings:
+    """全流程配置聚合。M1 只用到 pg;其余字段供 M2+ 使用。"""
+
+    pg: PgConfig
+    # 爬虫(M2)
+    crawler_base_url: str
+    crawler_key: str
+    crawler_timeout: int
+    # 多模态提取(M3)
+    video_model: str
+    gemini_api_key: str
+    openrouter_base_url: str
+    openrouter_api_key: str
+    # 判断/拆分/解构 LLM(M4)
+    llm_model: str
+    # 入库(M5)
+    knowhub_api: str
+    ingest_enabled: bool
+
+    @classmethod
+    def from_env(cls, env_file: str | Path = ".env") -> "Settings":
+        file_env = load_env_file(env_file)
+        return cls(
+            pg=PgConfig.from_env(env_file),
+            crawler_base_url=env_value(
+                "CONTENTFIND_API_CRAWAPI_BASE_URL", file_env,
+                "http://crawler.aiddit.com",
+            ),
+            crawler_key=env_value("CONTENTFIND_API_CRAWAPI_KEY", file_env),
+            crawler_timeout=int(
+                env_value("CONTENTFIND_API_CRAWAPI_TIMEOUT_SECONDS", file_env, "30")
+            ),
+            video_model=env_value(
+                "CONTENT_AGENT_VIDEO_LLM_MODEL", file_env,
+                "google/gemini-3-flash-preview",
+            ),
+            gemini_api_key=env_value("GEMINI_API_KEY", file_env),
+            openrouter_base_url=env_value(
+                "OPENROUTER_BASE_URL", file_env, "https://openrouter.ai/api/v1"
+            ),
+            openrouter_api_key=env_value("OPENROUTER_API_KEY", file_env)
+            or env_value("OPEN_ROUTER_API_KEY", file_env),
+            llm_model=env_value("MODEL", file_env, "anthropic/claude-sonnet-4.5"),
+            knowhub_api=env_value("KNOWHUB_API", file_env, "http://localhost:8000"),
+            # 开发期默认关闭真实入库;显式置 true 才发送
+            ingest_enabled=env_value("INGEST_ENABLED", file_env, "false").lower()
+            in ("1", "true", "yes"),
+        )

+ 1 - 0
creation_knowledge/integrations/__init__.py

@@ -0,0 +1 @@
+"""外部 IO 客户端:crawler / extractor / llm / db。"""

+ 150 - 0
creation_knowledge/integrations/crawler.py

@@ -0,0 +1,150 @@
+"""帖子详情拉取:小红书 detail 接口。
+
+POST {base}/crawler/xiao_hong_shu/detail  body={"content_id": ...}  无 token,限流 ≥15s。
+逻辑(限流 + code==0 信封校验)对齐 ContentFindAgentNew 的 crawapi_http.post_crawapi_json,
+但不依赖其错误体系,保持本项目自包含。
+
+拆成两层:parse_detail_response 纯函数(可离线用 fixture 测)+ fetch_post_detail 负责 HTTP。
+"""
+from __future__ import annotations
+
+import time
+from typing import Any, Callable, Optional
+from urllib.parse import urljoin
+
+import httpx
+
+from creation_knowledge.config import Settings
+from creation_knowledge.models import Post
+
+DETAIL_PATH = "/crawler/xiao_hong_shu/detail"
+RATE_LIMIT_SECONDS = 15.0
+
+
+class CrawlerError(RuntimeError):
+    pass
+
+
+class RateLimiter:
+    """同一 bucket 两次调用间隔 ≥ min_interval。对齐 CFA RateLimiter。"""
+
+    def __init__(
+        self,
+        min_interval_seconds: float = RATE_LIMIT_SECONDS,
+        now_fn: Callable[[], float] = time.monotonic,
+        sleep_fn: Callable[[float], None] = time.sleep,
+    ) -> None:
+        self.min_interval_seconds = min_interval_seconds
+        self.now_fn = now_fn
+        self.sleep_fn = sleep_fn
+        self._last: dict[str, float] = {}
+
+    def wait(self, bucket: str) -> None:
+        last = self._last.get(bucket)
+        if last is not None:
+            remaining = self.min_interval_seconds - (self.now_fn() - last)
+            if remaining > 0:
+                self.sleep_fn(remaining)
+        self._last[bucket] = self.now_fn()
+
+
+def parse_content_id(content_id_or_url: str) -> str:
+    """接受裸 content_id 或 https://www.xiaohongshu.com/explore/<id>?... 链接。"""
+    s = content_id_or_url.strip()
+    if "/explore/" in s:
+        s = s.split("/explore/", 1)[1]
+    if "/discovery/item/" in content_id_or_url:
+        s = content_id_or_url.split("/discovery/item/", 1)[1]
+    return s.split("?", 1)[0].strip("/").strip()
+
+
+def _image_urls(inner: dict) -> list[str]:
+    out: list[str] = []
+    seen: set[str] = set()
+    for x in inner.get("image_url_list") or []:
+        u = x.get("image_url") if isinstance(x, dict) else x
+        if u and u not in seen:
+            seen.add(u)
+            out.append(u)
+    return out
+
+
+def _video_urls(inner: dict) -> list[str]:
+    out: list[str] = []
+    for x in inner.get("video_url_list") or []:
+        u = x.get("video_url") if isinstance(x, dict) else x
+        if u:
+            out.append(u)
+    return out
+
+
+def parse_detail_response(response: dict, fallback_content_id: str = "") -> Post:
+    """把 detail 接口返回(信封 {code,msg,data:{data:{...}}})解析成 Post。"""
+    if not isinstance(response, dict):
+        raise CrawlerError("bad_response: not a dict")
+    code = response.get("code")
+    if code not in (0, "0"):
+        raise CrawlerError(f"business_error: code={code} msg={response.get('msg')}")
+    inner = ((response.get("data") or {}).get("data")) or {}
+    if not inner:
+        raise CrawlerError("empty_detail: data.data is empty")
+
+    content_id = inner.get("channel_content_id") or fallback_content_id
+    link = inner.get("content_link") or (
+        f"https://www.xiaohongshu.com/explore/{content_id}" if content_id else ""
+    )
+    return Post(
+        id=f"xhs_{content_id}",
+        platform="xiaohongshu",
+        url=link,
+        content_id=content_id,
+        title=inner.get("title") or "",
+        content_type=inner.get("content_type") or "",
+        body_text=inner.get("body_text") or "",
+        topic_list=list(inner.get("topic_list") or []),
+        image_urls=_image_urls(inner),
+        video_urls=_video_urls(inner),
+        author_id=inner.get("channel_account_id"),
+        author_name=inner.get("channel_account_name"),
+        raw=response,
+    )
+
+
+def fetch_post_detail(
+    content_id_or_url: str,
+    *,
+    settings: Optional[Settings] = None,
+    http_client: Any = None,
+    rate_limiter: Optional[RateLimiter] = None,
+    env_file: str = ".env",
+) -> Post:
+    """真实拉取一条小红书帖子详情,返回 Post。"""
+    settings = settings or Settings.from_env(env_file)
+    content_id = parse_content_id(content_id_or_url)
+    if not content_id:
+        raise CrawlerError(f"cannot parse content_id from: {content_id_or_url}")
+
+    rate_limiter = rate_limiter or RateLimiter()
+    rate_limiter.wait("xhs_detail")
+
+    owns_client = http_client is None
+    client = http_client or httpx.Client()
+    try:
+        url = urljoin(settings.crawler_base_url, DETAIL_PATH)
+        resp = client.post(
+            url,
+            json={"content_id": content_id},
+            headers={"Content-Type": "application/json"},
+            timeout=settings.crawler_timeout,
+        )
+        resp.raise_for_status()
+        data = resp.json()
+    except httpx.HTTPError as exc:
+        raise CrawlerError(f"http_error: {exc}") from exc
+    except ValueError as exc:
+        raise CrawlerError("bad_json") from exc
+    finally:
+        if owns_client:
+            client.close()
+
+    return parse_detail_response(data, fallback_content_id=content_id)

+ 169 - 0
creation_knowledge/integrations/db.py

@@ -0,0 +1,169 @@
+"""过程库 CkStore:写 / 读 creation_knowledge.ck_post、ck_knowledge_item。
+
+目标实例是 Greenplum(PG12 内核),注意:
+  - 不用 INSERT ... ON CONFLICT(Greenplum 分布表支持不稳):upsert = 先 UPDATE,rowcount=0 再 INSERT。
+  - 不更新分布键 id。
+  - JSONB 列用 psycopg2.extras.Json 包装。
+连接 / JSONB / 参数化风格对齐 ContentFindAgentNew 的 database_runtime.py。
+"""
+from __future__ import annotations
+
+from typing import Any, Callable, Optional
+
+import psycopg2
+import psycopg2.extras
+
+from creation_knowledge.config import PgConfig
+from creation_knowledge.models import Post
+
+ConnectionFactory = Callable[[], Any]
+
+
+def _connect(cfg: PgConfig) -> Any:
+    return psycopg2.connect(
+        host=cfg.host,
+        port=cfg.port,
+        user=cfg.user,
+        password=cfg.password,
+        dbname=cfg.database,
+        connect_timeout=cfg.timeout,
+        options=f"-c search_path={cfg.schema}",
+    )
+
+
+class CkStore:
+    def __init__(
+        self,
+        config: PgConfig,
+        connection_factory: ConnectionFactory | None = None,
+    ) -> None:
+        self.config = config
+        self._connection_factory = connection_factory or (lambda: _connect(config))
+
+    # ---------- 写 ----------
+    def upsert_post(self, post: Post) -> None:
+        """落 fetch 产物:raw 等基础字段,stage=fetched。先 UPDATE 后 INSERT。"""
+        with self._connection_factory() as conn:
+            with conn.cursor() as cur:
+                cur.execute(
+                    "UPDATE ck_post SET platform=%s, url=%s, raw=%s, "
+                    "updated_at=now() WHERE id=%s",
+                    (post.platform, post.url, psycopg2.extras.Json(post.raw), post.id),
+                )
+                if cur.rowcount == 0:
+                    cur.execute(
+                        "INSERT INTO ck_post (id, platform, url, raw, stage) "
+                        "VALUES (%s, %s, %s, %s, 'fetched')",
+                        (post.id, post.platform, post.url,
+                         psycopg2.extras.Json(post.raw)),
+                    )
+            conn.commit()
+
+    def set_extracted(self, post_id: str, extracted: dict, stage: str = "extracted") -> None:
+        self._set_json(post_id, "extracted", extracted, stage)
+
+    def set_screening(self, post_id: str, screening: dict, stage: str = "screened") -> None:
+        self._set_json(post_id, "screening", screening, stage)
+
+    def _set_json(self, post_id: str, column: str, value: dict, stage: str) -> None:
+        with self._connection_factory() as conn:
+            with conn.cursor() as cur:
+                cur.execute(
+                    f"UPDATE ck_post SET {column}=%s, stage=%s, updated_at=now() "
+                    "WHERE id=%s",
+                    (psycopg2.extras.Json(value), stage, post_id),
+                )
+            conn.commit()
+
+    def update_stage(self, post_id: str, stage: str) -> None:
+        with self._connection_factory() as conn:
+            with conn.cursor() as cur:
+                cur.execute(
+                    "UPDATE ck_post SET stage=%s, updated_at=now() WHERE id=%s",
+                    (stage, post_id),
+                )
+            conn.commit()
+
+    def save_item(
+        self,
+        post_id: str,
+        item: dict,
+        deconstruction: Optional[dict] = None,
+        ingest_payload: Optional[dict] = None,
+    ) -> int:
+        """插入一条知识片段,返回自增 id。ingest_status 默认 pending。"""
+        with self._connection_factory() as conn:
+            with conn.cursor() as cur:
+                cur.execute(
+                    "INSERT INTO ck_knowledge_item "
+                    "(post_id, item, deconstruction, ingest_payload, ingest_status) "
+                    "VALUES (%s, %s, %s, %s, 'pending') RETURNING id",
+                    (
+                        post_id,
+                        psycopg2.extras.Json(item),
+                        psycopg2.extras.Json(deconstruction) if deconstruction else None,
+                        psycopg2.extras.Json(ingest_payload) if ingest_payload else None,
+                    ),
+                )
+                item_id = cur.fetchone()[0]
+            conn.commit()
+            return int(item_id)
+
+    def update_item_ingest(
+        self, item_id: int, status: str, knowledge_id: Optional[str] = None
+    ) -> None:
+        with self._connection_factory() as conn:
+            with conn.cursor() as cur:
+                cur.execute(
+                    "UPDATE ck_knowledge_item SET ingest_status=%s, knowledge_id=%s, "
+                    "updated_at=now() WHERE id=%s",
+                    (status, knowledge_id, item_id),
+                )
+            conn.commit()
+
+    def delete_post(self, post_id: str) -> None:
+        """删除帖子及其片段(用于校验探测的清理)。"""
+        with self._connection_factory() as conn:
+            with conn.cursor() as cur:
+                cur.execute("DELETE FROM ck_knowledge_item WHERE post_id=%s", (post_id,))
+                cur.execute("DELETE FROM ck_post WHERE id=%s", (post_id,))
+            conn.commit()
+
+    # ---------- 读 ----------
+    def read_post(self, post_id: str) -> Optional[dict]:
+        return self._fetch_one(
+            "SELECT * FROM ck_post WHERE id=%s", (post_id,)
+        )
+
+    def read_items(self, post_id: str) -> list[dict]:
+        return self._fetch_all(
+            "SELECT * FROM ck_knowledge_item WHERE post_id=%s ORDER BY id", (post_id,)
+        )
+
+    def list_posts(self, limit: int = 100) -> list[dict]:
+        return self._fetch_all(
+            "SELECT id, platform, url, stage, created_at, updated_at "
+            "FROM ck_post ORDER BY created_at DESC LIMIT %s",
+            (limit,),
+        )
+
+    def table_columns(self, table: str) -> list[str]:
+        rows = self._fetch_all(
+            "SELECT column_name FROM information_schema.columns "
+            "WHERE table_schema=%s AND table_name=%s ORDER BY ordinal_position",
+            (self.config.schema, table),
+        )
+        return [r["column_name"] for r in rows]
+
+    def _fetch_one(self, sql: str, params: tuple) -> Optional[dict]:
+        with self._connection_factory() as conn:
+            with conn.cursor(cursor_factory=psycopg2.extras.RealDictCursor) as cur:
+                cur.execute(sql, params)
+                row = cur.fetchone()
+                return dict(row) if row else None
+
+    def _fetch_all(self, sql: str, params: tuple) -> list[dict]:
+        with self._connection_factory() as conn:
+            with conn.cursor(cursor_factory=psycopg2.extras.RealDictCursor) as cur:
+                cur.execute(sql, params)
+                return [dict(r) for r in cur.fetchall()]

+ 155 - 0
creation_knowledge/integrations/extractor.py

@@ -0,0 +1,155 @@
+"""多模态内容理解:把帖子的文本 + 图片(+视频) 交给 Gemini,提取真正的创作知识。
+
+走 OpenRouter /chat/completions,模型 google/gemini-3-flash-preview。
+消息格式(system + user.content 为 [text, image_url...] 列表)对齐 ContentFindAgentNew
+的 gemini_video.GeminiVideoClient,但提示词换成「提取创作知识」,不做相关性审核。
+
+关键:知识常在图片里,不能只读 body_text —— 见 创作知识-重构设计.md。
+"""
+from __future__ import annotations
+
+import json
+from typing import Any, Callable, Mapping, Optional
+
+import httpx
+
+from creation_knowledge.config import load_env_file
+from creation_knowledge.models import ExtractedContent, Post
+
+DEFAULT_MODEL = "google/gemini-3-flash-preview"
+DEFAULT_BASE_URL = "https://openrouter.ai/api/v1"
+DEFAULT_TIMEOUT = 90.0
+MAX_IMAGES = 6
+
+_SYSTEM_PROMPT = (
+    "你是创作知识提取助手。给你一篇小红书帖子(标题、正文、图片),"
+    "请提取出其中真正能指导『如何创作内容』的知识。"
+    "知识往往在图片里而不在正文里。只输出一个 JSON 对象,不要任何解释或 markdown。"
+)
+
+_USER_TMPL = (
+    "帖子标题:{title}\n"
+    "话题:{topics}\n"
+    "正文(可能为空或只是话题串,不要只看它):\n{body}\n\n"
+    "请综合图片内容,输出如下 JSON:\n"
+    '{{"text": "把这篇帖子真正讲的创作知识完整、忠实地讲清楚;原文没有的不要编造", '
+    '"from_image": "仅来自图片的知识要点;没有则空字符串", '
+    '"from_video": "仅来自视频的知识要点;没有则空字符串", '
+    '"is_empty": "true 或 false:多模态看完后是否没有任何有效创作知识"}}'
+)
+
+
+class ExtractorError(RuntimeError):
+    pass
+
+
+def _strip_to_json(text: str) -> dict:
+    """从模型输出里取出 JSON 对象(容忍 ```json fences 或前后多余文本)。"""
+    s = text.strip()
+    if s.startswith("```"):
+        s = s.split("```", 2)[1] if s.count("```") >= 2 else s.strip("`")
+        if s.lstrip().lower().startswith("json"):
+            s = s.lstrip()[4:]
+    start, end = s.find("{"), s.rfind("}")
+    if start == -1 or end == -1 or end < start:
+        raise ExtractorError(f"no json object in model output: {text[:120]!r}")
+    return json.loads(s[start : end + 1])
+
+
+def _to_bool(value: Any) -> bool:
+    if isinstance(value, bool):
+        return value
+    return str(value).strip().lower() in ("1", "true", "yes", "是")
+
+
+class GeminiExtractor:
+    def __init__(
+        self,
+        *,
+        api_key: str,
+        model: str = DEFAULT_MODEL,
+        base_url: str = DEFAULT_BASE_URL,
+        timeout_seconds: float = DEFAULT_TIMEOUT,
+        http_post: Callable[..., Any] = httpx.post,
+        max_images: int = MAX_IMAGES,
+    ) -> None:
+        if not api_key:
+            raise ExtractorError("missing OPENROUTER_API_KEY")
+        self.api_key = api_key
+        self.model = model
+        self.base_url = base_url.rstrip("/")
+        self.timeout_seconds = timeout_seconds
+        self.http_post = http_post
+        self.max_images = max_images
+
+    @classmethod
+    def from_env(cls, env: Mapping[str, str] | None = None, env_file: str = ".env") -> "GeminiExtractor":
+        source = dict(load_env_file(env_file))
+        if env:
+            source.update(env)
+        api_key = source.get("OPENROUTER_API_KEY") or source.get("OPEN_ROUTER_API_KEY") or ""
+        return cls(
+            api_key=api_key,
+            model=source.get("CONTENT_AGENT_VIDEO_LLM_MODEL") or DEFAULT_MODEL,
+            base_url=source.get("OPENROUTER_BASE_URL") or DEFAULT_BASE_URL,
+            timeout_seconds=float(source.get("CONTENT_AGENT_VIDEO_LLM_TIMEOUT_SECONDS") or DEFAULT_TIMEOUT),
+        )
+
+    def build_messages(self, post: Post) -> list[dict]:
+        user_text = _USER_TMPL.format(
+            title=post.title or "(无)",
+            topics="、".join(post.topic_list) or "(无)",
+            body=post.body_text or "(空)",
+        )
+        parts: list[dict] = [{"type": "text", "text": user_text}]
+        for url in post.image_urls[: self.max_images]:
+            parts.append({"type": "image_url", "image_url": {"url": url}})
+        return [
+            {"role": "system", "content": _SYSTEM_PROMPT},
+            {"role": "user", "content": parts},
+        ]
+
+    def extract(self, post: Post) -> ExtractedContent:
+        messages = self.build_messages(post)
+        last_exc: Optional[Exception] = None
+        for attempt in range(2):
+            try:
+                resp = self.http_post(
+                    f"{self.base_url}/chat/completions",
+                    headers={
+                        "Authorization": f"Bearer {self.api_key}",
+                        "Content-Type": "application/json",
+                    },
+                    json={"model": self.model, "messages": messages},
+                    timeout=self.timeout_seconds,
+                )
+                resp.raise_for_status()
+                content = resp.json()["choices"][0]["message"]["content"]
+                data = _strip_to_json(content)
+                return ExtractedContent(
+                    text=str(data.get("text") or ""),
+                    from_image=str(data.get("from_image") or ""),
+                    from_video=str(data.get("from_video") or ""),
+                    is_empty=_to_bool(data.get("is_empty")),
+                )
+            except httpx.HTTPError as exc:
+                last_exc = exc
+                if attempt == 0:
+                    continue
+                raise ExtractorError(f"gemini_http_error: {exc}") from exc
+            except (KeyError, IndexError, TypeError, ValueError) as exc:
+                last_exc = exc
+                if attempt == 0:
+                    continue
+                raise ExtractorError(f"gemini_response_invalid: {exc}") from exc
+        raise ExtractorError(f"gemini_unknown_error: {last_exc}")
+
+
+def extract_content(
+    post: Post,
+    *,
+    client: Optional[GeminiExtractor] = None,
+    env_file: str = ".env",
+) -> ExtractedContent:
+    client = client or GeminiExtractor.from_env(env_file=env_file)
+    return client.extract(post)

+ 82 - 0
creation_knowledge/models.py

@@ -0,0 +1,82 @@
+"""流水线各环节的数据结构(pydantic)。字段对齐业务设计 创作知识-重构设计.md。"""
+from __future__ import annotations
+
+from typing import Literal, Optional
+
+from pydantic import BaseModel, Field
+
+KnowledgeType = Literal["what", "why", "how"]
+ScopeType = Literal["substance", "form", "feeling", "effect", "intent"]
+Stage = Literal["灵感", "选题", "脚本"]
+
+
+class Post(BaseModel):
+    """fetch_post_detail 的产物:一条帖子的原始内容(文本 + 图片 + 视频)。"""
+
+    id: str  # xhs_<content_id>,复用为 ingest source.id
+    platform: str = "xiaohongshu"
+    url: str
+    content_id: str
+    title: str = ""
+    content_type: str = ""  # video / 图文
+    body_text: str = ""
+    topic_list: list[str] = Field(default_factory=list)
+    image_urls: list[str] = Field(default_factory=list)
+    video_urls: list[str] = Field(default_factory=list)
+    author_id: Optional[str] = None
+    author_name: Optional[str] = None
+    raw: dict = Field(default_factory=dict)  # 原始响应,整体落 ck_post.raw
+
+
+class ExtractedContent(BaseModel):
+    """extract_content 的产物:多模态汇总后的真实内容。不直接用 body_text。"""
+
+    text: str = ""  # 汇总后的正文/讲解
+    from_image: str = ""  # 图片里提取到的知识要点
+    from_video: str = ""  # 视频里提取到的知识要点
+    is_empty: bool = False  # 多模态提取后仍无有效内容
+
+
+class ScreeningResult(BaseModel):
+    """screen_post 的产物。"""
+
+    passed: bool
+    score: int = 0
+    reason: str = ""
+
+
+class KnowledgeItem(BaseModel):
+    """split_post 拆出的一个知识片段。knowledge_types 必须与非空的 what/why/how 一致。"""
+
+    title: str
+    knowledge_types: list[KnowledgeType]
+    what: Optional[str] = None
+    why: Optional[str] = None
+    how: Optional[str] = None
+    evidence: list[str] = Field(default_factory=list)
+
+
+class Scope(BaseModel):
+    scope_type: ScopeType
+    value: str  # 具体标签,不只是大类名
+
+
+class Deconstruction(BaseModel):
+    """deconstruct_item 的产物:阶段 + 作用域。"""
+
+    stages: list[Stage] = Field(default_factory=list)
+    scopes: list[Scope] = Field(default_factory=list)
+    stage_reason: str = ""
+    scope_reason: str = ""
+
+
+class IngestPayload(BaseModel):
+    """build_ingest_payload 的产物:对齐 创作知识-重构设计.md §6 的 ingest 请求体。"""
+
+    source: dict
+    title: str
+    content: str  # JSON 字符串 {"what":...,"why":...,"how":...}
+    dim_attributes: list[str]
+    dim_creations: list[str]
+    scopes: list[dict]
+    custom_ext: list[dict] = Field(default_factory=list)

+ 17 - 0
pyproject.toml

@@ -0,0 +1,17 @@
+[project]
+name = "creation-knowledge"
+version = "0.1.0"
+description = "从帖子里拆出可指导创作的知识,组装成 ingest payload 入库。"
+requires-python = ">=3.11"
+dependencies = [
+  "httpx>=0.27.0",
+  "pydantic>=2.8.0",
+  "psycopg2-binary>=2.9.9",
+  "fastapi>=0.115.0",
+  "uvicorn>=0.30.0",
+  "pytest>=8.2.0",
+]
+
+[tool.pytest.ini_options]
+testpaths = ["tests"]
+pythonpath = ["."]

+ 46 - 0
scripts/smoke_extract.py

@@ -0,0 +1,46 @@
+"""M3 真实验收:对样例帖子调真实 Gemini,打印多模态提取结果。
+
+须在能联网调 OpenRouter 的云端跑(会产生 API 费用)。
+用 fixture 解析出 Post(含 image_urls),避免重复爬虫调用。
+
+用法:
+    python scripts/smoke_extract.py [env_file] [content_id ...]
+默认跑「拾意」两条空正文帖(验收点:from_image 非空、is_empty=false)。
+"""
+from __future__ import annotations
+
+import json
+import sys
+from pathlib import Path
+
+from creation_knowledge.integrations.crawler import parse_detail_response
+from creation_knowledge.integrations.extractor import GeminiExtractor
+
+FIXTURES = Path(__file__).resolve().parent.parent / "tests" / "fixtures"
+DEFAULT_IDS = ["67e2e39b0000000003028ff0", "680659e8000000001a007a11"]
+
+
+def main() -> int:
+    args = sys.argv[1:]
+    env_file = args[0] if args and args[0].endswith(".env") else ".env"
+    ids = [a for a in args if not a.endswith(".env")] or DEFAULT_IDS
+
+    client = GeminiExtractor.from_env(env_file=env_file)
+    print(f"[model] {client.model}  base={client.base_url}\n")
+
+    for cid in ids:
+        resp = json.loads((FIXTURES / f"xhs_case_{cid}.json").read_text("utf-8"))
+        post = parse_detail_response(resp, fallback_content_id=cid)
+        print(f"==== {post.id}  作者={post.author_name}  图片={len(post.image_urls)} ====")
+        print(f"标题: {post.title}")
+        print(f"body_text(原文): {post.body_text[:50]!r}")
+        out = client.extract(post)
+        print(f"  is_empty   : {out.is_empty}")
+        print(f"  from_image : {out.from_image[:200]}")
+        print(f"  text       : {out.text[:200]}")
+        print()
+    return 0
+
+
+if __name__ == "__main__":
+    raise SystemExit(main())

+ 79 - 0
scripts/validate_db.py

@@ -0,0 +1,79 @@
+"""M1 校验:连库、确认 schema/表/列齐全、做一次可逆写探测。
+
+用法(在能连到 RDS 的机器上,如海外开发机):
+    python scripts/validate_db.py [path/to/.env]
+"""
+from __future__ import annotations
+
+import sys
+
+from creation_knowledge.config import PgConfig
+from creation_knowledge.integrations.db import CkStore, _connect
+from creation_knowledge.models import Post
+
+EXPECTED = {
+    "ck_post": {"id", "platform", "url", "raw", "extracted", "screening",
+                "stage", "created_at", "updated_at"},
+    "ck_knowledge_item": {"id", "post_id", "item", "deconstruction",
+                          "ingest_payload", "ingest_status", "knowledge_id",
+                          "created_at", "updated_at"},
+}
+PROBE_ID = "_validate_probe"
+
+
+def main() -> int:
+    env_file = sys.argv[1] if len(sys.argv) > 1 else ".env"
+    cfg = PgConfig.from_env(env_file)
+    print(f"[cfg] host={cfg.host} db={cfg.database} schema={cfg.schema} user={cfg.user}")
+
+    # 1) 连通 + 版本
+    with _connect(cfg) as conn:
+        with conn.cursor() as cur:
+            cur.execute("SELECT version()")
+            print("[conn] OK:", cur.fetchone()[0][:70])
+
+    store = CkStore(cfg)
+
+    # 2) 表/列齐全
+    ok = True
+    for table, expected_cols in EXPECTED.items():
+        cols = set(store.table_columns(table))
+        if not cols:
+            print(f"[schema] MISSING table: {cfg.schema}.{table}")
+            ok = False
+            continue
+        missing = expected_cols - cols
+        if missing:
+            print(f"[schema] {table} 缺列: {sorted(missing)}")
+            ok = False
+        else:
+            print(f"[schema] {table} OK ({len(cols)} cols)")
+    if not ok:
+        print("RESULT: FAIL(表结构不符)")
+        return 1
+
+    # 3) 可逆写探测:插入一帖+一片段,读回,删除
+    store.delete_post(PROBE_ID)  # 清理上次残留
+    try:
+        store.upsert_post(Post(id=PROBE_ID, url="probe://x", content_id="x",
+                               raw={"probe": True}))
+        store.set_extracted(PROBE_ID, {"text": "probe", "is_empty": False})
+        item_id = store.save_item(PROBE_ID, {"title": "probe item",
+                                             "knowledge_types": ["how"]},
+                                  {"stages": ["脚本"]}, {"title": "probe"})
+        post = store.read_post(PROBE_ID)
+        items = store.read_items(PROBE_ID)
+        assert post and post["stage"] == "extracted", post
+        assert items and items[0]["id"] == item_id, items
+        print(f"[write] OK: post.stage={post['stage']}, item_id={item_id}, "
+              f"ingest_status={items[0]['ingest_status']}")
+    finally:
+        store.delete_post(PROBE_ID)
+        print("[write] 探测数据已清理")
+
+    print("RESULT: PASS")
+    return 0
+
+
+if __name__ == "__main__":
+    raise SystemExit(main())

+ 48 - 0
sql/creation_knowledge.sql

@@ -0,0 +1,48 @@
+-- 创作知识 · 过程库建表 DDL
+-- 目标实例:open_aigc(阿里云 AnalyticDB for PostgreSQL / Greenplum 7.0.0,PG12 内核,新加坡)
+-- 连接:OPEN_AIGC_PG_*(用户 aiddit_aigc 已确认有 CREATE 权限)
+--
+-- Greenplum 注意事项:
+--   1. 每张表需 DISTRIBUTED BY;主键/唯一键必须包含分布列。
+--   2. 不依赖外键强约束(Greenplum 不强制 FK),post_id ↔ ck_post.id 的关系由应用维护。
+--   3. updated_at 由应用在更新时写入(不用触发器,保持简单)。
+--   4. 本实例无 pgvector;embedding 一期不做,需要时另议(非 pgvector 路线)。
+
+CREATE SCHEMA IF NOT EXISTS creation_knowledge;
+SET search_path TO creation_knowledge;
+
+-- 每帖一行:各环节产物存 JSONB,stage 记录处理到哪一步
+CREATE TABLE IF NOT EXISTS ck_post (
+    id          text        NOT NULL,                 -- xhs_<content_id>,同帖唯一,复用为 ingest source.id
+    platform    text,                                 -- xiaohongshu 等
+    url         text,                                 -- 原始链接
+    raw         jsonb,                                 -- fetch_post_detail 原始响应
+    extracted   jsonb,                                -- extract_content 多模态产物
+    screening   jsonb,                                -- screen_post 结果 {passed,score,reason}
+    stage       text        NOT NULL DEFAULT 'fetched', -- fetched/extracted/screened/split/done/rejected/failed
+    created_at  timestamptz NOT NULL DEFAULT now(),
+    updated_at  timestamptz NOT NULL DEFAULT now(),
+    PRIMARY KEY (id)
+) DISTRIBUTED BY (id);
+
+CREATE INDEX IF NOT EXISTS idx_ck_post_stage    ON ck_post (stage);
+CREATE INDEX IF NOT EXISTS idx_ck_post_platform ON ck_post (platform);
+
+-- 每条知识片段一行:拆分+解构产物,以及组装好的 ingest payload(开发期的最终落点)
+CREATE TABLE IF NOT EXISTS ck_knowledge_item (
+    id              bigserial,                          -- 片段自增 ID
+    post_id         text        NOT NULL,               -- → ck_post.id(同帖多片段复用同一 source)
+    item            jsonb,                              -- 拆分结果 title/knowledge_types/what/why/how/evidence
+    deconstruction  jsonb,                              -- 解构结果 stages/scopes/reason
+    ingest_payload  jsonb,                              -- 组装后的 ingest 请求体(开发期最终产物)
+    ingest_status   text        NOT NULL DEFAULT 'pending', -- pending(未发送) / ingested / failed
+    knowledge_id    text,                               -- ingest API 返回的知识 ID(上线后才有)
+    created_at      timestamptz NOT NULL DEFAULT now(),
+    updated_at      timestamptz NOT NULL DEFAULT now(),
+    PRIMARY KEY (id)
+) DISTRIBUTED BY (id);
+
+CREATE INDEX IF NOT EXISTS idx_ck_item_post   ON ck_knowledge_item (post_id);
+CREATE INDEX IF NOT EXISTS idx_ck_item_status ON ck_knowledge_item (ingest_status);
+
+-- 回滚:DROP SCHEMA creation_knowledge CASCADE;

File diff ditekan karena terlalu besar
+ 0 - 0
tests/fixtures/xhs_case_67e2e39b0000000003028ff0.json


File diff ditekan karena terlalu besar
+ 0 - 0
tests/fixtures/xhs_case_67e4bdf50000000006028a59.json


File diff ditekan karena terlalu besar
+ 0 - 0
tests/fixtures/xhs_case_680659e8000000001a007a11.json


File diff ditekan karena terlalu besar
+ 0 - 0
tests/fixtures/xhs_case_698481e1000000000a02a7c1.json


File diff ditekan karena terlalu besar
+ 0 - 0
tests/fixtures/xhs_case_699308fa0000000016009697.json


+ 66 - 0
tests/test_crawler.py

@@ -0,0 +1,66 @@
+"""M2 离线测试:用 5 个真实 capture 验证 parse_detail_response 字段映射。"""
+from __future__ import annotations
+
+import json
+from pathlib import Path
+
+import pytest
+
+from creation_knowledge.integrations.crawler import (
+    parse_content_id,
+    parse_detail_response,
+)
+
+FIXTURES = Path(__file__).parent / "fixtures"
+
+# content_id -> (期望作者, 标题里应出现的子串)
+EXPECTED = {
+    "67e4bdf50000000006028a59": ("海狸教自媒体运营", "短视频脚本"),
+    "698481e1000000000a02a7c1": ("Irvin是个编剧(接稿版)", "叙事结构"),
+    "67e2e39b0000000003028ff0": ("拾意", "剧本创作"),
+    "699308fa0000000016009697": ("方圆的增长飞轮", "选题"),
+    "680659e8000000001a007a11": ("故事设计原理拆解学习"[:2], "故事设计"),
+}
+
+
+def _load(content_id: str) -> dict:
+    return json.loads((FIXTURES / f"xhs_case_{content_id}.json").read_text("utf-8"))
+
+
+@pytest.mark.parametrize("content_id", list(EXPECTED))
+def test_parse_detail_fields(content_id: str):
+    # 重抓的 xhs_case_*.json 即原始响应 {code,msg,data},无 response 包裹
+    response = _load(content_id)
+    post = parse_detail_response(response, fallback_content_id=content_id)
+
+    assert post.id == f"xhs_{content_id}"
+    assert post.platform == "xiaohongshu"
+    assert post.content_id == content_id
+    assert content_id in post.url
+    assert post.title, "title 不应为空"
+    _, title_sub = EXPECTED[content_id]
+    assert title_sub in post.title
+    assert post.raw.get("code") == 0
+
+
+def test_authors():
+    for cid, (author, _) in EXPECTED.items():
+        post = parse_detail_response(_load(cid), fallback_content_id=cid)
+        if cid in ("67e4bdf50000000006028a59", "698481e1000000000a02a7c1",
+                   "67e2e39b0000000003028ff0", "699308fa0000000016009697"):
+            assert post.author_name == author
+
+
+def test_shiyi_posts_text_sparse():
+    """拾意两条正文几乎只有话题串——M3 多模态提取存在的理由。"""
+    for cid in ("67e2e39b0000000003028ff0", "680659e8000000001a007a11"):
+        post = parse_detail_response(_load(cid), fallback_content_id=cid)
+        stripped = post.body_text.replace("#", "").replace("话题", "").strip()
+        assert len(stripped) < 40, f"{cid} body_text 应很稀疏: {post.body_text!r}"
+
+
+def test_parse_content_id_from_url():
+    url = ("https://www.xiaohongshu.com/explore/67e4bdf50000000006028a59"
+           "?xsec_token=ABC=&xsec_source=pc_like")
+    assert parse_content_id(url) == "67e4bdf50000000006028a59"
+    assert parse_content_id("67e4bdf50000000006028a59") == "67e4bdf50000000006028a59"

+ 80 - 0
tests/test_extractor.py

@@ -0,0 +1,80 @@
+"""M3 离线测试:注入假 http_post,验证消息构造 + JSON 解析(不调真实 Gemini)。
+
+真实 Gemini 验收见 scripts/smoke_extract.py(须在能联网调 OpenRouter 的云端跑)。
+"""
+from __future__ import annotations
+
+import json
+
+from creation_knowledge.integrations.extractor import GeminiExtractor
+from creation_knowledge.models import Post
+
+
+class _FakeResp:
+    def __init__(self, payload: dict):
+        self._payload = payload
+
+    def raise_for_status(self):
+        return None
+
+    def json(self):
+        return self._payload
+
+
+def _fake_post_returning(content: str):
+    captured = {}
+
+    def _post(url, headers=None, json=None, timeout=None):
+        captured["url"] = url
+        captured["headers"] = headers
+        captured["json"] = json
+        return _FakeResp({"choices": [{"message": {"content": content}}]})
+
+    return _post, captured
+
+
+def _post(**kw) -> Post:
+    return Post(
+        id="xhs_x", url="u", content_id="x",
+        title="只要学会这几样,写短视频脚本真的不难",
+        body_text="", topic_list=["短视频"],
+        image_urls=["https://img/1.webp", "https://img/2.webp"],
+        **kw,
+    )
+
+
+def test_build_messages_has_text_and_images():
+    client = GeminiExtractor(api_key="k", http_post=lambda **kw: None)
+    msgs = client.build_messages(_post())
+    assert msgs[0]["role"] == "system"
+    user_parts = msgs[1]["content"]
+    assert user_parts[0]["type"] == "text"
+    images = [p for p in user_parts if p["type"] == "image_url"]
+    assert len(images) == 2
+    assert images[0]["image_url"]["url"] == "https://img/1.webp"
+
+
+def test_parse_plain_json():
+    fake, captured = _fake_post_returning(
+        json.dumps({"text": "脚本要素:标题/地点/分镜", "from_image": "九宫格讲了6要素",
+                    "from_video": "", "is_empty": False}, ensure_ascii=False)
+    )
+    client = GeminiExtractor(api_key="k", http_post=fake)
+    out = client.extract(_post())
+    assert out.is_empty is False
+    assert "from_image" and out.from_image
+    assert "脚本" in out.text
+    # 鉴权头 + 模型名正确传入
+    assert captured["headers"]["Authorization"].startswith("Bearer ")
+    assert captured["json"]["model"]
+
+
+def test_parse_json_with_code_fence():
+    fenced = "```json\n" + json.dumps(
+        {"text": "x", "from_image": "y", "from_video": "", "is_empty": "false"},
+        ensure_ascii=False) + "\n```"
+    fake, _ = _fake_post_returning(fenced)
+    client = GeminiExtractor(api_key="k", http_post=fake)
+    out = client.extract(_post())
+    assert out.is_empty is False
+    assert out.from_image == "y"

+ 436 - 0
创作知识-重构设计.md

@@ -0,0 +1,436 @@
+# 创作知识 · 知识重构设计
+
+> 当前版本先不做 Query、不做搜索、不做游走。  
+> 输入直接是已经搜到的帖子链接,输出是可以调用入库接口的知识数据。
+
+## 1. 主流程
+
+```text
+帖子链接
+  -> 0. 多模态内容理解(文本 + 图片 + 视频 -> Gemini(gemini-3-flash-preview))
+  -> 1. 筛选
+  -> 2. 帖子拆分
+  -> 3. 帖子解构
+  -> 4. 组装入库数据
+```
+
+各环节分别做:
+
+| 环节 | 做什么 | 产出 |
+|---|---|---|
+| 多模态内容理解 | 把帖子的文本、图片、视频一起交给 Gemini(gemini-3-flash-preview),提取出真正的内容 | extracted_content |
+| 筛选 | 判断帖子是不是有效创作知识 | passed / rejected |
+| 帖子拆分 | 把帖子拆成 What / Why / How 知识片段 | knowledge_items |
+| 帖子解构 | 判断每个知识片段属于哪些阶段和作用域 | stages / scopes |
+| 组装入库数据 | 转成 `POST /api/v1/knowledge/ingest` 请求体 | ingest payload |
+
+> ⚠️ 关键约束:**知识内容主要在图片或视频里,不在 `body_text` 里**。小红书图文/视频笔记的 `body_text` 往往只是话题串(例如 `#短剧编剧# #写作#`),正文几乎为空。因此**不可以只读 `body_text`**——文本、图片、视频都必须交给 Gemini(gemini-3-flash-preview) 多模态理解,由它提取真正的内容,后续筛选 / 拆分都基于这份提取结果,而不是原始 `body_text`。
+
+## 2. 输入案例
+
+这几个链接先作为标注样例,用来校准 What / Why / How 的拆分规则。共 4 种案例(5 个链接):
+
+| 标注 | content_id | 链接 |
+|---|---|---|
+| HOW + WHAT | `67e4bdf50000000006028a59` | https://www.xiaohongshu.com/explore/67e4bdf50000000006028a59?xsec_token=ABvi6o6tDVgqSVV7eLImIcQxoVhayPv3GGE7mK9I28EqI=&xsec_source=pc_like |
+| HOW + WHAT | `698481e1000000000a02a7c1` | https://www.xiaohongshu.com/explore/698481e1000000000a02a7c1?xsec_token=ABrLeB8aB0ggoeNA0cmGv0E6NDl0CLhuLl4KqS-Mhd4js=&xsec_source=pc_like |
+| HOW | `67e2e39b0000000003028ff0` | https://www.xiaohongshu.com/explore/67e2e39b0000000003028ff0?xsec_token=ABcF_yNIoadKLJ4LfS3EhDo0GVaz-nFK2mlMN9qr-0j_4=&xsec_source=pc_like |
+| WHY | `699308fa0000000016009697` | https://www.xiaohongshu.com/explore/699308fa0000000016009697?xsec_token=ABLOnWGgs67c1SediQp7db7vZVmdOFs9Fm1m46ONG7GCA=&xsec_source=pc_like |
+| HOW + WHY + WHAT | `680659e8000000001a007a11` | https://www.xiaohongshu.com/explore/680659e8000000001a007a11?xsec_token=ABrdoPHvLAxNV-RI0zHL5Pg6nMe98RL32BksjutBYHvvY=&xsec_source=pc_like |
+
+> 抓取方式:`POST http://crawler.aiddit.com/crawler/xiao_hong_shu/detail`,body 仅需 `content_id`(即上表 content_id 列),无 token,限流 ≥15s。重抓样本落在 `数据接口与来源/captures/xhs_case_<content_id>.json`。
+
+输入结构可以保持很简单:
+
+```jsonc
+[
+  {
+    "source": "xiaohongshu",
+    "url": "https://www.xiaohongshu.com/explore/...",
+    "label": ["how", "what"]
+  }
+]
+```
+
+`label` 只是人工样例标注,用于调试和验收,不是线上必填字段。
+
+## 3. 核心定义
+
+### 3.1 知识类型:What / Why / How
+
+这里的“知识类型”只指 What / Why / How。
+
+| 类型 | 判断标准 | 常见内容 |
+|---|---|---|
+| What | 这是什么、有哪些、由什么组成 | 类型、分类、要素、清单、特征、模板 |
+| Why | 为什么这样做、为什么有效 | 原理、底层逻辑、机制、依据、原因 |
+| How | 具体怎么做、怎么用 | 方法、步骤、技巧、流程、公式框架、实操 case |
+
+一个帖子可以包含一种、两种或三种知识类型:
+
+```text
+What
+Why
+How
+What + Why
+What + How
+Why + How
+What + Why + How
+```
+
+规则很简单:
+
+1. 原文有哪个就提取哪个。
+2. 原文没有的不要补。
+3. 不为了结构完整而编造。
+4. 一个帖子可以拆成多个知识片段。
+
+### 3.2 阶段:灵感 / 选题 / 脚本
+
+灵感、选题、脚本的总和叫“创作”。
+
+```text
+创作 = 灵感 + 选题 + 脚本
+```
+
+| 阶段 | 判断标准 |
+|---|---|
+| 灵感 | 帮助发现方向、素材、切口、洞察 |
+| 选题 | 帮助判断写什么、拍什么、从哪个角度切入 |
+| 脚本 | 帮助组织表达顺序、文案、镜头、结构 |
+
+每个知识片段可以对应一个、两个或三个阶段。
+
+### 3.3 作用域:五棵分类树
+
+作用域来自五棵分类树:
+
+```text
+实质 / 形式 / 感受 / 作用 / 意图
+```
+
+| 作用域 | API `scope_type` | 判断标准 |
+|---|---|---|
+| 实质 | `substance` | 内容真正讲的对象、主题、事实、问题 |
+| 形式 | `form` | 内容结构、模板、公式、表达形式 |
+| 感受 | `feeling` | 用户情绪、体验、氛围、感知 |
+| 作用 | `effect` | 解决什么创作问题、带来什么效果 |
+| 意图 | `intent` | 创作者目的、传播目的、商业目标 |
+
+每个知识片段可以命中一个或多个作用域。
+
+## 4. 四个环节
+
+### 4.1 筛选
+
+筛选判断帖子是否值得处理。
+
+**输入是多模态内容理解后的提取结果,不是原始 `body_text`。** 知识可能只存在于图片或视频里,所以必须先把文本 + 图片 + 视频交给 Gemini(gemini-3-flash-preview) 提取内容,再判断。只读 `body_text` 会把「正文为空、知识在图里」的帖子误判成空内容而错误淘汰。
+
+通过条件(针对提取后的内容判断):
+
+1. 帖子不是空内容(指多模态提取后仍无有效内容,而非仅 `body_text` 为空)。
+2. 帖子和创作相关。
+3. 帖子至少包含一点 What / Why / How。
+4. 帖子能拆出至少一个知识片段。
+
+输出:
+
+```jsonc
+{
+  "passed": true,
+  "score": 8,
+  "reason": "内容完整,包含明确 How,且和创作相关"
+}
+```
+
+### 4.2 帖子拆分
+
+拆分目标:从帖子里拆出一个或多个知识片段。
+
+一个知识片段的结构:
+
+```jsonc
+{
+  "title": "评论区选题法",
+  "knowledge_types": ["what", "how"],
+  "what": "从用户评论里提取问题和痛点,用来生成内容选题的方法。",
+  "why": null,
+  "how": "收集高赞评论,归类问题,再改写成标题或脚本切入点。",
+  "evidence": ["原文中支持该知识片段的句子"]
+}
+```
+
+拆分规则:
+
+1. 如果 What / Why / How 都在讲同一个知识对象,放在同一个知识片段里。
+2. 如果帖子里有多个独立知识对象,拆成多个知识片段。
+3. `knowledge_types` 必须和非空的 `what / why / how` 一致。
+
+### 4.3 帖子解构
+
+解构目标:给每个知识片段补上阶段和作用域。
+
+```jsonc
+{
+  "title": "评论区选题法",
+  "knowledge_types": ["what", "how"],
+  "stages": ["选题", "脚本"],
+  "scopes": [
+    { "scope_type": "form", "value": "评论区选题流程" },
+    { "scope_type": "effect", "value": "生成选题" }
+  ],
+  "stage_reason": "该知识既能生成选题,也能改写成脚本切入点。",
+  "scope_reason": "它提供了流程形式,也说明了解决的创作问题。"
+}
+```
+
+注意:
+
+1. `stages` 是灵感 / 选题 / 脚本,可以多选。
+2. `scopes` 是五棵分类树,可以多选。
+3. `scopes.value` 是具体标签,不只是五个大类名。
+
+### 4.4 组装入库数据
+
+每个知识片段组装成一次入库请求:
+
+```text
+POST /api/v1/knowledge/ingest
+```
+
+同一个帖子拆出的多条知识,复用同一个 `source.id`。
+
+## 5. 入库字段映射
+
+| 本项目字段 | 入库接口字段 | 说明 |
+|---|---|---|
+| 帖子 ID | `source.id` | 同一帖子保持同一个来源 ID |
+| 平台 | `source.source_metadata.platform` | 例如 `xiaohongshu` |
+| 帖子链接 | `source.source_metadata.url` | 原始 URL |
+| 帖子标题 | `source.title` | 来源标题 |
+| 知识标题 | `title` | 每个知识片段的标题 |
+| What / Why / How 内容 | `content` | 建议存成 JSON 字符串 |
+| What / Why / How 标签 | `dim_attributes` | 例如 `["what", "how"]` |
+| 灵感 / 选题 / 脚本 | `dim_creations` | 例如 `["选题", "脚本"]` |
+| 作用域 | `scopes` | 使用 `scope_type + value` |
+| 证据、理由、置信度 | `custom_ext` | 用扩展字段保存 |
+
+## 6. 入库请求示例
+
+### 6.1 HOW + WHAT 示例
+
+```jsonc
+{
+  "source": {
+    "id": "xhs_67e4bdf50000000006028a59",
+    "source_type": "post",
+    "title": "帖子标题",
+    "author": null,
+    "source_metadata": {
+      "platform": "xiaohongshu",
+      "url": "https://www.xiaohongshu.com/explore/67e4bdf50000000006028a59"
+    }
+  },
+  "title": "知识片段标题",
+  "content": "{\"what\":\"这里放 What 内容\",\"why\":null,\"how\":\"这里放 How 内容\"}",
+  "dim_attributes": ["what", "how"],
+  "dim_creations": ["选题", "脚本"],
+  "scopes": [
+    { "scope_type": "form", "value": "公式框架" },
+    { "scope_type": "effect", "value": "生成选题" }
+  ],
+  "custom_ext": [
+    { "key": "原文证据", "type": "str", "value": "原文中支持该知识片段的句子" },
+    { "key": "阶段判断理由", "type": "str", "value": "该知识同时服务选题和脚本" }
+  ]
+}
+```
+
+### 6.2 HOW 示例
+
+```jsonc
+{
+  "source": {
+    "id": "xhs_67e2e39b0000000003028ff0",
+    "source_type": "post",
+    "title": "帖子标题",
+    "source_metadata": {
+      "platform": "xiaohongshu",
+      "url": "https://www.xiaohongshu.com/explore/67e2e39b0000000003028ff0"
+    }
+  },
+  "title": "知识片段标题",
+  "content": "{\"what\":null,\"why\":null,\"how\":\"这里放 How 内容\"}",
+  "dim_attributes": ["how"],
+  "dim_creations": ["脚本"],
+  "scopes": [
+    { "scope_type": "form", "value": "操作流程" }
+  ],
+  "custom_ext": [
+    { "key": "原文证据", "type": "str", "value": "原文中支持 How 的句子" }
+  ]
+}
+```
+
+### 6.3 WHY 示例
+
+```jsonc
+{
+  "source": {
+    "id": "xhs_699308fa0000000016009697",
+    "source_type": "post",
+    "title": "帖子标题",
+    "source_metadata": {
+      "platform": "xiaohongshu",
+      "url": "https://www.xiaohongshu.com/explore/699308fa0000000016009697"
+    }
+  },
+  "title": "知识片段标题",
+  "content": "{\"what\":null,\"why\":\"这里放 Why 内容\",\"how\":null}",
+  "dim_attributes": ["why"],
+  "dim_creations": ["灵感", "选题"],
+  "scopes": [
+    { "scope_type": "intent", "value": "内容传播目的" },
+    { "scope_type": "feeling", "value": "用户感受" }
+  ],
+  "custom_ext": [
+    { "key": "原文证据", "type": "str", "value": "原文中支持 Why 的句子" }
+  ]
+}
+```
+
+## 7. 最小函数职责
+
+这里只定义职责,不展开复杂技术实现。
+
+```python
+fetch_post_detail(url) -> Post                 # 含 body_text、image_url_list、video_url_list
+extract_content(post) -> ExtractedContent       # 文本+图片+视频 -> Gemini(gemini-3-flash-preview) 多模态提取
+screen_post(post, content) -> ScreeningResult
+split_post(post, content) -> list[KnowledgeItem]
+deconstruct_item(item) -> Deconstruction
+build_ingest_payload(post, item, deconstruction) -> dict
+ingest(payload) -> IngestResult
+```
+
+`extract_content` 是新流程的前置环节:把帖子的文本、图片、视频一起喂给 Gemini(gemini-3-flash-preview),输出统一的 `ExtractedContent`;筛选和拆分都消费它,不直接读 `body_text`。
+
+处理流程:
+
+```text
+for url in post_urls:
+    post = fetch_post_detail(url)
+    content = extract_content(post)        # 多模态提取,知识可能只在图片/视频里
+    screening = screen_post(post, content)
+
+    if not screening.passed:
+        save_rejected(post, screening)
+        continue
+
+    items = split_post(post, content)
+
+    for item in items:
+        deconstruction = deconstruct_item(item)
+        payload = build_ingest_payload(post, item, deconstruction)
+        ingest(payload)
+```
+
+## 8. 与数据工程血缘关系
+
+这里参考 `/Users/samlee/Documents/works/数据工程` 里的 Clustering / Pattern V2 血缘口径,只补充和本项目有关的部分。
+
+### 8.1 已有数据工程主线
+
+已有数据工程大致是:
+
+```text
+原始内容解构元素
+  -> Clustering / 分类归一
+  -> global_category / global_element / element_classification_mapping
+  -> Pattern V2 snapshot / mining
+  -> 下游构建或分析系统
+```
+
+其中和我们最相关的是 Clustering 的五类分类树:
+
+```text
+实质 / 形式 / 感受 / 作用 / 意图
+```
+
+这些分类树在数据工程里属于长期稳定的业务语言。Pattern V2 会消费这些树和标准元素,再去挖组合规律。
+
+### 8.2 本项目在血缘里的位置
+
+本项目不是 Pattern V2,也不参与原有聚类链路。它是一条新的“帖子知识入库”链路:
+
+```text
+帖子链接
+  -> 拉取帖子详情
+  -> 筛选
+  -> 拆分 What / Why / How
+  -> 解构阶段和作用域
+  -> 组装 ingest payload
+  -> POST /api/v1/knowledge/ingest
+  -> knowledge_source / knowledge / knowledge_tag / custom_ext
+```
+
+简单说:
+
+1. 数据工程的 Clustering 负责沉淀“五棵分类树”的业务口径。
+2. 本项目负责把新帖子里的知识拆出来,并挂到这五类作用域上。
+3. 本项目通过 ingest API 入库,不直接写 `global_category`、`global_element` 或 `element_classification_mapping`。
+4. 如果后续需要参考已有分类树,只做只读查询,不在当前流程里改树。
+
+### 8.3 字段级对应
+
+| 本项目 | 数据工程 / 入库侧 | 说明 |
+|---|---|---|
+| 帖子链接 | `source.source_metadata.url` | 原始来源 URL |
+| 帖子 ID | `source.id` / `knowledge_source.id` | 同一帖子拆出的多条知识复用同一来源 |
+| What / Why / How | `dim_attributes` | 当前知识片段真实包含的知识类型 |
+| 灵感 / 选题 / 脚本 | `dim_creations` | 创作阶段,可多选 |
+| 实质 / 形式 / 感受 / 作用 / 意图 | `scopes.scope_type` | 对齐数据工程五棵分类树 |
+| 具体作用域标签 | `scopes.value` / `knowledge_tag` | ingest API 会自动维护标签字典和向量 |
+| 原文证据、判断理由 | `custom_ext` | 用扩展字段保留可追溯信息 |
+
+### 8.4 作用域映射
+
+| 中文作用域 | API `scope_type` | 数据工程口径 |
+|---|---|---|
+| 实质 | `substance` | 内容对象、主题、实体、问题本身 |
+| 形式 | `form` | 表达结构、模板、公式、载体、内容形态 |
+| 感受 | `feeling` | 情绪、观感、氛围、体验 |
+| 作用 | `effect` | 功能、用途、解决的问题、产生的效果 |
+| 意图 | `intent` | 创作者目的、传播目的、商业目标 |
+
+### 8.5 当前边界
+
+当前只对齐血缘口径,不接入复杂链路:
+
+1. 不跑 Clustering。
+2. 不跑 Pattern V2。
+3. 不直接改五棵分类树。
+4. 不把 ingest API 自动生成的 `knowledge_tag` 反写为 `global_category`。
+5. 后续如果要把本项目纳入全局血缘图,再补 `domain_interface` 和字段级 lineage。
+
+## 9. 当前边界
+
+当前版本只做:
+
+1. 从帖子链接开始。
+2. 拉取帖子详情(文本 + 图片 + 视频)。
+3. 多模态内容理解:文本、图片、视频交给 Gemini(gemini-3-flash-preview) 提取真正内容,不只读 `body_text`。
+4. 筛选有效帖子。
+5. 拆分 What / Why / How。
+6. 解构阶段和作用域。
+7. 组装并调用入库接口。
+
+当前版本不做:
+
+1. Query 生成。
+2. 平台搜索。
+3. 多跳游走。
+4. 作者主页分析。
+5. LangGraph。
+6. 自动改写五棵分类树。

+ 125 - 0
技术文档/开发顺序.md

@@ -0,0 +1,125 @@
+# 创作知识 · 开发顺序步骤
+
+> 配套:业务设计 [创作知识-重构设计.md](../创作知识-重构设计.md)、架构 [技术架构.md](技术架构.md)、DDL [creation_knowledge.sql](creation_knowledge.sql)。
+> 本文是**落地施工顺序**:从搭 DB → 跑通测试 → web 可视化,每步细到组件/文件/主要函数/验证。
+> 原则:简洁、可延展、能复用已有代码,不堆架构。
+
+## 0. 现状与复用
+
+**现状**:本项目目前零代码。已就绪的是——业务/架构文档、数据库(Greenplum `open_aigc` 的 schema `creation_knowledge` + 表 `ck_post` / `ck_knowledge_item` 已建好)、5 个小红书样例(`数据接口与来源/captures/xhs_case_*.json`)。
+
+**复用模板**:开发机 `/home/sam/ContentFindAgentNew`(Python + uv + FastAPI + httpx + pydantic)。三个客户端直接当蓝本,不重造:
+
+| 要写的 | 复用蓝本(CFA 路径) | 关键符号 |
+|---|---|---|
+| `integrations/extractor.py` | `content_agent/integrations/gemini_video.py` | `GeminiVideoClient`(OpenRouter,`google/gemini-3-flash-preview`,多模态出 JSON) |
+| `integrations/crawler.py` | `content_agent/integrations/crawapi_http.py` | `post_crawapi_json()`、`RateLimiter`、`_load_env_file()`、`content_format()`(含 ≥15s 限流) |
+| `integrations/db.py` | `content_agent/integrations/database_runtime.py` | `DatabaseRuntimeStore`(psycopg + JSONB 列处理) |
+| `api.py` / `cli.py` / `scripts/validate_db.py` | `content_agent/api.py`、`cli.py`、`scripts/validate_content_agent_db.py` | FastAPI、argparse、DB 校验 |
+
+**两条已定决策**:① web = 简洁版 FastAPI + 单页 React;② 本地 repo 开发,部署到 `/home/sam`。
+
+## 1. 目标项目结构(最小化镜像 CFA)
+
+```
+pyproject.toml                # uv;deps: httpx, pydantic, psycopg[binary], fastapi, uvicorn, python-dotenv, pytest
+creation_knowledge/
+  config.py                   # Settings:从 .env 读 crawler/gemini/llm/pg/ingest 配置
+  models.py                   # pydantic: Post, ExtractedContent, ScreeningResult, KnowledgeItem, Deconstruction, IngestPayload
+  integrations/
+    crawler.py                # fetch_post_detail(content_id|url) -> Post
+    extractor.py              # extract_content(post) -> ExtractedContent(文本+图片+视频)
+    llm.py                    # chat_json(system, user, model='anthropic/claude-sonnet-4.5') -> dict (OpenRouter via httpx)
+    db.py                     # CkStore:upsert_post / update_stage / save_item / update_item_ingest / read_*
+  stages/
+    screen.py                 # screen_post(post, content) -> ScreeningResult
+    split.py                  # split_post(post, content) -> list[KnowledgeItem]
+    deconstruct.py            # deconstruct_item(item) -> Deconstruction
+    assemble.py               # build_ingest_payload(post, item, deco) -> IngestPayload(对齐设计文档 §6)
+  ingest.py                   # ingest(payload) -> dict;INGEST_ENABLED 开关,开发期 False(只存库不发)
+  pipeline.py                 # run_pipeline(urls, ingest_enabled=False):串 6 步 + 每步落库
+  cli.py                      # python -m creation_knowledge.cli run --urls ...
+  api.py                      # FastAPI:GET /posts, /posts/{id}, /posts/{id}/items, /posts/{id}/audit
+  audit/
+    auditor.py                # cross_audit(post_id) -> AuditReport:多 sub-agent 交叉审计(扩展面,见 M9)
+sql/creation_knowledge.sql    # 从 技术文档/ 移来(DDL 已在库上执行)
+prompts/                      # screen/split/deconstruct/audit 提示词模板(带版本号)
+scripts/validate_db.py        # 连库断言 schema/表/列
+scripts/run_batch.py          # 跑 5 个样例
+web/                          # 简洁版:单页 React(Vite) 读 FastAPI;帖子列表 + 流水线面板
+tests/fixtures/               # 5 个 xhs_case_*.json
+tests/{test_crawler,test_extractor,test_stages,test_pipeline_e2e}.py
+```
+
+## 2. 开发顺序(9 个里程碑)
+
+> 每个里程碑都能独立验证后再进下一个。函数签名以 `models.py` 的 pydantic 类型为准。
+
+### M0 · 脚手架
+- **文件**:`pyproject.toml`(uv)、包目录骨架、`creation_knowledge/config.py`、`creation_knowledge/models.py`。
+- **主要函数/类**:`config.Settings`(读 `.env`:`CONTENTFIND_API_CRAWAPI_*`、`CONTENT_AGENT_VIDEO_LLM_MODEL`、`GEMINI_API_KEY`、`OPENROUTER_*`、`MODEL`、`OPEN_AIGC_PG_*`、`KNOWHUB_API`、`INGEST_ENABLED`);`models` 里六个 pydantic 模型。
+- **验证**:`uv sync && uv run python -c "import creation_knowledge"`。
+
+### M1 · DB 层(库已建好,本步只接线 + 校验)
+- **文件**:`integrations/db.py`、`scripts/validate_db.py`、把 `技术文档/creation_knowledge.sql` 移到 `sql/`。
+- **主要函数**:`CkStore.upsert_post(post)`、`update_stage(id, stage)`、`save_item(post_id, item, deco, payload)`、`update_item_ingest(item_id, status, knowledge_id)`、`read_post(id)` / `read_items(post_id)`(供 api & audit)。连接走 `OPEN_AIGC_PG_*`,`search_path=creation_knowledge`。
+- **验证**:`uv run python scripts/validate_db.py` → 打印两表列齐全;写一行再回滚(可逆)。
+
+### M2 · 拉取
+- **文件**:`integrations/crawler.py`。
+- **主要函数**:`fetch_post_detail(content_id|url) -> Post`。`POST {crawler}/crawler/xiao_hong_shu/detail`,body `{content_id}`,复用 `RateLimiter`(≥15s)。从 url 解析 `content_id`。
+- **验证**:`tests/test_crawler.py` 用 5 个 capture 当 fixture 断言字段映射;跑 1 次真实 smoke。
+
+### M3 · 多模态提取(关键环节)
+- **文件**:`integrations/extractor.py`。
+- **主要函数**:`extract_content(post) -> ExtractedContent`。把 `body_text` + `image_url_list` + `video_url_list` 一起交给 `GeminiVideoClient`(`google/gemini-3-flash-preview`),产出 `{text, from_image, from_video, is_empty}`。**不只读 body_text**。
+- **验证**:对「拾意」两条(`67e2e39b`、`680659e8`,`body_text` 几乎空)能从图片提出非空 `from_image`、`is_empty=false`。
+
+### M4 · 四个环节(筛选/拆分/解构/组装)
+- **文件**:`stages/{screen,split,deconstruct,assemble}.py`、`prompts/`。
+- **主要函数**:`screen_post`→`ScreeningResult{passed,score,reason}`;`split_post`→`KnowledgeItem[]`(What/Why/How + evidence);`deconstruct_item`→`Deconstruction{stages,scopes,reason}`;`build_ingest_payload`→严格对齐设计文档 §6 的 ingest 请求体。screen/split/deconstruct 走 `llm.chat_json`。
+- **验证**:`tests/test_stages.py` 在 fixture 上逐环节断言;5 样例的 HOW/WHY/WHAT 标注与人工标注一致。
+
+### M5 · 流水线 + CLI(= 跑通测试)
+- **文件**:`pipeline.py`、`cli.py`、`ingest.py`。
+- **主要函数**:`run_pipeline(urls, ingest_enabled=False)` 串 6 步,每步 `CkStore` 落库;`ingest(payload)` 由 `INGEST_ENABLED` 控制,开发期 False(只存 `ingest_payload`,`ingest_status=pending`)。
+- **验证**:`python -m creation_knowledge.cli run --urls <5个>` → 库里 5 帖 + 知识片段,`ingest_status=pending`、`knowledge_id` 空。
+
+### M6 · 测试
+- **文件**:`tests/`(fixture 单测无网络 + e2e 5 样例落库)。
+- **验证**:`uv run pytest` 全绿;查库确认 5 帖及片段。
+
+### M7 · API
+- **文件**:`api.py`(FastAPI)。
+- **主要函数/路由**:`GET /posts`、`GET /posts/{id}`(含各环节产物)、`GET /posts/{id}/items`、`GET /posts/{id}/audit`。`uvicorn creation_knowledge.api:app`。
+- **验证**:`curl /posts`、`/posts/{id}` 返回 raw/extracted/screening/items/payload。
+
+### M8 · Web 可视化(简洁版)
+- **文件**:`web/`(单页 React + Vite,读 FastAPI)。
+- **内容**:左侧帖子列表,右侧流水线面板:原文 → 多模态提取 → 筛选(passed/score) → 知识片段(What/Why/How) → ingest payload。
+- **验证**:本地起 api + web,浏览器看到 5 帖完整流水线。
+
+### M9 · 多 sub-agent 交叉审计(核心扩展面)
+- **文件**:`audit/auditor.py`;新表 `ck_audit`。
+- **主要函数**:`cross_audit(post_id) -> AuditReport`。**读真实数据**:`ck_post`/`ck_knowledge_item`(DB) + 原始 capture/raw + 对应 stage 的 prompt/代码;**fan-out N 个独立 sub-agent,每个一个审计视角**:
+  1. 知识类型 What/Why/How 判定是否准确;
+  2. 每条 `evidence` 是否真支撑该片段;
+  3. 阶段(灵感/选题/脚本)、作用域(五棵树)归类是否正确;
+  4. 是「方法知识」还是「作品本身」——彩虹草原型应被否决。
+  多数表决,写 `ck_audit(post_id, item_id, dimension, verdict, reason, model, ext jsonb)`,web 标红/标绿。
+- **验证**:对「海狸 HOW+WHAT」判通过、对「彩虹草原」判否决。
+
+## 3. 可延展点(现在不做,留好接口)
+
+- **多平台**:`fetch_post_detail` 按 `platform` 分发不同 crawler path,下游环节不动。
+- **真实入库**:翻 `INGEST_ENABLED` 即调 KnowHub `POST {KNOWHUB_API}/api/v1/knowledge/ingest`,payload 结构不变。
+- **审计加深**:`cross_audit` 的视角数/投票数可调;prompt 版本写库可做 A/B。
+- **部署**:`rsync` 本 repo 到 `/home/sam/Create-knowledge-find-decode`,`uv sync`(或复用 `demand-agent-new/.venv`);DB 直连(开发机→RDS 5432 已验证可达)。
+
+## 4. 整套端到端验证
+
+1. `scripts/validate_db.py`:库连通 + 表结构 OK。
+2. `uv run pytest`:单测 + e2e 全绿。
+3. `cli run --urls <5样例>`:查库 5 帖 + 片段、`ingest_status=pending`。
+4. 起 api + web:浏览器看 5 帖流水线。
+5. `cross_audit` 对正/反例给出正确 verdict 并落 `ck_audit`、web 可见。

+ 180 - 0
技术文档/技术架构.md

@@ -0,0 +1,180 @@
+# 创作知识 · 技术架构
+
+> 配套业务设计见 [创作知识-重构设计.md](../创作知识-重构设计.md)。
+> 本文只讲「怎么落地」:流水线、数据存储、外部依赖、部署。保持简单、可延展,不堆架构。
+
+## 1. 定位
+
+一条**线性流水线**:输入一批帖子链接,输出组装好的创作知识(ingest payload)。
+
+```
+帖子链接[] → [拉取 → 多模态理解 → 筛选 → 拆分 → 解构 → 组装 ingest payload] → 存 PostgreSQL
+                                                                              ↘(上线后再)调 ingest API
+```
+
+- 一次只做一件事,每个环节是一个**纯函数**,输入输出都是明确的数据结构。
+- 不引入消息队列、微服务、编排框架(LangGraph 等)。先把单进程批处理跑通,需要扩展时再加。
+- **终态**:知识通过 ingest API(`KNOWHUB_API` + `/api/v1/knowledge/ingest`)入库,本项目**不直接写**知识库底层表。
+- **开发/测试期(当前)**:**不真实调用 ingest**。把数据组装成 ingest 要的结构,存进 PostgreSQL,流水线即结束。上线时只需打开真实调用的开关,payload 结构不变。
+
+## 2. 总体架构
+
+```text
+pipeline(单进程,可按帖子分片并发)
+
+  url ─► fetch ─► extract ─► screen ─► split ─► deconstruct ─► build_payload ─►[ingest]
+          │         │          │         │          │            │             (上线后)
+       crawler   Gemini      LLM        LLM        LLM         组装        开发期只存 PG
+       .aiddit   多模态                                       ingest payload   不真实调用
+          │         │          │         │          │            │
+          ▼         ▼          ▼         ▼          ▼            ▼
+  ┌──────────────────── 过程库(我们自己的表)─────────────────────┐
+  │  ck_post            每帖一行,各环节产物存 JSONB                │
+  │  ck_knowledge_item  每条知识片段一行,含入库状态               │
+  └────────────────────────────────────────────────────────────────┘
+```
+
+三类参与方:
+
+| 角色 | 是什么 | 谁提供 |
+|---|---|---|
+| 流水线 | 本项目的代码,6 个函数串起来 | 我们写 |
+| 过程库 | 记录每帖每片段的处理过程和状态 | 我们建表(见 §4) |
+| 外部能力 | 爬虫、多模态模型、入库 API | 已有,`.env` 配置(见 §5) |
+
+## 3. 处理流水线
+
+6 个函数,对应业务设计 §7。每个函数职责单一、可单独替换或重跑。
+
+| 步骤 | 函数 | 输入 → 输出 | 依赖 |
+|---|---|---|---|
+| 1 拉取 | `fetch_post_detail(url)` | url → `Post`(text+image+video) | crawler.aiddit.com |
+| 2 多模态理解 | `extract_content(post)` | `Post` → `ExtractedContent` | Gemini(多模态) |
+| 3 筛选 | `screen_post(post, content)` | → `ScreeningResult{passed,score,reason}` | LLM |
+| 4 拆分 | `split_post(post, content)` | → `KnowledgeItem[]` (What/Why/How) | LLM |
+| 5 解构 | `deconstruct_item(item)` | → `Deconstruction{stages,scopes}` | LLM |
+| 6 组装 | `build_ingest_payload(post,item,deco)` | → ingest payload(存 `ck_knowledge_item.ingest_payload`) | 无(纯组装) |
+| 7 入库 | `ingest(payload)` | → 调 ingest API 写知识库 | KnowHub API · **开发期关闭** |
+
+> 步骤 6 是开发期的终点:组装出 ingest payload 并存 PG 即算完成。步骤 7(真实调用 ingest)由开关控制,开发/测试期默认关闭,`ingest_status` 停在 `pending`。
+
+### 3.1 关键约束:内容在图片/视频里
+
+知识主体常在图片或视频里,`body_text` 往往只是话题串(例如 `#短剧编剧# #写作#`)。
+所以 **`extract_content` 是流水线的第一等公民**:把文本 + 图片 + 视频一起交给多模态模型,产出统一的 `ExtractedContent`;筛选和拆分都消费它,**不直接读 `body_text`**。
+
+`ExtractedContent` 建议结构(先简单,后可扩):
+
+```jsonc
+{
+  "text": "多模态汇总后的正文/讲解",
+  "from_image": "图片里提取到的知识要点",
+  "from_video": "视频里提取到的知识要点(抽帧或整段)",
+  "is_empty": false
+}
+```
+
+### 3.2 失败与重跑
+
+- 每个环节的产物独立落库(JSONB),任一环节可基于上一环节产物**单独重跑**,不必从头爬。
+- 失败只标记状态(见 `ck_post.stage` / `status`),不阻塞同批其他帖子。
+
+## 4. 数据存储
+
+只建 **2 张表**。开发期知识的最终落点就是这里——`ck_knowledge_item.ingest_payload` 存的就是组装好、待发送的 ingest 请求体;上线后再由步骤 7 把它发给 ingest API。
+
+**落点(已建好 ✅)**:`open_aigc` 实例新建独立 schema `creation_knowledge`,两张表已创建。
+- 实例实为 **AnalyticDB for PostgreSQL / Greenplum 7.0.0(PG12 内核)**,不是单机 PG——建表需 `DISTRIBUTED BY`,主键须含分布列,不强制外键(关系由应用维护)。
+- 写权限**已确认**:用户 `aiddit_aigc` 对 `open_aigc` 有 CREATE 权限,schema owner = `aiddit_aigc`。
+- 本实例**无 pgvector**(`vector` 扩展不可用),embedding 一期不做;将来要做语义检索需另选方案,不走 pgvector。
+- DDL 见 [`sql/creation_knowledge.sql`](../sql/creation_knowledge.sql);机器上副本 `/home/sam/creation_knowledge.sql`。回滚:`DROP SCHEMA creation_knowledge CASCADE;`。
+- 操作账号统一用 **sam**(部署机 `47.245.103.121`),数据库角色用 `aiddit_aigc`。
+
+### 4.1 `ck_post`(每帖一行)
+
+| 字段 | 类型 | 说明 |
+|---|---|---|
+| `id` | text PK | `xhs_<content_id>`,同帖唯一,复用为 ingest `source.id` |
+| `platform` | text | `xiaohongshu` 等 |
+| `url` | text | 原始链接 |
+| `raw` | jsonb | `fetch_post_detail` 原始响应 |
+| `extracted` | jsonb | `extract_content` 多模态产物 |
+| `screening` | jsonb | `screen_post` 结果 |
+| `stage` | text | `fetched/extracted/screened/split/done/rejected/failed` |
+| `created_at` / `updated_at` | timestamptz | |
+
+### 4.2 `ck_knowledge_item`(每条知识片段一行)
+
+| 字段 | 类型 | 说明 |
+|---|---|---|
+| `id` | bigserial PK | |
+| `post_id` | text FK→`ck_post.id` | 同帖多片段复用同一 source |
+| `item` | jsonb | 拆分结果(title/knowledge_types/what/why/how/evidence) |
+| `deconstruction` | jsonb | 解构结果(stages/scopes/reason) |
+| `ingest_payload` | jsonb | 组装后的 ingest 请求体(**开发期的最终产物**) |
+| `ingest_status` | text | `pending`(开发期默认,未发送) / `ingested` / `failed` |
+| `knowledge_id` | text | ingest API 返回的知识 ID(上线后才有,开发期为空) |
+| `created_at` / `updated_at` | timestamptz | |
+
+> 这两表用 JSONB 承载各环节产物,字段稳定后再按需「晋升成列」。这是过程库,不是对外契约表。
+
+## 5. 外部依赖与配置
+
+全部来自 `.env`,代码只读环境变量,不硬编码。
+
+| 能力 | 用途 | `.env` 变量 | 状态 |
+|---|---|---|---|
+| 帖子详情爬虫 | 步骤 1 拉取 | `CONTENTFIND_API_CRAWAPI_BASE_URL` / `_KEY`,host `crawler.aiddit.com` | 小红书 detail 已验证 ✅,限流 ≥15s |
+| 多模态模型 | 步骤 2 提取 | `CONTENT_AGENT_VIDEO_LLM_MODEL=google/gemini-3-flash-preview`(走 `OPENROUTER_BASE_URL`+`OPENROUTER_API_KEY`)或直连 `GEMINI_API_KEY` | 已确定 |
+| 判断/拆分/解构 LLM | 步骤 3–5 | `MODEL`(`anthropic/claude-sonnet-4.5` via OpenRouter) | 可用 |
+| 知识入库 | 步骤 7 | `KNOWHUB_API`,调 `POST {KNOWHUB_API}/api/v1/knowledge/ingest` | 终态依赖,**开发期不真实调用** |
+| 过程库 | 落库 | `OPEN_AIGC_PG_*`(Greenplum,schema `creation_knowledge`) | 已建表 ✅,写权限已确认 |
+| 媒体暂存(可选) | 大图/视频转存后给模型 | `ALIYUN_OSS_*` | bucket 未配,**默认直接传 URL,OSS 暂不接** |
+
+### 5.1 多模态模型说明
+
+- 多模态理解统一用 **`google/gemini-3-flash-preview`**(已确定)。
+- 代码统一读 `CONTENT_AGENT_VIDEO_LLM_MODEL`,不写死模型名;走 OpenRouter,必要时可切直连 `GEMINI_API_KEY`。
+
+## 6. 运行与部署
+
+### 6.1 本地/开发机运行
+
+单进程批处理脚本,读一批 url,串行(或按帖子并发)跑完流水线:
+
+```text
+for url in urls:
+    post     = fetch_post_detail(url)        # 失败→标 failed,跳过
+    content  = extract_content(post)         # 多模态
+    result   = screen_post(post, content)
+    if not result.passed:  mark rejected; continue
+    for item in split_post(post, content):
+        deco    = deconstruct_item(item)
+        payload = build_ingest_payload(post, item, deco)
+        save_knowledge_item(post, item, deco, payload)   # 存 PG,ingest_status=pending
+        if INGEST_ENABLED:        # 开发/测试期 = False,只组装+存库
+            ingest(payload)       # 上线后才真实调用
+```
+
+### 6.2 部署目标
+
+- 阿里云海外开发机 `47.245.103.121`,密钥 `工作环境配置/阿里云海外lsh开发机/ali-denet.pem`。
+- 过程库与本流水线**同机/同内网**,本机直连即可;ingest API(`KNOWHUB_API`)同机,但**开发期不调用**,上线再开 `INGEST_ENABLED`。
+- 部署形态:先一个可手动/定时触发的 Python 进程;`.env` 随项目走,不进仓库。
+
+## 7. 延展点(需要时再加,现在不做)
+
+| 想扩展 | 怎么加(不改主结构) |
+|---|---|
+| 多平台(抖音/B站/视频号…) | `fetch_post_detail` 按 `platform` 分发到对应 crawler path,其余环节不变 |
+| 提速 | 按帖子分片并发,受 crawler ≥15s 限流约束;过程库已支持断点重跑 |
+| 接搜索/游走 | 在 `fetch` 前面接一段「链接来源」,流水线下游不动 |
+| 多套规则实验 | `screen/split/deconstruct` 的 prompt/规则版本号写进 `ck_post` JSONB |
+| 异步/服务化 | 过程库的 `stage` 已是状态机,可直接换成队列驱动 |
+
+## 8. 不做
+
+1. 不做 Query 生成、平台搜索、多跳游走、作者主页分析。
+2. 不引入 LangGraph / 消息队列 / 微服务。
+3. 不直接写 KnowHub 底层表,也不改数据工程的五棵分类树。
+4. 不为结构完整而编造知识;原文(含图/视频)没有的不补。

+ 786 - 0
数据接口与来源/00_数据接口总览.md

@@ -0,0 +1,786 @@
+# ContentFindAgent 数据接口与来源总览
+
+更新时间:2026-06-08
+
+## 0. 证据口径
+
+本文只记录旧版代码、旧版接口审计、DB-first schema inventory、ContentFindAgent 数据工程 run 和 subagent 交叉验证过的数据接口。当前数据接口与来源的目录入口以本文为准,字段合同以 [数据库字段总览](../数据库字段总览/) 为准。
+
+机器可读索引见 [external_data_sources_registry.json](external_data_sources_registry.json)。本文负责给人解释接口来源、用途和边界;JSON 负责让程序、脚本或后续检查工具按 `source_id` 查询外部数据源、环境变量、接入状态、输出落点和缺口。
+
+| 状态 | 含义 |
+|---|---|
+| 已验证 | 已有 DB / API 只读验证或旧版实测结果 |
+| 源码定位 | 旧版代码能定位到接口或写入逻辑,但本次未实连 |
+| blocked | 因 token、只读条件或副作用限制未实连 |
+| pending / 待接入 | DB 字段存在,产品应接入,但旧版 ContentFindAgent 未作为主链路实现 |
+| source-only | 已有配置来源或源码来源,但本轮未作为主链路实连验证 |
+| missing | 变量、key、表或 API 未找到可用真实值 |
+| 缺口 | 没有真实表、真实接口或稳定字段,不能写成已接入 |
+
+不把 `show` 静态样例、小红书搜索、共创作者、相似作者、发现内容列表、淘汰原因表写成已验证接口。
+
+### 0.1 阅读方式
+
+每个阶段都按“短索引 + 详情块”组织:
+
+- 短索引只看接口、用途和状态,方便快速扫读。
+- 详情块再看输入字段、输出字段和边界,避免长表在窄屏下挤成一行。
+- 缺口统一放在最后,避免和已验证接口混在一起。
+
+### 0.2 环境配置和只读验证摘要
+
+本节吸收原环境缺口报告的确认结果,只记录变量名、能力和验证状态,不记录密码、token、AK/SK 或完整 DSN。
+
+#### 已验证配置
+
+- `.env` 结构:pass
+  - 对象:根目录 `.env`
+  - 注释:共 `139` 个变量,无重复 key;本地私有文件,不进入代码仓库。
+- 旧版 env 覆盖:pass
+  - 对象:旧仓 Python `os.getenv(...)`
+  - 注释:旧代码中发现的 `52` 个 getenv 变量都已在 `.env` 中覆盖。
+- 业务库:pass
+  - 变量:`DB_*`, `CONTENT_SUPPLY_DB_*`, `CONTENTFIND_DB_*`
+  - 注释:`demand_content`, `workflow_decode_task_result`, `demand_find_author`, `demand_find_content_result`, `demand_find_task`, `demand_task_oprate` 均只读通过。
+- Pattern 库:pass
+  - 变量:`OPEN_AIGC_PATTERN_DB_*`, `PATTERN_GLOBAL_DB_*`, `CONTENTFIND_PATTERN_DB_*`
+  - 注释:旧 MySQL `topic_pattern_element`, `topic_pattern_itemset`, `topic_pattern_category` 均只读通过,但新版 V1 不再把它们作为 `evidence_pack` 来源;只保留为历史迁移对照。
+- Crawapi 抖音接口:pass
+  - 变量:`CONTENTFIND_API_CRAWAPI_BASE_URL`, `CONTENTFIND_DOUYIN_*`, `CONTENTFIND_HOT_TOPIC_PATH`
+  - 注释:抖音关键词、作者作品、内容画像、账号画像、今日热榜均只读通过。
+  - 最新 smoke:2026-06-08 使用当前 `.env` 复测抖音关键词搜索,已不再返回强制登录异常;`POST /crawler/dou_yin/keyword` 可返回内容、`has_more` 和 `next_cursor`。同一内容调用 `POST /crawler/dou_yin/re_dian_bao/video_like_portrait` 返回 `code=0 / msg=null`,但样本画像为空,需按 `portrait_available=false / age_50_plus_level=missing` 处理。
+- AIGC plan detail:pass
+  - 变量:`AIGC_TOKEN`, `CONTENTFIND_API_AIGC_TOKEN`, `CONTENTFIND_API_READONLY_TOKEN`, `CONTENTFIND_AIGC_READONLY_PRODUCE_PLAN_ID`
+  - 注释:只查 produce plan detail,未创建或保存计划。
+- OpenRouter:pass
+  - 变量:`OPEN_ROUTER_API_KEY`, `OPENROUTER_API_KEY`, `OPENROUTER_BASE_URL`
+  - 注释:两个 key 别名已同步;只读 key metadata probe HTTP 200;未调用 chat completion 或 embeddings。
+- 上游 open_aigc MySQL:pass
+  - 变量:`OPEN_AIGC_MYSQL_*`
+  - 注释:本轮只读 `SELECT 1` 通过,并完成 5 张上游表 `LIMIT 1` 探测。
+- 上游 open_aigc PG:pass
+  - 变量:`OPEN_AIGC_PG_*`, `PGVECTOR_DSN`, `DATA_ENGINEERING_OPEN_AIGC_PG_DSN`
+  - 注释:`DATA_ENGINEERING_OPEN_AIGC_PG_DSN` 和同步后的 `OPEN_AIGC_PG_*` 均只读 `SELECT 1` 通过;Pattern 相关表 `LIMIT 1` 通过。
+- ODPS 表现数据:pass
+  - 变量:`ODPS_ACCESS_ID`, `ODPS_ACCESS_KEY`, `ODPS_ENDPOINT`, `ODPS_PROJECT`
+  - 注释:本轮 `SELECT 1` 通过,`video_dimension_detail_add_column`, `dwd_multi_demand_pool_di`, `feature_point_data` schema 可读。
+
+#### 待补或仅有来源配置
+
+- TikHub fallback:missing
+  - 变量:`TIKHUB_API_KEY`, `TIKHUB_BASE_URL`, `TIKHUB_DOUYIN_SEARCH_PATH`
+  - 注释:URL 和 path 已有,旧仓未找到真实 key;只能作为待补备用通道。
+- OSS:missing
+  - 变量:`ALIYUN_OSS_*`, `OSS_ACCESS_KEY_ID`, `OSS_ACCESS_KEY_SECRET`
+  - 注释:变量名已定位,真实 AK/SK、bucket、region、prefix、public base URL 缺失。
+- Feishu:source-only
+  - 变量:`FEISHU_APP_ID`, `FEISHU_APP_SECRET`
+  - 注释:旧版有来源,但不是 v2 主链路;本轮未调用。
+- 前端联调 API:missing
+  - 变量:`VITE_API_BASE_URL`, `VITE_CONTENTFIND_API_BASE_URL`
+  - 注释:show 当前仍是静态沙盘,尚未接真实后端。
+
+### 0.3 CFA 新数据合同
+
+旧接口审计记录的是老系统和上游能力;新版 CFA 的生产事实层使用同一个云库里的 `content_agent_*` 表。
+
+核心身份:
+
+| 字段 | 含义 |
+|---|---|
+| `run_id` | 一次 CFA 运行 ID,由系统生成,同编号只能跑一次 |
+| `policy_run_id` | 一次运行里的策略执行 ID。V1 一个 run 默认一套策略;V1.1 支持同一 run 多套策略实验 |
+| `schema_version` | DB 表或 JSON 文件结构版本 |
+| `record_schema_version` | JSONL 单行结构版本 |
+| `policy_bundle_id` | 策略组合包 ID |
+| `strategy_version` | 策略组合版本 |
+| `rule_pack_id` / `rule_pack_version` | 规则包 ID 和版本 |
+
+P0 新表:
+
+```text
+content_agent_runs
+content_agent_source_contexts
+content_agent_pattern_seed_packs
+content_agent_queries
+content_agent_discovered_content_items
+content_agent_content_media_records
+content_agent_rule_decisions
+content_agent_source_path_records
+content_agent_search_clues
+content_agent_run_events
+content_agent_final_outputs
+content_agent_publish_jobs
+content_agent_pattern_recall_evidence
+content_agent_strategy_reviews
+content_agent_policy_runs
+```
+
+字段边界:
+
+- 关联、去重、状态筛选、审计和多策略比较字段必须做 DB 列。
+- 原始响应、上游证据包、规则命中明细、运行事件详情和最终输出快照先放 JSON。
+- JSON 字段要晋升成列,必须先经过命名登记、DDL、回填、测试和文档同步。
+
+`content_agent_source_contexts` 是 run 级输入事实,不写 `policy_run_id`。从 `content_agent_pattern_seed_packs` 开始的策略相关表都必须写 `policy_run_id`。
+
+## 1. 数据源
+
+数据源阶段回答:从哪里拿原始素材、原始种子和可搜索线索。
+
+### 1.1 索引
+
+| 编号 | 接口/表 | 用途 | 状态 |
+|---|---|---|---|
+| S1 | `content-deconstruction-supply.demand_content` | 需求输入 | 已验证 |
+| S2 | `open_aigc.public.pattern_itemset + pattern_itemset_post` | PG Pattern V2 到支撑素材 | 已验证 / V1 使用 |
+| S3 | `content-deconstruction-supply.workflow_decode_task_result` | 直接 Case 原始素材和解构点 | 已验证 |
+| S4 | 旧 MySQL `topic_pattern_itemset -> workflow_decode_task_result` | 历史 Pattern Item Set 派生多个 Case | 已废弃 / 迁移对照 |
+| S5 | `open_aigc.public.pattern_mining_category` | PG Pattern V2 类目上下文 | 已验证 / V1 使用 |
+| S6 | `content-deconstruction-supply.demand_find_author` | 历史沉淀账号 | 已验证 |
+| S7 | 今日热榜 `/crawler/jin_ri_re_bang/content_rank` | 热点入口 | 已验证 |
+| S8 | `open_aigc.post` | 上游历史内容素材 | 已验证 |
+| S9 | `open_aigc.post_decode_topic_point_element` | 上游选题点元素 | 已验证 |
+| S10 | `open_aigc.post_script_paragraph_field_element` | 上游脚本段落元素 | 已验证 |
+
+### 1.2 详情
+
+#### S1. 数据库:`content-deconstruction-supply`,表:`demand_content`
+
+- 当前输入字段:`id`, `name`, `suggestion`, `score`, `merge_leve2`, `dt`, `ext_data`
+- 新版必解析字段:`ext_data.evidence_pack`
+- 输出字段:需求词、需求解释、品类、分数、日期。
+- 边界:这是需求源,不是 Case 素材源;旧版只取基础字段,新版不能丢掉证据包。
+
+`ext_data.evidence_pack` 需要包含并向下游传递:
+
+| 字段 | 用途 |
+|---|---|
+| `source_kind` | 区分 Pattern、Case、聚类、历史搜索等来源 |
+| `pattern_source_system` | 新版唯一合法值为 `pg_pattern_v2` |
+| `case_id_type` | 说明 Case ID / post ID / channel content ID 的口径 |
+| `source_post_id` | 绑定原始素材 ID |
+| `pattern_execution_id` | 回查 Pattern 执行 |
+| `mining_config_id` | 回查 Pattern 挖掘配置 |
+| `itemset_ids` | 回查频繁项集 |
+| `itemset_items[]` | 回查 itemset 内的分类、元素和维度 |
+| `category_bindings` | 绑定分类树父节点 |
+| `element_bindings` | 绑定分类树元素节点 |
+| `support` / `absolute_support` | Pattern 支持度 |
+| `matched_post_ids` | 记录 Pattern 支撑素材 |
+| `video_ids` / `case_ids` | Pattern 来源下均为 `post_id` 语义 |
+| `decode_case_ids` | PG-only 当前可为空数组,不参与 exact 闭合 |
+| `seed_terms` | 给 Query 使用的策略种子 |
+| `run_id` | 串起上游和下游 run_context |
+| `demand_task_id` / `demand_content_id` | 绑定 DemandAgent 任务和需求记录 |
+| `source_certainty` | 标记来源确定性 |
+| `validation_status` | 标记已验证、待接入或待复看反查 |
+
+这些字段要进入数据源、Query、判断、游走、资产清洗沉淀和策略学习。目标是从某个 `case_id` 或 `post_id` 能反查到 Pattern、itemset、分类节点或元素节点。
+
+#### S2. 数据库:`open_aigc PG`,表:`public.pattern_itemset` + `public.pattern_itemset_post`
+
+- 输入字段:`execution_id`, `itemset_id`, `mining_config_id`, `scope`
+- 输出字段:`support`, `absolute_support`, `matched_post_ids`, `itemset_items`
+- 边界:这是新版 DemandAgent `evidence_pack` 的正式 Pattern 主事实来源;旧 MySQL 只保留迁移对照。
+
+#### S3. 数据库:`content-deconstruction-supply`,表:`workflow_decode_task_result`
+
+- 输入字段:`channel_content_id`
+- 输出字段:`title`, `body_text`, `images`, `video_url`, `channel`, `channel_account_id`, `channel_account_name`
+- 解构字段:`purpose_points`, `key_points`, `inspiration_points`, `topic_fusion_result`, `merge_leve2`
+- 边界:Case 的最终落点;可由直接 Case 或 Pattern 派生 Case 回查。
+
+#### S4. 历史接口:旧 MySQL `topic_pattern_itemset` -> 数据库:`content-deconstruction-supply`,表:`workflow_decode_task_result`
+
+- 输入字段:`execution_id`, `combination_type`, `item_count`, `support`, `absolute_support`, `matched_post_ids`
+- 输出字段:用 `matched_post_ids` 回查 `workflow_decode_task_result.channel_content_id`
+- 边界:旧字段仅作历史迁移对照;新版 `evidence_pack` 不能从这里生成或兜底。
+
+#### S5. 数据库:`open_aigc PG`,表:`public.pattern_mining_category`
+
+- 输入字段:`execution_id`, `id`, `path`, `source_type`
+- 输出字段:`name`, `description`, `category_nature`, `level`, `parent_id`, `element_count`
+- 边界:辅助解释 PG Pattern V2 的分类路径,不直接召回内容。
+
+#### S6. 数据库:`content-deconstruction-supply`,表:`demand_find_author`
+
+- 输入字段:`content_tags`, `channel`, `author_id`, `author_name`
+- 输出字段:`run_id`, `author_name`, `author_link`, `author_id`, `elderly_ratio`, `elderly_tgi`, `is_good`, `remark`, `content_tags`, `channel`
+- 边界:旧版可按 `content_tags LIKE query` 找历史作者。
+
+#### S7. 接口:今日热榜 `/crawler/jin_ri_re_bang/content_rank`
+
+- 输入字段:`sort_type`, `cursor`
+- 输出字段:`source`, `jump_url`, `type`, `rankList[].title`, `rankList[].heat`, `has_more`, `next_cursor`
+- 边界:热点只做修饰和探索入口,不等于最终内容源。
+
+#### S8. 数据库:`open_aigc`,表:`post`
+
+- 输入字段:`post_id`, `platform`, `merge_leve1`, `merge_leve2`, `import_date`
+- 输出字段:`title`, `body_text`, `platform_account_id`, `platform_account_name`, `publish_timestamp`, `like_count`, `comment_count`, `collect_count`, `images`
+- 边界:数据工程上游素材表,不是旧版 ContentFindAgent 主读表。
+
+#### S9. 数据库:`open_aigc`,表:`post_decode_topic_point_element`
+
+- 输入字段:`post_id`, `topic_point_id`, `element_type`, `element_sub_type`
+- 输出字段:`element_name`, `element_description`, `element_source`, `element_reason`
+- 边界:用于理解上游元素,不替代 `workflow_decode_task_result`。
+
+#### S10. 数据库:`open_aigc`,表:`post_script_paragraph_field_element`
+
+- 输入字段:`post_id`, `paragraph_id`, `field_type`, `element_type`, `element_sub_type`
+- 输出字段:`element_name`, `element_description`
+- 边界:用于策略学习和素材理解。
+
+## 2. Query
+
+Query 阶段回答:哪些输入会被转成平台可执行搜索词或采集动作。
+
+### 2.1 索引
+
+| 编号 | 接口/表 | 用途 | 状态 |
+|---|---|---|---|
+| Q1 | `demand_content` | 需求转 Query 输入 | 已验证 |
+| Q2 | `workflow_decode_task_result` | Case 解构点转 Query 输入 | 已验证 |
+| Q3 | `ext_data.evidence_pack.seed_terms/itemset_items/category_bindings` | PG Pattern V2 证据转 Query 输入 | 已验证 / V1 使用 |
+| Q4 | 旧 MySQL `topic_pattern_element/topic_pattern_itemset` | 历史 Pattern 词或组合转 Query 输入 | 已废弃 / 迁移对照 |
+| Q5 | OpenRouter | LLM Query Builder / 判断辅助 | 只读鉴权通过 |
+| Q6 | `demand_find_task` | Query 执行 run_context 台账 | 已验证 |
+
+### 2.2 详情
+
+#### Q1. 数据库:`content-deconstruction-supply`,表:`demand_content`
+
+- 输入字段:`name`, `suggestion`, `merge_leve2`, `score`, `dt`, `ext_data.evidence_pack.seed_terms`, `ext_data.evidence_pack.source_kind`
+- 输出字段:Query 原始需求、品类、解释、策略种子。
+- 边界:旧版从需求池出发;新版有证据包时优先使用 `seed_terms`,不能只把宽泛 `name` 当 Query 输入。
+
+#### Q2. 数据库:`content-deconstruction-supply`,表:`workflow_decode_task_result`
+
+- 输入字段:`purpose_points`, `key_points`, `inspiration_points`, `topic_fusion_result`, `title`, `body_text`, `merge_leve2`
+- 输出字段:Case 策略种子、筛选点、回扣依据。
+- 边界:v2 以解构出的策略种子为主,不直接用账号名做 Query。
+
+#### Q3. 输入对象:`demand_content.ext_data.evidence_pack`
+
+- 输入字段:`seed_terms`, `itemset_items`, `category_bindings`, `element_bindings`, `pattern_source_system`
+- 输出字段:Pattern 词、维度、类目路径和 Query seed。
+- 边界:`pattern_source_system` 必须为 `pg_pattern_v2`,不再从旧 MySQL 表临时补证据。
+
+#### Q4. 历史接口:旧 MySQL `topic_pattern_element/topic_pattern_itemset`
+
+- 输入字段:`combination_type`, `item_count`, `support`, `absolute_support`, `dimensions`, `matched_post_ids`
+- 输出字段:Pattern 组合、支持度、多 Case 命中集合。
+- 边界:字段曾验证存在,但不再作为新版 Query 主链路或 fallback。
+
+#### Q5. 能力:OpenRouter
+
+- 输入字段:`model`, `messages`, `tools`, `system`, `max_tokens`, `temperature`
+- 输出字段:`content`, `tool_calls`, `prompt_tokens`, `completion_tokens`, `finish_reason`, `cost`, `usage`
+- 边界:本轮只做 key metadata 鉴权探测,未调用 chat completion 或 embeddings;真实生成仍需显式预算开关。
+
+#### Q6. 数据库:`content-deconstruction-supply`,表:`demand_find_task`
+
+- 输入字段:`run_id`, `demand_content_id`, `status`, `created_at`, `token_coast`
+- 输出字段:任务状态、成本、需求关联。
+- 边界:不是 Query 内容表,但承载执行追踪。
+
+## 3. Platform
+
+Platform 阶段回答:同一个 Query 在平台上用什么动作执行,返回什么字段。
+
+### 3.1 索引
+
+| 编号 | 接口/表 | 用途 | 状态 |
+|---|---|---|---|
+| P1 | 抖音关键词搜索 `/crawler/dou_yin/keyword` | Query -> 发现视频 | 已验证 |
+| P2 | TikHub 搜索 fallback | 抖音搜索备用 | blocked |
+| P3 | 抖音账号作品 `/crawler/dou_yin/blogger` | 作者 -> 作者作品 | 已验证 |
+| P4 | 热点宝内容画像 | 视频画像 | 已验证 |
+| P5 | 热点宝账号画像 | 作者画像 | 已验证 |
+| P6 | `demand_find_content_result` | 平台结果沉淀字段 | 已验证 |
+| P7 | `demand_find_author` | 作者平台身份 | 已验证 |
+
+### 3.2 详情
+
+#### P1. 接口:抖音关键词搜索 `/crawler/dou_yin/keyword`
+
+- 输入字段:`keyword`, `content_type`, `sort_type`, `publish_time`, `cursor`, `account_id`
+- 输出字段:`platform_content_id`, `desc`, `author.nickname`, `author.platform_author_id`, `statistics.*`, `has_more`, `next_cursor`
+- 边界:2026-06-08 真实 smoke 已确认 `content_type=视频` 可返回第一页、`has_more` 和 `next_cursor`;`综合` 口径不能直接照搬。
+
+#### P2. 接口:TikHub 搜索 fallback
+
+- 输入字段:`keyword`, `cursor`, `sort_type`, `publish_time`, `filter_duration`, `content_type`, `search_id`, `backtrace`
+- 输出字段:`business_data[].data.aweme_info`, `next_page`, `backtrace`
+- 边界:缺 `TIKHUB_API_KEY`,不能写成已接入。
+
+#### P3. 接口:抖音账号作品 `/crawler/dou_yin/blogger`
+
+- 输入字段:`account_id`, `sort_type`, `cursor`
+- 输出字段:`platform_content_id`, `desc`, `author.*`, `statistics.*`, `has_more`, `next_cursor`
+- 边界:已验证抖音作者作品;小红书作者作品仍待验证。
+
+#### P4. 接口:热点宝内容画像
+
+- 输入字段:`content_id`, `need_age`, `need_gender`, `need_province`
+- 输出字段:年龄、性别、省份画像,`percentage`, `preference`
+- 边界:用于判断,不是召回接口;2026-06-08 真实 smoke 确认接口可返回 `code=0`,但单条内容可能 `data.data=null`,运行层必须把它当作画像缺失而不是接口登录失败。
+
+#### P5. 接口:热点宝账号画像
+
+- 输入字段:`account_id`, `need_age`, `need_gender`, `need_province`
+- 输出字段:年龄、性别、省份画像,`percentage`, `preference`
+- 边界:可作为作者是否值得扩展的判断信号。
+
+#### P6. 数据库:`content-deconstruction-supply`,表:`demand_find_content_result`
+
+- 输入字段:`channel`, `platform_content_id`, `video_url`, `author_id`, `author_name`, `author_link`
+- 输出字段:平台、内容 ID、作者 ID、链接。
+- 边界:这是结果表字段,不是平台 API。
+
+#### P7. 数据库:`content-deconstruction-supply`,表:`demand_find_author`
+
+- 输入字段:`channel`, `author_id`, `author_name`, `author_link`, `content_tags`
+- 输出字段:作者资产、内容标签、平台身份。
+- 边界:可作为后续作者起点。
+
+## 4. 判断
+
+判断阶段回答:内容、作者、Pattern 派生 Case 是否值得留下或继续扩展。
+
+### 4.1 索引
+
+| 编号 | 接口/表 | 用途 | 状态 |
+|---|---|---|---|
+| J1 | 热点宝内容画像 | 50+ 内容适配 | 已验证 |
+| J2 | 热点宝账号画像 | 50+ 作者适配 | 已验证 |
+| J3 | `workflow_decode_task_result` | Case 回扣判断 | 已验证 |
+| J4 | 解构接口 + 分类树 `match-paths` | 新发现内容 Pattern 回扣判断 | 待接入 |
+| J5 | PG `pattern_itemset` + `pattern_itemset_post` | Pattern 来源 Case 支持度判断 | 已验证 / V1 使用 |
+| J6 | `demand_find_content_result` | 判断结果沉淀 | 已验证 |
+| J7 | `dwd_multi_demand_pool_di` | 下游需求池表现参考 | 已验证 |
+| J8 | `feature_point_data` | 特征表现参考 | 已验证 |
+
+### 4.2 详情
+
+#### J1. 接口:热点宝内容画像
+
+- 输入字段:`content_id`, `need_age`, `need_gender`, `need_province`
+- 输出字段:年龄、性别、省份画像,`percentage`, `preference`
+- 边界:判断信号,不直接代表内容质量。
+
+#### J2. 接口:热点宝账号画像
+
+- 输入字段:`account_id`, `need_age`, `need_gender`, `need_province`
+- 输出字段:年龄、性别、省份画像,`percentage`, `preference`
+- 边界:作者强不代表作品必然强。
+
+#### J3. 数据库:`content-deconstruction-supply`,表:`workflow_decode_task_result`
+
+- 输入字段:`purpose_points`, `key_points`, `inspiration_points`, `topic_fusion_result`
+- 输出字段:目的点、关键点、灵感点、选题描述。
+- 边界:直接 Case 和 Pattern 派生 Case 都回到这张表判断。
+
+#### J4. 接口:解构接口 + 分类树 `match-paths`
+
+- 输入字段:发现视频的解构元素、`source_type`, `top_k`, `min_score`
+- 输出字段:分类树备选路径、分数和匹配依据。
+- 当前 endpoint:`POST https://library.aiddit.com/api/search/categories/match-paths/v2`。
+- 最新 smoke:2026-06-08 提交元素词 `毛主席`,返回 `success=true`,首个候选路径为 `/表象/视觉/实体/人物/个体/现实人物`,score 为 `1.0`。
+- 边界:只有解构强证据词和本次 PG `evidence_pack` 能解释相连,才允许把 `pattern_recall` 升级为 `matched`。`strong / medium / weak` 只用于画像、置信度或强弱等级,不表示 Pattern 回扣通过。
+
+#### J5. 数据库:`open_aigc PG`,表:`public.pattern_itemset` + `public.pattern_itemset_post`
+
+- 输入字段:`support`, `absolute_support`, `item_count`, `matched_post_ids`, `combination_type`
+- 输出字段:Pattern 支持度、支撑素材和 itemset 规模。
+- 边界:只用于验证上游 `evidence_pack`,不替新发现内容做自动回扣。
+- 输出字段:支持度、帖子集合、组合类型。
+- 边界:用于 Pattern -> 多 Case 判断;旧版未主链路使用。
+
+#### J6. 数据库:`content-deconstruction-supply`,表:`demand_find_content_result`
+
+- 输入字段:`digg_count`, `comment_count`, `share_count`, `portrait_source`, `elderly_ratio`, `elderly_tgi`, `recommendation_reason`, `process_trace`
+- 输出字段:互动、画像来源、50+ 指标、推荐理由、过程 run_context。
+- 边界:旧版只沉淀最终结果,没有全量发现内容判断表。
+
+#### J7. 数据库:`ODPS`,表:`dwd_multi_demand_pool_di`
+
+- 输入字段:`strategy`, `demand_id`, `demand_name`, `weight`, `type`, `video_count`, `video_list`, `extend`, `dt`
+- 输出字段:需求池权重和视频列表。
+- 边界:用于策略学习/复盘,不是旧版判断实时输入。
+
+#### J8. 数据库:`ODPS`,表:`feature_point_data`
+
+- 输入字段:`特征点`, `总分发曝光pv`, `bn_总回流`, `质bn_rovn`, `分发视频量`, `总日回流uv`, `vid_list`, `dt`
+- 输出字段:特征点表现、回流、视频列表。
+- 边界:用于后续策略学习,不是旧版实时评分表。
+
+## 5. 游走
+
+游走阶段回答:从视频、作者、Pattern、Case 还能走到哪里。
+
+### 5.1 索引
+
+| 编号 | 接口/表 | 用途 | 状态 |
+|---|---|---|---|
+| W1 | 抖音关键词搜索返回作者 | 视频 -> 作者 | 已验证 |
+| W2 | 抖音账号作品 | 作者 -> 作者作品 | 已验证 |
+| W3 | `demand_find_author` | 历史作者 -> 作者作品 | 已验证 |
+| W4 | PG `pattern_itemset_post` | Pattern -> 支撑素材 | 已验证 / V1 使用 |
+| W5 | 旧 MySQL `topic_pattern_* -> workflow_decode_task_result` | 历史特征词或 itemset -> Case | 已废弃 / 迁移对照 |
+| W6 | 相关搜索 / 标签 / 共创 / 相似作者 | 内容继续扩展 | 缺口 |
+| W7 | 小红书笔记/作者/话题游走 | 小红书扩展 | 缺口 |
+
+### 5.2 详情
+
+#### W1. 接口:抖音关键词搜索返回作者
+
+- 输入字段:`platform_content_id`, `desc`, `author.nickname`, `author.platform_author_id`, `statistics.*`
+- 输出字段:作者昵称、`platform_author_id`、互动指标。
+- 边界:只是进入作者判断,不代表作者自动入库。
+
+#### W2. 接口:抖音账号作品
+
+- 输入字段:`account_id` / `author.platform_author_id`, `sort_type`, `cursor`
+- 输出字段:`platform_content_id`, `desc`, `author.*`, `statistics.*`, `has_more`, `next_cursor`
+- 边界:作品需要重新过判断。
+
+#### W3. 数据库:`content-deconstruction-supply`,表:`demand_find_author`
+
+- 输入字段:`author_id`, `author_link`, `content_tags`, `channel`
+- 输出字段:可复用作者身份、标签、画像指标。
+- 边界:旧版按作者资产复用;作品仍走平台接口。
+
+#### W4. 数据库:`open_aigc PG`,表:`public.pattern_itemset_post`
+
+- 输入字段:`execution_id`, `itemset_id`
+- 输出字段:`post_id` 列表,进入 `matched_post_ids`、`video_ids`、`case_ids`。
+- 边界:这是新版 PG-only `evidence_pack` 的支撑素材来源。
+
+#### W5. 历史接口:旧 MySQL `topic_pattern_*` -> 数据库:`content-deconstruction-supply`,表:`workflow_decode_task_result`
+
+- 输入字段:`matched_post_ids`, `support`, `absolute_support`
+- 输出字段:历史 Case 解构点。
+- 边界:仅保留迁移说明,新版不再用它补齐或兜底 `evidence_pack`。
+
+#### W6. 缺口:相关搜索 / 标签 / 共创 / 相似作者
+
+- 输入字段:暂无稳定字段。
+- 输出字段:暂无稳定返回。
+- 边界:不写成已验证接口。
+
+#### W7. 缺口:小红书笔记/作者/话题游走
+
+- 输入字段:暂无旧版实测字段。
+- 输出字段:暂无稳定返回。
+- 边界:目前只有静态 Case 字段,不等于平台接口接入。
+
+## 6. 资产清洗沉淀
+
+资产清洗沉淀阶段回答:召回和判断后的内容、作者、后处理链接沉到哪里。
+
+### 6.1 索引
+
+| 编号 | 接口/表 | 用途 | 状态 |
+|---|---|---|---|
+| A1 | `demand_find_content_result` | 内容资产入库 | 已验证 |
+| A2 | `demand_find_content_result` | 内容质量和画像沉淀 | 已验证 |
+| A3 | `demand_find_author` | 作者资产入库 | 已验证 |
+| A4 | AIGC plan | 后处理计划绑定 | 源码定位 / blocked |
+| A5 | OSS log HTML | 过程可视化链接 | 源码定位 / blocked |
+| A6 | 关系资产 | 来源、query、作者、标签、游走路径关系 | 缺口 |
+| A7 | 搜索线索 | 有效 query、失败 query、标签、话题 | 缺口 |
+
+### 6.2 详情
+
+#### A1. 数据库:`content-deconstruction-supply`,表:`demand_find_content_result`(内容资产入库)
+
+- 输入字段:`run_id`, `query`, `rank_no`, `video_url`, `title`, `author_name`, `author_link`, `author_id`, `platform_content_id`, `demand_content_id`, `channel`, `dt`
+- 输出字段:内容资产、排序、来源需求、平台身份。
+- 新版必须补:结构化 `source_evidence`,或 sidecar/source edge artifact。
+- 边界:旧版沉淀最终内容,不沉淀全量发现内容列表;只靠 `platform_content_id + demand_content_id + process_trace` 不能 exact 回溯到 Pattern 和分类树节点。
+
+#### A2. 数据库:`content-deconstruction-supply`,表:`demand_find_content_result`(内容质量和画像沉淀)
+
+- 输入字段:`digg_count`, `comment_count`, `share_count`, `portrait_source`, `elderly_ratio`, `elderly_tgi`, `recommendation_reason`, `process_trace`
+- 输出字段:互动指标、画像、推荐理由、过程记录。
+- 边界:`process_trace` 可复盘,但不是结构化全量 run_context 表;不能替代 `source_evidence`。
+
+#### A3. 数据库:`content-deconstruction-supply`,表:`demand_find_author`
+
+- 输入字段:`run_id`, `author_name`, `author_link`, `author_id`, `elderly_ratio`, `elderly_tgi`, `is_good`, `remark`, `content_tags`, `channel`
+- 输出字段:作者资产、画像、标签、入选理由。
+- 边界:作者身份合并逻辑需新版明确。
+
+#### A4. 能力:AIGC plan
+
+- 输入字段:`platform_content_id`, `merge_leve2`, `produce_plan_id`, `account_id`, `sort_type`
+- 输出字段:`crawler_plan_id`, `produce_plan_id`, `produce_plan_name`, `publish_plan_id`
+- 边界:写侧副作用,开发测试不能默认触发。
+
+#### A5. 能力:OSS log HTML
+
+- 输入字段:`html_path`, `object_key`, `task_id`
+- 输出字段:`web_html_url`
+- 边界:上传有副作用;旧版只保留能力边界。
+
+#### A6. 缺口:关系资产
+
+- 输入字段:暂无真实表。
+- 输出字段:暂无真实字段。
+- 边界:内容与数据源、query、作者、标签、游走路径关系都需要承载,但当前不伪造 schema。
+
+#### A7. 缺口:搜索线索
+
+- 输入字段:暂无真实表。
+- 输出字段:暂无真实字段。
+- 边界:有效 query、失败 query、标签、话题、相关搜索线索目前只在结果和 run_context 中间接保留。
+
+## 7. 策略学习
+
+策略学习阶段回答:下一轮如何根据 run_context、表现和概念层事实调整策略。
+
+### 7.1 索引
+
+| 编号 | 接口/表 | 用途 | 状态 |
+|---|---|---|---|
+| L1 | `demand_find_task` | 任务级 run_context 和成本 | 已验证 |
+| L2 | `demand_task_oprate` | 调度和预算开关 | 源码定位 |
+| L3 | `demand_find_content_result` | 内容结果复盘 | 已验证 |
+| L4 | `demand_find_author` | 作者资产复盘 | 已验证 |
+| L5 | `open_aigc.global_category` | 长期概念分类 | 已验证 |
+| L6 | `open_aigc.global_element` | 长期概念元素 | 已验证 |
+| L7 | `open_aigc.element_classification_mapping` | 元素归类映射 | 已验证 |
+| L8 | `open_aigc.public.pattern_mining_execution` | Pattern V2 执行快照 | 已验证 |
+| L9 | `open_aigc.public.pattern_mining_element` | Pattern V2 元素快照 | 已验证 |
+| L10 | `open_aigc.public.pattern_itemset` | Pattern V2 itemset | 已验证 |
+| L11 | `open_aigc.public.pattern_itemset_item` | Pattern V2 itemset 成员 | 已验证 |
+| L12 | `loghubods.video_dimension_detail_add_column` | 视频表现回看 | 已验证 |
+
+### 7.2 详情
+
+#### L1. 数据库:`content-deconstruction-supply`,表:`demand_find_task`
+
+- 输入字段:`run_id`, `demand_content_id`, `status`, `created_at`, `token_coast`
+- 输出字段:执行状态、成本、需求关联。
+- 边界:只能看任务级结果,不能还原全量发现内容过程。
+
+#### L2. 数据库:`content-deconstruction-supply`,表:`demand_task_oprate`
+
+- 输入字段:`is_open`, `day_limit_coast`, `update_time`
+- 输出字段:是否开启、日成本限制。
+- 边界:策略控制数据,不是学习结论。
+
+#### L3. 数据库:`content-deconstruction-supply`,表:`demand_find_content_result`
+
+- 输入字段:`run_id`, `query`, `rank_no`, `channel`, `platform_content_id`, `process_trace`, `crawler_plan_id`, `produce_plan_id`, `publish_plan_id`, `web_html_url`, `source_evidence`
+- 输出字段:成功路径、平台、计划绑定、过程记录、来源证据。
+- 边界:没有失败待复看和淘汰原因结构化表;如果没有 `source_evidence` 或 source edge artifact,策略学习只能看到结果,不能 exact 回溯到 Pattern、Case 和分类树节点。
+
+#### L4. 数据库:`content-deconstruction-supply`,表:`demand_find_author`
+
+- 输入字段:`run_id`, `author_id`, `author_name`, `content_tags`, `elderly_ratio`, `elderly_tgi`, `is_good`, `channel`
+- 输出字段:作者表现和可复用标签。
+- 边界:后续需要与作品表现关联。
+
+#### L5. 数据库:`open_aigc`,表:`global_category`
+
+- 输入字段:`stable_id`, `name`, `source_type`, `path`, `parent_stable_id`, `category_nature`, `level`
+- 输出字段:分类树和稳定分类 ID。
+- 边界:上游概念层,非旧版实时输入。
+
+#### L6. 数据库:`open_aigc`,表:`global_element`
+
+- 输入字段:`id`, `name`, `source_type`, `belong_category_stable_id`, `element_sub_type`, `occurrence_count`
+- 输出字段:元素词和出现次数。
+- 边界:用于长期策略学习和 Pattern 生成。
+
+#### L7. 数据库:`open_aigc`,表:`element_classification_mapping`
+
+- 输入字段:`source_table`, `source_element_id`, `post_id`, `element_name`, `element_type`, `global_element_id`, `global_category_stable_id`, `classification_path`
+- 输出字段:元素到全局类目的映射。
+- 边界:用于理解上游元素如何进入 Pattern。
+
+#### L8. 数据库:`open_aigc PG`,表:`public.pattern_mining_execution`
+
+- 输入字段:`id`, `snapshot_date`, `is_current`, `status`, `post_count`, `category_count`, `element_count`, `topic_itemset_count`, `cross_itemset_count`, `start_time`, `end_time`, `error_message`
+- 输出字段:Pattern 执行状态和规模。
+- 边界:新版 DemandAgent 直接读取 PG Pattern V2;旧 PG -> MySQL bridge 仅作为历史风险说明。
+
+#### L9. 数据库:`open_aigc PG`,表:`public.pattern_mining_element`
+
+- 输入字段:`execution_id`, `post_id`, `source_table`, `source_element_id`, `element_type`, `element_sub_type`, `name`, `category_path`, `point_type`, `point_text`
+- 输出字段:元素快照和类目路径。
+- 边界:用于 PG Pattern V2 解释和后续回扣判断,不再服务旧 MySQL 兜底。
+
+#### L10. 数据库:`open_aigc PG`,表:`public.pattern_itemset`
+
+- 输入字段:`execution_id`, `combination_type`, `item_count`, `support`, `absolute_support`, `dimensions`, `is_cross_point`, `is_cross_layer`
+- 输出字段:Pattern 组合、支持度、维度。
+- 边界:新版 DemandAgent 读取它生成 `evidence_pack`;ContentFindAgent 通过 `evidence_pack/source_evidence` 间接消费,不直接连 PG。
+
+#### L11. 数据库:`open_aigc PG`,表:`public.pattern_itemset_item`
+
+- 输入字段:`itemset_id`, `layer`, `point_type`, `dimension`, `category_id`, `category_path`, `element_name`, `element_id`, `post_count`
+- 输出字段:itemset 中的元素项。
+- 边界:用于分析 Pattern 词和组合效果。
+
+#### L12. 数据库:`loghubods`,表:`video_dimension_detail_add_column`
+
+- 输入字段:`视频id`, `视频地址`, `标题`, `一级品类`, `二级品类`, `上传渠道`, `dt`
+- 表现字段:`当日分发曝光pv`, `当日分发回流uv`, `rov_t0`, `流量池曝光`, `流量池播放`, `流量池回流`, `推荐曝光`, `推荐播放`, `推荐回流`, `总日回流uv`
+- 输出字段:表现、曝光、播放、回流、标签。
+- 边界:宽表只列策略学习关键字段。
+
+## 8. 缺口清单
+
+本节吸收原环境缺口报告的缺口项。凡是没有真实表、真实 key、真实接口或只读验证证据的能力,都不能在产品或技术文档里写成“已接入”。
+
+### 8.1 P0 必须补齐
+
+#### 新版发现内容列表承载
+
+- 需要补:全量发现内容列表表或 API。
+- 业务用途:保存所有召回的视频、笔记、作者,包括入池、观察、淘汰和最终入选。
+- 当前状态:新版 DDL / schema registry 已定义为 `content_agent_discovered_content_items`;云库是否已建表并可写,按 P0 DB 验收确认。旧版未发现可承担该职责的真实表。
+- 中文注释:旧版只保存最终结果,无法复盘“未入选的发现内容”。
+
+#### 判断/淘汰日志承载
+
+- 需要补:规则包执行记录、硬门槛、软评分、淘汰原因、停止原因表或 API。
+- 业务用途:记录每个发现内容为什么继续、入池、观察、停止或淘汰。
+- 当前状态:新版 DDL / schema registry 已定义为 `content_agent_rule_decisions`;云库是否已建表并可写,按 P0 DB 验收确认。旧版未发现可承担该职责的真实表。
+- 中文注释:`process_trace` 只能粗略复盘,不能替代结构化规则日志。
+
+#### 来源关系承载
+
+- 需要补:数据源、seed、query、平台内容、作者、标签、游走路径关系表或 API;或先用 sidecar/source edge artifact 承载。
+- 业务用途:记录内容从哪里来、经过哪条路径来、由哪个规则放行,并从 `case_id/post_id` 回溯到分类树节点。
+- 当前状态:新版 DDL / schema registry 已定义为 `content_agent_source_path_records`;云库是否已建表并可写,按 P0 DB 验收确认。旧版未发现可承担该职责的真实表。
+- 中文注释:没有关系承载,策略学习无法按来源和路径归因;最终只剩 `platform_content_id + demand_content_id + process_trace` 时,无法 exact 追到 Pattern 和分类树。
+
+#### 搜索线索承载
+
+- 需要补:有效 query、失败 query、标签、话题、相关搜索线索表或 API。
+- 业务用途:保存下一轮可继续尝试的搜索线索,以及失败线索。
+- 当前状态:新版 DDL / schema registry 已定义为 `content_agent_search_clues`;云库是否已建表并可写,按 P0 DB 验收确认。旧版未发现可承担该职责的真实表。
+- 中文注释:旧版只在结果和 run_context 里间接留下 query,不够做系统学习。
+
+#### show 联调后端
+
+- 需要补:`VITE_API_BASE_URL`, `VITE_CONTENTFIND_API_BASE_URL`
+- 业务用途:让 show 从静态沙盘切到真实后端接口。
+- 当前状态:missing
+- 中文注释:当前前端只能展示策略和静态样例,不能跑真实链路。
+
+### 8.2 P1 生产增强
+
+#### TikHub fallback
+
+- 需要补:`TIKHUB_API_KEY`
+- 业务用途:Crawapi 抖音搜索异常、限流或不可用时做备用召回。
+- 当前状态:missing
+- 中文注释:URL 已定位,缺 key;不能写成已接入。
+
+#### OSS 过程链接
+
+- 需要补:`ALIYUN_OSS_ACCESS_KEY_ID`, `ALIYUN_OSS_ACCESS_KEY_SECRET`, `ALIYUN_OSS_BUCKET`, `ALIYUN_OSS_REGION`, `ALIYUN_OSS_PREFIX`, `ALIYUN_OSS_PUBLIC_BASE_URL`
+- 业务用途:保存任务日志、HTML 报告、截图、run_context 文件的可访问链接。
+- 当前状态:missing
+- 中文注释:旧版有上传能力线索,但当前缺真实 OSS 配置。
+
+#### 外部调度源
+
+- 需要补:`SCHEDULE_QUERY_API`, `SCHEDULE_QUERY_API_KEY`
+- 业务用途:从外部系统接收任务、定时需求或批量触发策略运行。
+- 当前状态:missing
+- 中文注释:当前没有真实调度入口。
+
+#### AIGC token 治理
+
+- 需要补:将旧版 fallback token 换成密钥平台托管值。
+- 业务用途:避免旧代码硬编码 token,保证后处理计划查询/绑定安全可维护。
+- 当前状态:source-only
+- 中文注释:这是安全治理,不是新增业务能力。
+
+### 8.3 P2 产品待验证
+
+#### 小红书笔记搜索、作者主页、作者笔记、话题标签接口
+
+- 当前状态:无旧版实测接口。
+- 中文注释:产品可以设计小红书路径,但技术文档不能写成已接入。
+
+#### 快手、B站、视频号、票圈平台适配接口
+
+- 当前状态:无旧版实测接口。
+- 中文注释:这些平台暂时不能复用抖音字段口径。
+
+#### 相关搜索、视频 tag、共创作者、相似作者、相似内容接口
+
+- 当前状态:无稳定字段或实测。
+- 中文注释:可以作为游走策略方向,但必须标为待验证。
+
+#### 养号推荐流账号、cookie/session、设备、代理/风控配置
+
+- 当前状态:无真实接入配置。
+- 中文注释:养号是产品意图源,不能伪装成已有旧版 DB/API backing。
+
+#### 策略实验、规则包版本、Prompt 版本、预算回写表/API
+
+- 当前状态:无真实承载。
+- 中文注释:策略学习需要这些承载,但当前没有真实表或 API。
+
+#### Pattern -> Item Set -> 多 Case
+
+- 当前状态:PG `pattern_itemset_post / pattern_itemset_item / pattern_mining_category` 字段存在,DemandAgent 新版已用于生成 `evidence_pack`;旧 MySQL 同名能力只作历史迁移说明。
+- 中文注释:新版重要来源只指 PG Pattern V2,不指旧 `topic_pattern_*` 兜底。
+
+## 9. 多平台 crawler 接口(crawler.aiddit.com)
+
+本节记录 2026-06-11 对 `crawler.aiddit.com` 10 个平台接口的真实抓包实测。机器可读台账见 [crawler_endpoints.registry.json](crawler_endpoints.registry.json)(接口级,共 26 条 endpoint),原始 capture 在 `/tmp/aiddit_captures/`。所有接口共用 `CONTENTFIND_API_CRAWAPI_BASE_URL`,限流间隔 ≥15s。
+
+状态标签:✅=本批实测 code=0 可用;⛔=失败/超时/不可达(附错误码);—=本平台无该能力或本批未抓到独立接口。
+
+### 9.1 平台能力矩阵
+
+| 平台 | 搜索 | 详情 | 作者作品 | 账号画像 | 视频可下载 |
+|---|---|---|---|---|---|
+| 抖音 douyin | ✅ `/dou_yin/keyword` | ✅ `/dou_yin/detail` | ✅ `/dou_yin/blogger` | ✅ `/dou_yin/re_dian_bao/account_fans_portrait`;内容画像 ⛔404 `video_like_portrait` | ✅(iOS UA+Referer 抖音) |
+| 快手 kuaishou | ✅ `/kuai_shou/keyword_v2` | ✅ `/kuai_shou/detail` | — 无独立接口,依赖搜索聚合 | ✅ `/kuai_shou/account_info` | ✅(Range+Referer 快手) |
+| 视频号 shipinhao | ✅ `/shi_pin_hao/keyword`(抖动需重试) | — | ⛔25011 `blogger` | ⛔10001 `account_info` | ✅(Referer channels.weixin) |
+| 小红书 xiaohongshu | ✅ `/xiao_hong_shu/keyword` | ✅ `/xiao_hong_shu/detail` | ⛔超时 `blogger` | — | — 图文为主(note_card 嵌套) |
+| B站 bilibili | ✅ `/bilibili/keyword` | ✅ `/bilibili/detail` | ⛔ 无作者接口 | — | ✅(m4s 分轨+Referer B站) |
+| 公众号 weixin | ✅ `/wei_xin/keyword` | ✅ `/wei_xin/detail` | ⛔ blogger 不可达,作者仅 biz | ✅ `/wei_xin/account_info`(仅昵称/biz补全,无作品列表) | — 图文,无 tag |
+| youtube | ✅ `/youtube/keyword` | ✅ `/youtube/detail` | — 无作者作品接口 | — | ⛔ detail 无视频地址(video_url_list=[]) |
+| github | ✅ `/github/keyword` | — | — | — | ⛔ 非视频(代码仓库,topics 即 tag) |
+| 知乎 zhihu | ⛔10000 全失败 | ⛔ | ⛔ | ⛔ | ⛔ |
+| 头条 toutiao | ⛔10000 全失败 | ⛔ | ⛔ | ⛔ | ⛔ |
+
+### 9.2 每平台一句话状态
+
+- **抖音**:全链路最完整,搜索/详情/作者作品/账号画像/视频下载均通;仅内容级人群画像 404 不可用。详见 `接口台账/抖音.md`。
+- **快手**:搜索/详情/账号info/视频下载通;无独立作者作品接口,author_to_works 暂依赖搜索聚合。详见 `接口台账/快手.md`。
+- **视频号**:搜索可用但服务端抖动需重试+退避;视频可下载;blogger 与 account_info 失败。详见 `接口台账/视频号.md`。
+- **小红书**:搜索/详情通,以图文为主(内容字段嵌在 note_card 下);blogger 超时不可落地。详见 `接口台账/小红书.md`。
+- **B站**:搜索/详情/视频下载通(m4s 分轨需合并);集合内无作者作品接口。详见 `接口台账/B站.md`。
+- **公众号**:搜索/详情/account_info 通,图文;作者仅 biz、blogger 不可达、整平台无 tag。详见 `接口台账/公众号.md`。
+- **youtube**:搜索/详情通,但 detail 无视频地址、无作者作品接口;hashtag 须从 body_text 正则抽。详见 `接口台账/youtube.md`。
+- **github**:仅搜索,且搜的是代码仓库非视频;topics 即 tag。详见 `接口台账/github.md`。
+- **知乎**:整平台 blocked,关键词搜索两次均 code=10000,下游全部阻断。详见 `接口台账/知乎.md`。
+- **头条**:整平台 blocked,关键词搜索两次均 code=10000,下游全部阻断。详见 `接口台账/头条.md`。
+
+### 9.3 缺口
+
+沿用「缺口统一放最后」的口径,本批 crawler 平台的明确缺口如下,均不能在产品或技术文档里写成"已接入":
+
+- **知乎 / 头条整平台不可用**:`/zhi_hu/keyword` 与 `/tou_tiao_hao/keyword` 两次抓包(含变参重试)均 `code=10000 / msg=未知错误 / data=null`,与参数无关,判定平台/接口侧不可用;detail/blogger/account_info/视频下载因搜索失败全部无样本,待上游修复复抓到 code=0 后再解锁登记。
+- **视频号 blogger / account_info 失败 + 搜索抖动**:`/shi_pin_hao/blogger` `code=25011`、`/shi_pin_hao/account_info` `code=10001`(仅传 account_id 被拒,需补 app_id 或 account_name);搜索首次 25011、重试才 code=0,必须带重试+退避。author_to_works 边当前不可落地。
+- **小红书 blogger 超时**:`/xiao_hong_shu/blogger` 请求超时 `error=timed out` 无响应,需超时重试+退避;author_to_works 边当前不可落地。
+- **B站无作者接口**:集合内无 author_to_works 数据源,作者维度仅作标识(以 `mid` 为准,`uid` 恒为 0 弃用)。
+- **公众号作者仅 biz**:search item 的 `biz/nick_name` 为空须从 url 正则抽 `__biz`;blogger 不可达、`account_info.publish_count=null` 无作品列表,author_to_works 走不通;整平台 `topic_list=null` 无 tag,video_to_hashtag 不可走。
+- **抖音内容画像 404**:`/dou_yin/re_dian_bao/video_like_portrait` 实测 HTTP 404 Not Found,内容级人群画像不可用,需上游确认正确 path 或下线,游走层不要挂该边(账号级画像 `account_fans_portrait` 仍可用)。
+- **youtube detail 无视频地址**:`/youtube/detail` 结构完整但 `video_url_list=[] / image_url_list=[]`,视频/图片文件不可经本平台接口直取,须另走字幕或其它通道。
+- **github 非视频**:`/github/keyword` 搜的是代码仓库(repo),无 video 字段,不能复用视频字段口径;`topics` 即 tag(多数为空)。

+ 484 - 0
数据接口与来源/01_DemandAgent输入合同.md

@@ -0,0 +1,484 @@
+# DemandAgent 给下游的迭代需求
+
+## 1. 结论先行
+
+新版 ContentFindAgent 不能再依赖旧 MySQL Pattern 反查机制来恢复 Pattern、Case 和分类树血缘。
+
+旧 MySQL `topic_pattern_*` 链路已删除弃用,不进入新版 `evidence_pack`,不作为下游回溯依据。旧字段只允许作为迁移前后的字段对照出现,用来说明它们在 PG Pattern V2 中被哪些字段替换。
+
+新版 DemandAgent 的唯一正式 Pattern 证据源是 PG `open_aigc.public` Pattern V2 主事实表。DemandAgent 输出的 `pattern_source_system` 唯一合法值是 `pg_pattern_v2`。
+
+为了新版能从需求出发稳定跑通数据源、Query、判断、游走、资产沉淀和策略学习,DemandAgent 或上游证据层需要把生成需求时已经知道的证据一起传给下游。
+
+更准确地说:DemandAgent 补 `demand_content.ext_data.evidence_pack` 是 Exact Mode 的必要条件,但不是充分条件。ContentFindAgent 还必须在领取需求、生成发现内容、判断筛选、最终入库时读取、继承并沉淀结构化 `source_evidence`,最终结果才能从 `post_id/platform_content_id` 回到具体 Pattern、itemset 和分类树节点。
+
+下游必须新增或扩展的核心字段:
+
+| 字段 | 作用 |
+| --- | --- |
+| `pattern_source_system` | DemandAgent 输出中固定且唯一合法值为 `pg_pattern_v2`,标记 Pattern 证据来自 PG Pattern V2 主事实 |
+| `pattern_execution_id` | 标记需求来自哪次 PG `pattern_mining_execution` |
+| `mining_config_id` | 标记来源 Pattern 使用的具体挖掘配置 |
+| `source_kind` | 标记需求来源是聚类结果、Pattern 频繁项集、直接 Case,还是其他来源 |
+| `case_id_type` | 标准化 `caseid` 的语义,例如本链路中应明确为 `post_id` |
+| `source_post_id` | 标记本条需求证据中的原始支撑帖子 |
+| `category_bindings` | 绑定分类节点,例如分类 ID、路径、层级、来源类型、点类型和维度 |
+| `element_bindings` | 绑定具体元素,例如元素名、元素类型、点类型、所属 post |
+| `itemset_ids` | 绑定 Pattern 频繁项集 |
+| `itemset_items[]` | 绑定 itemset 内每个 item 对应的分类节点、路径、点类型和维度 |
+| `support` / `absolute_support` | 记录 Pattern 支持度,判断它是不是稳定组合 |
+| `matched_post_ids` | 记录支撑 Pattern 的原始帖子或视频 |
+| `video_ids` / `case_ids` | 记录可作为 Case seed 的素材 ID;Pattern 来源下二者都是 `post_id` 语义 |
+| `decode_case_ids` | PG-only 当前固定为空数组的兼容字段,不参与 Pattern exact 闭合 |
+| `seed_terms` | 记录真正给 Query 使用的下层特征或元素词 |
+| `source_evidence` | ContentFindAgent 从 `evidence_pack` 继承并追加运行态字段后形成的下游结果证据,不由 DemandAgent 直接输出 |
+| `source_certainty` / `validation_status` | 标记证据是否已经 DB 强校验通过 |
+| `run_id` / `demand_content_id` / `demand_task_id` | `run_id` 是 CFA 本次运行 ID;`demand_content_id` 是 DemandAgent 需求主键;`demand_task_id` 在云端单表模式下可以为空,只作为上游任务线索 |
+
+V1 不一定马上改复杂 DB schema。可以先在 `demand_content.ext_data` 里增加一个结构化 `evidence_pack`,先把证据传下来。
+
+MVP 边界:DemandAgent 只输出 PG `pattern_itemset.scope='topic'` 的分类 Pattern 证据。`topic_element`、script、paragraph、group scope 暂不输出,因为它们不能保证每条证据都有 `category_id/category_path` 回到分类树节点。
+
+## 2. 新版下游到底需要什么
+
+新版 ContentFindAgent 不是只拿一个需求词去搜内容。它需要知道这个需求从哪里来、为什么成立、应该怎么生成 Query、判断结果应该绑定回哪棵分类树,以及最终资产入库前是否可追溯。
+
+下游需要的对象主要有五类。
+
+| 对象 | 下游含义 | 为什么需要 |
+| --- | --- | --- |
+| Pattern | 分类或元素的稳定组合 | 用来判断需求是不是有结构支撑,而不是单条素材偶然出现 |
+| Case | 支撑 Pattern 或需求的原始素材 | 用来查看素材原文、解构点、平台调性和后续判断证据 |
+| 分类 / 元素绑定 | 需求对应分类树的哪个父节点或子节点 | 所有游走、判断和入库结果都要能绑定回分类树 |
+| 支撑素材 | `matched_post_ids`、`video_ids`、Case ID 等 | 用来做 Query 输入、Case 回扣、判断规则证据和策略学习 |
+| run_context | 一路记录从需求到结果的路径 | 策略学习、失败复盘、入库追溯都需要它 |
+
+三类“有需求”的数据源都应该作为 DemandAgent 下游。它们不能只给一个自然语言需求名,还要给来源证据。不然后续即使找到内容,也说不清这个内容为什么服务于当初那个需求。
+
+所有资产入库前至少要保留:
+
+| 必留信息 | 用途 |
+| --- | --- |
+| 来源路径 | 证明资产从哪个需求、Pattern、Case 或平台线索来 |
+| 判断结果 | 证明为什么继续、入池、观察、淘汰 |
+| 分类或元素绑定 | 证明资产属于分类树中的哪个节点 |
+| 平台调性说明 | 证明资产适合当前平台,不是跨平台硬套 |
+| run_context | 支持策略学习和后续复盘 |
+
+## 3. DemandAgent 当前给了什么
+
+### 3.1 DemandItem
+
+DemandAgent 当前生成的 `DemandItem` 是 LLM / tool 产生的备选业务需求,不是最终给下游消费的强校验证据。
+
+代码证据:
+
+- `/Users/samlee/Documents/works/DemandAgentNew/examples/demand/demand_build_agent_tools.py:37`
+- `/Users/samlee/Documents/works/DemandAgentNew/examples/demand/demand_build_agent_tools.py:113`
+
+当前保留字段:
+
+| 字段 | 当前含义 |
+| --- | --- |
+| `element_names` | 需求名称来源,后续会拼成 `demand_content.name` |
+| `reason` | 生成需求的理由 |
+| `desc` | 需求描述,后续写入 `suggestion` |
+| `type` | 来源类型,例如元素、关系、分类 |
+| `evidence_refs` | LLM 声明的证据引用发现内容,只能作为 DB 强校验输入,不能直接给下游当真实证据 |
+
+`evidence_refs` 里即使出现 `itemset_ids/source_post_id/seed_terms`,也只是声明。DemandAgent 必须用 PG DB 重新读取和校验,再升级成 `demand_content.ext_data.evidence_pack`。任一最终字段来自旧 MySQL `topic_pattern_*` 时,该 DemandItem 必须 rejected。
+
+### 3.2 demand_content
+
+新版 DemandAgent V1 同时保留两种受控输出模式:
+
+- `local_json`:本地回归 / fixture 模式,只写本地 `demand_content.json` 等 JSON 文件,不作为 CFA 生产读取来源。
+- `mysql_demand_content`:云端测试服模式,只写 MySQL `content-deconstruction-supply.demand_content` 单表。
+
+两种模式给下游的正式证据载体都必须是 `demand_content.ext_data.evidence_pack`。云端单表模式不新建 `demand_task`,因此 `demand_task_id` 可以为空;CFA 不能把它当作必填主键。P0F 以后,CFA 正式需求读取应使用 MySQL `demand_content`,本地 JSON 只保留为回归 fixture。
+
+代码证据:
+
+- `/Users/samlee/Documents/works/DemandAgentNew/examples/demand/run.py`
+- `/Users/samlee/Documents/works/DemandAgentNew/examples/demand/evidence_pack_builder.py`
+- `/Users/samlee/Documents/works/DemandAgentNew/examples/demand/local_output_sink.py`
+- `/Users/samlee/Documents/works/DemandAgentNew/examples/demand/mysql_demand_content_sink.py`
+
+当前本地 `demand_content.json` 字段:
+
+| `demand_content` 字段 | 来源 |
+| --- | --- |
+| `merge_leve2` | 当前执行品类 |
+| `name` | `element_names` 逗号拼接 |
+| `reason` | DemandItem.reason |
+| `suggestion` | DemandItem.desc |
+| `score` | 按 `name` 拆分后查权重并求平均 |
+| `ext_data` | JSON 对象,包含旧业务字段 `reason/desc/type/video_ids`,以及新版强校验字段 `evidence_pack` |
+| `dt` | 当天日期 |
+
+注意:这里的字段名是历史真实表字段 `merge_leve2`,不是 `merge_level2`。CLI 或函数参数可以使用 `merge_level2` 作为变量名,但落到 `demand_content`、本地 JSON、下游读取契约时必须保持 `merge_leve2`。
+
+`video_ids` 在新版 PG-only 链路中来自 DB 校验后的 `evidence_pack.video_ids/matched_post_ids`。`pattern_execution_id` 指 PG `pattern_mining_execution.id`,不是旧 MySQL execution,也不是 DemandAgent 本地 run id。
+
+真实 DB 中 `demand_content.ext_data` 是 MySQL JSON 字段,可以承载完整 `evidence_pack`;但当前生产样例仍多为 `reason/desc/type/video_ids`,还没有稳定落下新版 PG `evidence_pack`。这就是本次需求要补齐的输出契约。
+
+### 3.3 dwd_multi_demand_pool_di
+
+新版 local MVP 不写 Hive,只生成本地 `dwd_multi_demand_pool_di.json` 镜像。这个文件不是给 ContentFindAgent 做 exact 回溯的主输入。
+
+代码证据:
+
+- `/Users/samlee/Documents/works/DemandAgentNew/examples/demand/data_query_tools.py:128`
+- `/Users/samlee/Documents/works/DemandAgentNew/examples/demand/data_query_tools.py:194`
+- `/Users/samlee/Documents/works/DemandAgentNew/examples/demand/data_query_tools.py:227`
+
+当前映射字段:
+
+| 字段 | 当前含义 |
+| --- | --- |
+| `strategy` | 策略名 |
+| `demand_id` | 派生 ID |
+| `demand_name` | 需求名 |
+| `weight` | 分数 |
+| `type` | 从 `ext_data.type` 解析 |
+| `video_count` | `video_ids` 数量 |
+| `video_list` | `video_ids` |
+| `extend` | 当前主要保留品类 |
+| `dt` | 分区日期 |
+
+这一层不增加 `evidence_pack`,不承载 Pattern exact evidence。ContentFindAgent 的主输入只能是 `demand_content.json` 或未来 DB `demand_content.ext_data.evidence_pack`。
+
+## 4. 旧 MySQL Pattern 链路为什么删除弃用
+
+旧版 ContentFindAgent 的 Case 反查工具是 `get_goodcase_topic_point`。
+
+代码证据:
+
+- `/Users/samlee/Documents/works/ContentFindAgent/examples/content_finder/tools/get_goodcase_topic_point.py:91`
+- `/Users/samlee/Documents/works/ContentFindAgent/examples/content_finder/tools/get_goodcase_topic_point.py:96`
+- `/Users/samlee/Documents/works/ContentFindAgent/examples/content_finder/tools/get_goodcase_topic_point.py:144`
+
+旧链路曾经是:
+
+```text
+features
+-> topic_pattern_element.name = feature
+-> post_id 交集
+-> workflow_decode_task_result.channel_content_id
+-> purpose_points / key_points / inspiration_points
+```
+
+这条链路已删除弃用,原因如下。
+
+| 问题 | 说明 |
+| --- | --- |
+| 不带 `execution_id` | 同一个词可能出现在多个 Pattern execution,不能证明来自当前需求那次执行 |
+| 只查元素名 | DemandAgent 当前有些需求名其实是分类节点,旧 CFA 只查 `topic_pattern_element.name` 会漏掉 |
+| 不查 itemset | 无法恢复 `itemset_id`、support、absolute support、matched posts |
+
+更关键的是,新版 DemandAgent 已切换为 PG Pattern V2 主事实。旧 MySQL `topic_pattern_element` 即使能查到 post,也不是新版 `evidence_pack` 的合法来源。
+
+因此旧链路不能作为任何兜底链路写入新版主血缘。它只保留在本文档中作为“删除弃用字段如何被 PG 字段替换”的迁移说明。
+
+## 5. 旧 MySQL 字段删除弃用与 PG 替换关系
+
+| 旧 MySQL 表/字段 | 新状态 | 新 PG 替换来源 |
+| --- | --- | --- |
+| `topic_pattern_execution.id` | 删除弃用 | `pattern_mining_execution.id`,即新版 `pattern_execution_id` |
+| `topic_pattern_execution.status` | 删除弃用 | `pattern_mining_execution.status` |
+| `topic_pattern_execution.cluster_name/merge_leve2/platform/account_name/post_limit/min_absolute_support/mining_configs` | 删除弃用为 Pattern 证据字段 | PG execution 是全局 Pattern 快照;业务侧 `merge_leve2/platform` 只保留在 Demand 输出上下文,不作为 Pattern 主事实 |
+| `topic_pattern_mining_config.id` | 删除弃用 | `pattern_mining_config.id`,即 `mining_config_id` |
+| `topic_pattern_mining_config.dimension_mode/target_depth` | 删除弃用 | 从 `pattern_mining_config.params` 解析或派生 |
+| `topic_pattern_category.id` | 删除弃用 | `pattern_mining_category.id` |
+| `topic_pattern_category.path` | 删除弃用 | `pattern_mining_category.path` |
+| `topic_pattern_category.category_nature` | 删除弃用 | `pattern_mining_category.category_nature` 和 `pattern_mining_category.classified_as` |
+| `topic_pattern_element.id/post_id/point_type/point_text/element_type/name/description/category_id/category_path` | 删除弃用 | `pattern_mining_element.id/post_id/point_type/point_text/element_type/name/description/category_id/category_path` |
+| `topic_pattern_itemset.id` | 删除弃用 | `pattern_itemset.id` |
+| `topic_pattern_itemset.mining_config_id` | 删除弃用 | `pattern_itemset.mining_config_id` |
+| `topic_pattern_itemset.support/absolute_support` | 删除弃用 | `pattern_itemset.support/absolute_support` |
+| `topic_pattern_itemset.matched_post_ids` | 删除弃用 | 从 `pattern_itemset_post` 按 `execution_id + itemset_id` 聚合生成 `matched_post_ids` |
+| `topic_pattern_itemset_item.id/itemset_id/point_type/dimension/category_id/category_path/element_name` | 删除弃用 | `pattern_itemset_item.id/itemset_id/point_type/dimension/category_id/category_path/element_name`,并可补充 PG 新字段 `layer/element_id/post_count` |
+
+新版 `evidence_pack` 中不允许出现旧 MySQL 专属来源。字段名可以保留通用业务含义,例如 `itemset_ids`、`matched_post_ids`、`category_bindings`,但它们的值必须来自 PG Pattern V2。
+
+## 6. 必须补给下游的字段清单
+
+| 字段 | 字段意义 | 下游用途 | 为什么不能靠 CFA 自己补 | 缺失风险 |
+| --- | --- | --- | --- | --- |
+| `pattern_source_system` | Pattern 证据来源系统,DemandAgent 输出中唯一合法值为 `pg_pattern_v2` | 判断反查目标是 PG Pattern V2 主事实 | CFA 只看需求单无法知道证据来自哪套 Pattern 表 | 把旧 MySQL 删除弃用链路误当 PG 主事实 |
+| `pattern_execution_id` | 当前需求来源的 Pattern 执行 ID | 数据源详情、Pattern 回查、策略学习 | CFA 只能按词反查,无法知道当时 execution | 同名词跨 execution 混淆 |
+| `mining_config_id` | 当前 itemset 所属挖掘配置 ID | 区分同一 execution 下不同 Pattern 配置 | CFA 事后只靠 post 反查会得到多个配置下的 itemset | 无法确定具体 Pattern 配置 |
+| `source_kind` | 来源类型:聚类结果、Pattern 频繁项集、直接 Case 等 | 决定后续流程:是否进 Query,是否先游走或先判断 | 只看 `type` 不够,不能区分真实来源路径 | 不同来源走错流程 |
+| `case_id_type` | `caseid` 的 ID 语义,Pattern case 链路中应明确为 `post_id` | 稳定对齐 `post_id/channel_content_id/platform_content_id` | CFA 只能猜这个 ID 是结果表 id、decode id 还是 post id | join 语义混乱 |
+| `source_post_id` | 本条证据里的原始支撑帖子 ID | 从最终 case 回到上游 matched post | 单个 post 可能支撑很多 itemset,CFA 不能知道哪条是来源 post | 只能得到多条可能路径,不能 exact |
+| `category_bindings` | 分类节点绑定,当前包含 `itemset_id/itemset_item_id/category_id/category_name/category_path/category_full_path/category_source_type/category_level/point_type/dimension/element_name` | 所有结果绑定回分类树节点 | CFA 按元素名查不到分类节点,且同名分类可能多处存在 | 入库后无法解释属于哪个分类 |
+| `element_bindings` | 元素绑定,当前包含 `itemset_id/itemset_item_id/category_id/point_type/dimension/element_name/matched_element_count/matched_post_count/matched_post_ids/sample_elements` | 作为 Query 输入素材、判断回扣证据 | CFA 可以按词查元素,但不知道哪个是 DemandAgent 采用的 | Query seed 可能跑偏 |
+| `itemset_ids` | Pattern 频繁项集 ID | 回查 Pattern 组合和稳定性 | CFA 旧链路不查 itemset | 不能证明 Pattern 是组合,不是散词 |
+| `itemset_items[]` | itemset 内每个 item 对应的 `category_id/category_path/point_type/dimension/element_name` | 直接还原 Pattern chip 到分类树节点 | CFA 只靠 `itemset_id` 还要二次猜 item 和节点 | 不能稳定解释具体命中的分类树节点 |
+| `support` | 相对支持度 | 判断 Pattern 是否稳定 | 需求池当前没有保存 | 无法按稳定性排序或过滤 |
+| `absolute_support` | 绝对支撑素材数 | 判断有多少素材支撑 | 需求池当前没有保存 | 不能区分单例和稳定模式 |
+| `matched_post_ids` | 支撑 itemset 的帖子 ID 列表 | 找 Case、看原始素材、做回扣判断 | `video_ids` 不等价于 itemset 的 matched posts | Case 来源不准,支撑证据不准 |
+| `video_ids` / `case_ids` | 可直接作为 Case seed 的素材 ID;Pattern 来源下固定是 `post_id` 语义 | 数据源 Case、Query 输入、判断证据 | CFA 可偶尔从 decode 表命中,但不稳定 | 如果语义不清,容易把 post_id 和 decode row id 混用 |
+| `decode_case_ids` | PG-only 当前固定为空数组的兼容字段 | 明确 decode row ID 不参与本次 Pattern exact 闭合 | 本次主链路不读旧 decode-case 表 | 不能把 decode 缺失误判成 Pattern 证据失败 |
+| `seed_terms` | 真正用于 Query 的下层特征或元素词 | Query 输入素材 | `name` 可能是分类、关系或宽泛表达,不一定适合作 Query | Query 输入不稳定 |
+| `source_evidence` | 下游最终结果继承的结构化证据,不是 DemandAgent 输出字段 | 写入 `demand_find_content_result` 或 source edge artifact | DemandAgent 只能给 `evidence_pack`,无法替下游结果落库 | 最终结果又断在 `process_trace` 文本 |
+| `source_certainty` | 证据可信度,进入下游时必须为 `db_validated` | 下游判断是否能 exact 回溯 | CFA 无法判断 LLM 声明是否已被 DB 校验 | 把备选证据误当真实证据 |
+| `validation_status` | DemandAgent 证据校验状态,进入需求池时必须为 `passed` | 下游只消费通过校验的任务 | CFA 事后补查无法恢复生成时的拒绝原因 | 失败证据流入下游 |
+| `run_id` | 贯穿下游任务的 run_context | 策略学习、失败复盘 | CFA 可创建自己的 run_context,但不能补上游生成过程 | 上下游链路断开 |
+| `demand_task_id` | DemandAgent 侧任务 ID | 回查生成日志和任务状态 | CFA 无法凭需求名可靠找到唯一任务 | 无法定位上游运行 |
+| `demand_content_id` | 下游领取的需求 ID | CFA 主任务绑定 | 这个字段 CFA 已能拿到,但应进入统一证据包 | run_context 不统一 |
+
+## 7. 检查过程与证据
+
+### 7.1 DemandAgent 文档审计
+
+`/Users/samlee/Documents/works/DemandAgent工程文档集/demand-agent-analysis.md:432` 已写明 DemandItem 到 `demand_content` 的映射:
+
+| 目标字段 | 来源 |
+| --- | --- |
+| `merge_leve2` | 当前执行品类 |
+| `name` | `element_names` 拼接 |
+| `reason` | DemandItem.reason |
+| `suggestion` | DemandItem.desc |
+| `score` | 权重 JSON 查分求平均 |
+| `ext_data` | `reason/desc/type/video_ids` |
+| `dt` | 当天日期 |
+
+历史文档曾把 `workflow_decode_task_result` 作为辅助回填逻辑;PG-only MVP 不再依赖它闭合 Pattern 证据。Agent 输出主要靠 Prompt 约束,最终是否进入需求池由 DemandAgent 代码按 PG DB 强校验决定。
+
+### 7.2 DemandAgent 代码审计
+
+DemandAgent 新版代码里直接读取 PG Pattern V2 的分类、元素、itemset 和支撑帖子字段。
+
+代码证据:
+
+- PG repository:`/Users/samlee/Documents/works/DemandAgentNew/examples/demand/pg_pattern_repository.py`
+- PG tool adapter:`/Users/samlee/Documents/works/DemandAgentNew/examples/demand/pattern_builds/pg_pattern_service.py`
+- Evidence 强校验:`/Users/samlee/Documents/works/DemandAgentNew/examples/demand/evidence_pack_builder.py`
+
+关键字段包括:
+
+| 表 | 关键字段 |
+| --- | --- |
+| `pattern_mining_execution` | `id`, `status`, `topic_itemset_count`, `post_count`, `category_count`, `element_count` |
+| `pattern_mining_config` | `id`, `execution_id`, `algorithm`, `scope`, `name`, `params` |
+| `pattern_itemset` | `id`, `execution_id`, `mining_config_id`, `scope`, `support`, `absolute_support`, `dimensions` |
+| `pattern_itemset_post` | `execution_id`, `itemset_id`, `post_id` |
+| `pattern_itemset_item` | `itemset_id`, `point_type`, `dimension`, `category_id`, `category_path`, `element_name` |
+| `pattern_mining_category` | `id`, `execution_id`, `source_type`, `path`, `level`, `parent_id`, `classified_as` |
+| `pattern_mining_element` | `execution_id`, `post_id`, `source_table`, `point_type`, `element_type`, `name`, `category_id`, `category_path` |
+
+也就是说,PG 主事实表已经具备 DemandAgent 输出下游证据链所需字段。新版问题不是“上游没有”,而是 DemandAgent 必须把这些字段校验后写进 `demand_content.ext_data.evidence_pack`,并要求下游继续继承。
+
+### 7.3 旧 ContentFindAgent 代码审计
+
+旧 CFA 的 `get_goodcase_topic_point` 只按 `topic_pattern_element.name` 精确匹配。
+
+关键 SQL:
+
+```sql
+SELECT DISTINCT post_id
+FROM topic_pattern_element
+WHERE name = %s
+```
+
+这个 SQL 不带 `execution_id`、`category_id`、`itemset_id`,也不查分类树节点。更重要的是,它读取的是已删除弃用的旧 MySQL `topic_pattern_element`,不能进入新版 PG `evidence_pack`。
+
+### 7.4 真实 DB 只读抽样
+
+本轮只做了只读查询,没有写 DB,也没有输出 secret。
+
+PG Pattern V2 主事实表只读校对结论:
+
+| PG 表 | 行数 | 字段结论 |
+| --- | --- |
+| `pattern_mining_execution` | 7 | 有 `id/status/snapshot_date/is_current/is_retired/post_filter/post_count/classify_execution_id/category_count/element_count/topic_itemset_count/topic_element_itemset_count` |
+| `pattern_mining_config` | 45 | 有 `id/execution_id/algorithm/scope/name/params/transaction_count/result_count/input_bucket_key` |
+| `pattern_mining_category` | 25816 | 有 `id/execution_id/source_stable_id/source_type/name/description/path/level/parent_id/category_nature/classified_as` |
+| `pattern_mining_element` | 1950755 | 有 `id/execution_id/post_id/source_table/source_element_id/element_type/name/category_id/category_path/point_type/point_text/topic_point_id` |
+| `pattern_itemset` | 449216 | 有 `id/execution_id/mining_config_id/scope/support/absolute_support/dimensions/is_cross_point/is_cross_layer`,没有 `matched_post_ids` 列 |
+| `pattern_itemset_item` | 1808629 | 有 `id/itemset_id/layer/point_type/dimension/category_id/category_path/element_name/element_id/post_count` |
+| `pattern_itemset_post` | 3910262 | 有 `itemset_id/post_id/execution_id`,是新版 `matched_post_ids` 的唯一来源 |
+
+需求池真实表只读校对结论:
+
+| 表 | 行数 | 字段 |
+| --- | --- | --- |
+| `demand_content` | 29888 | `id/merge_leve2/name/reason/suggestion/ext_data/score/dt/create_time/update_time` |
+| `demand_task` | 1987 | `id/execution_id/name/platform/status/log/create_time/update_time` |
+
+`demand_content.ext_data` 是 JSON 字段,可以承载完整 `evidence_pack`。当前生产样例仍主要是 `desc/reason/type/video_ids`,没有稳定出现新版 `pg_pattern_v2` 的 `evidence_pack`,所以这仍是待补齐的输出契约。
+
+### 7.5 subagent 交叉验证
+
+本轮拆了三个 subagent 交叉验证。
+
+| subagent | 验证范围 | 结论 |
+| --- | --- | --- |
+| PG/MySQL DB 字段侧 | PG Pattern V2、旧 MySQL `topic_pattern_*`、需求池表字段 | PG V2 能支撑新版证据链;旧 MySQL 字段必须删除弃用,只作为迁移对照 |
+| DemandAgent 代码侧 | PG repository、tool adapter、`evidence_pack_builder`、local output | 当前主路径读取 PG Pattern V2 并写本地 JSON,`evidence_pack.pattern_source_system` 为 `pg_pattern_v2` |
+| ContentFindAgentNew 下游侧 | `source_context.ext_data.evidence_pack`、`source_evidence`、校验器 | 下游需要继承 DemandAgent 的 PG `evidence_pack`,再追加运行态 `source_evidence` 字段 |
+
+三个方向结论一致。
+
+## 8. 建议的交付方式
+
+V1 建议先不要大改表结构,先扩展 `demand_content.ext_data`。
+
+推荐结构:
+
+```json
+{
+  "reason": "...",
+  "desc": "...",
+  "type": "...",
+  "video_ids": ["51978710"],
+  "evidence_pack": {
+    "pattern_source_system": "pg_pattern_v2",
+    "source_kind": "pattern_itemset",
+    "case_id_type": "post_id",
+    "source_post_id": "51978710",
+    "pattern_execution_id": 581,
+    "mining_config_id": 2082,
+    "itemset_ids": [1608352],
+    "itemset_items": [
+      {
+        "itemset_id": 1608352,
+        "category_id": 76006,
+        "category_path": "/理念/观念/个人观念/情感认同/国家民族认同/爱国情感",
+        "point_type": null,
+        "dimension": "需求",
+        "element_name": null
+      }
+    ],
+    "category_bindings": [],
+    "element_bindings": [],
+    "support": 0.0045734552921411235,
+    "absolute_support": 49,
+    "matched_post_ids": ["51978710"],
+    "video_ids": ["51978710"],
+    "case_ids": ["51978710"],
+    "decode_case_ids": [],
+    "seed_terms": ["爱国情感", "人物故事"],
+    "run_id": "...",
+    "demand_task_id": 123,
+    "demand_content_id": 456,
+    "source_certainty": "db_validated",
+    "validation_status": "passed"
+  }
+}
+```
+
+字段可以分批补齐:
+
+| 阶段 | 建议 |
+| --- | --- |
+| V1 必须 | `pattern_source_system`, `source_kind`, `case_id_type`, `source_post_id`, `pattern_execution_id`, `mining_config_id`, `itemset_ids`, `itemset_items[]`, `category_bindings`, `element_bindings`, `support`, `absolute_support`, `matched_post_ids`, `video_ids/case_ids`, `seed_terms`, `run_id`, `source_certainty`, `validation_status` |
+| V1 兼容字段 | `decode_case_ids`,PG-only 当前固定为空数组;如后续重新引入 decode row ID,需要另做下游契约 |
+| V1.1 增强 | 独立证据表、下游完整判断日志、topic_element 后续分类树补齐方案 |
+| 后续再拆表 | 如果 `evidence_pack` 变大,再考虑独立证据表或关系表 |
+
+注意:本次 MVP 只下发 `source_kind=pattern_itemset` 且 PG `scope='topic'` 的需求;如果来源不是该类 Pattern 频繁项集,暂不进入 exact 输出。
+
+### 8.1 DemandAgent 必须保证的真实性边界
+
+给下游 ContentFindAgent 的任务证据链必须真实。LLM 只能在 `evidence_refs` 里声明引用,不能直接决定最终证据。
+
+当前 MVP 中,LLM 生成需求时仍只写 `evidence_refs` 引用声明;DemandAgent 代码会基于 PG DB 只读校验并升级为 `evidence_pack`。推荐 `evidence_refs` 形态如下:
+
+```json
+{
+  "source_kind": "pattern_itemset",
+  "source_tool": "get_itemset_detail",
+  "itemset_ids": [1608352],
+  "category_ids": [76006, 76848],
+  "source_post_id": "51978710",
+  "case_ids": {
+    "pattern_itemset": ["51978710"]
+  },
+  "seed_terms": ["爱国情感", "人物故事"]
+}
+```
+
+LLM 最好显式声明 `source_kind=pattern_itemset`;如果漏填但已经给出 `itemset_ids` 或 `source_tool=get_itemset_detail`,DemandAgent 内部可以安全补齐为 `pattern_itemset`,然后继续真实 DB 强校验。`source_post_id` 必须来自 `get_itemset_detail` 的 `post_ids/matched_post_ids` 或已查询过的 `get_post_elements` 结果。`case_ids` 在待复看阶段可以按 `source_kind` 分组;最终 `evidence_pack.case_ids` 对 Pattern 来源固定为 post_id 列表,decode 表行 ID 另放 `decode_case_ids`。
+
+DemandAgent 代码必须按真实 DB 校验并补齐 `evidence_pack`。对于 `source_kind=pattern_itemset` 的需求,必须确认:
+
+| 校验项 | 必须满足 |
+| --- | --- |
+| `pattern_execution_id` | PG `pattern_mining_execution.id` 必须存在且 `status='success'` |
+| `source_kind` | 最终 `evidence_pack` 必须是 `pattern_itemset`;LLM 漏填时可由 `itemset_ids/source_tool` 安全推断,不是 Pattern itemset 则拒绝 |
+| `itemset_ids` | 每个 itemset 都属于当前 PG execution,且 `pattern_itemset.scope='topic'`,能查到 `mining_config_id/support/absolute_support/matched_post_ids` |
+| `mining_config_id` | 必须来自 PG `pattern_itemset.mining_config_id`,并能 join 到同一 execution 且 `scope='topic'` 的 `pattern_mining_config` |
+| `source_post_id` | 必须在对应 itemset 的 `pattern_itemset_post.post_id` 聚合结果中 |
+| `matched_post_ids` | 必须由 PG `pattern_itemset_post` 聚合得到,非空,`COUNT(DISTINCT post_id)` 必须等于 `absolute_support` |
+| `itemset_items[]` | 必须能从 PG `pattern_itemset_item` 查到,并能 join 到当前 execution 的 `pattern_mining_category` |
+| `category_bindings` | `category_id` 必须属于当前 `pattern_execution_id`,不能跨 execution 借节点 |
+| `element_bindings` | 必须能用 `execution_id + source_post_id + category_id + point_type + dimension/element_type + element_name(如有)` 精确绑定到 PG `pattern_mining_element`,且限定 `source_table='post_decode_topic_point_element'` |
+| `source_certainty` / `validation_status` | 进入 `demand_content` 时只能是 `db_validated` / `passed` |
+
+在当前官方 `local_json` 和 `mysql_demand_content` 两种路径中,任一必需字段查不到、跨 execution、post 不在 matched posts、category 不在当前 execution、source post 精确 element binding 不成立,当前 DemandItem 都失败,不写入下游可消费的 `demand_content`。本地模式失败项进入 `rejected_demand_items.json`;云端单表模式不写入 `demand_content` 成功记录。
+
+任一最终证据字段来自旧 MySQL `topic_pattern_*` 时,同样必须 rejected。新版 exact evidence 不允许 MySQL 兜底。
+
+对 `source_kind=pattern_itemset` 的需求,`case_ids` 按 `post_id` 语义直接等于已校验的 `matched_post_ids`,因为 PG Pattern V2 的主支撑关系来自 `pattern_itemset_post`;兼容字段 `decode_case_ids` 当前固定为空数组。`source_post_id/itemset_ids/itemset_items/mining_config_id/matched_post_ids/support/absolute_support` 不可为空且必须 DB 校验通过。
+
+### 8.2 V1 双输出方式
+
+V1 有两种受控输出方式:
+
+- `local_json`:通过 `examples.demand.run_existing_execution_local` 读取已有 PG `pattern_mining_execution.id`,把输出写到本地,只作为回归 fixture。
+- `mysql_demand_content`:通过 `examples.demand.run_existing_execution_mysql` 读取已有 PG `pattern_mining_execution.id`,只写 MySQL `demand_content` 单表,不写 `demand_task`、Hive、PG 或其他 MySQL 表。
+
+本地输出目录:
+
+```text
+examples/demand/test_output_data/{run_id}/
+  run_manifest.json
+  demand_task.json
+  demand_items.json
+  rejected_demand_items.json
+  demand_content.json
+  dwd_multi_demand_pool_di.json
+  feature_point_data.json
+  intermediate/result/
+  intermediate/data/
+  .run_context/
+  output/
+```
+
+其中只有 `demand_content.json[].ext_data.evidence_pack` 是给下游 exact evidence 的新增载体;`dwd_multi_demand_pool_di.json` 和 `feature_point_data.json` 只做原业务字段镜像,不增加 `evidence_pack`。
+
+云端测试服输出只看 `content-deconstruction-supply.demand_content.ext_data.evidence_pack`。CFA 领取真实需求池时,应优先从该 MySQL 单表解析证据包。
+
+### 8.3 ContentFindAgent 接到需求后必须做什么
+
+ContentFindAgent 后续领取 `demand_content` 时,不能只取 `id/name/suggestion/score/merge_leve2/dt`,还必须解析 `ext_data.evidence_pack`。
+
+它需要把 `source_kind/source_post_id/pattern_execution_id/mining_config_id/itemset_ids/itemset_items/category_bindings/matched_post_ids/source_certainty` 注入数据源、Query、判断、游走、入库上下文。最终结果必须保存结构化 `source_evidence` 到 `demand_find_content_result` 或 sidecar/source edge artifact。
+
+ContentFindAgentNew 生成 `source_evidence` 时,需要继承 DemandAgent 的 `evidence_pack`,并追加运行态字段:`discovery_start_source/previous_discovery_step/origin_path_id/search_query_id/query/search_query_generation_method/discovered_platform_content_id/discovery_relation/source_path_record_ids`。这些字段不由 DemandAgent 预写完整。当前 CFA validator 已强校验 `discovery_start_source/previous_discovery_step/origin_path_id/discovered_platform_content_id`,并校验 `source_evidence` 与 `evidence_pack` 的 `pattern_source_system/pattern_execution_id/source_post_id/case_id_type/mining_config_id/source_certainty/validation_status/itemset_ids/itemset_items/matched_post_ids/seed_terms` 保持一致;`search_query_id/query/search_query_generation_method/discovery_relation/source_path_record_ids` 当前由生成逻辑追加,后续如要作为硬门槛,需要在 CFA validator 中继续加严。
+
+如果新找到的 `platform_content_id/post_id` 不在 DemandAgent 的 `source_post_id/matched_post_ids` 中,只能标记为 `derived` 或 `discovered_content_item`,不能声称它 exact 属于某个 Pattern 节点。除非下游额外完成新 post 的解构和分类绑定,否则 DemandAgent 的证据只能证明“这个需求来源于某 Pattern”,不能证明“这个新 post 属于这个 Pattern”。
+
+## 9. 下游使用方式
+
+| 下游阶段 | 怎么使用这些字段 |
+| --- | --- |
+| 数据源 | 展示 Pattern、Case、分类/元素绑定和原始支撑素材 |
+| Query | 使用 `seed_terms` 作为 Query 输入素材,不直接把宽泛 `name` 当 Query |
+| Platform | 根据来源平台和 seed 生成平台适配 Query |
+| 判断 | 用分类/元素绑定、Case 原文和 support 做回扣判断 |
+| 游走 | 每次游走结果绑定回分类或元素节点,避免无限漂移 |
+| 资产清洗沉淀 | 入库前保留来源路径、判断结果、分类或元素绑定、平台调性说明、run_context 和结构化 `source_evidence` |
+| 策略学习 | 用 run_context 回看哪类来源、哪类 seed、哪类规则包有效 |
+
+## 10. 最终判断
+
+旧版 ContentFindAgent 的 MySQL Pattern 反查已删除弃用,不能承担新版主血缘,也不能作为新版 `evidence_pack` 的兜底来源。
+
+如果新版要求精准找到 Pattern、Case、分类或元素绑定,并让所有入库资产可追溯,DemandAgent 必须把生成需求时已经知道的证据一并传给下游。
+
+最小可行做法是:先在 `demand_content.ext_data` 中增加 `evidence_pack`。这样 V1 可以先让需求单携带真实上游证据,不需要马上重构 DB schema,也能避免下游继续靠猜。
+
+但这只是 Exact Mode 的上游基础。最终 `demand_find_content_result` 能不能从 `platform_content_id/post_id` 回到具体 Pattern 和分类树节点,还取决于 ContentFindAgent 是否读取、继承并沉淀结构化 `source_evidence`。

+ 35 - 0
数据接口与来源/captures/_run_log.txt

@@ -0,0 +1,35 @@
+== douyin ==
+  [api] douyin_search: code=0 
+  [api] douyin_detail: code=0 
+  [api] douyin_blogger: code=0 
+  [api] douyin_profile_content: code=None ERR
+  [api] douyin_profile_author: code=0 
+  [dl] douyin_video_dl: status=206 bytes=1048576 video=True
+== shi_pin_hao ==
+  [api] sph_search: code=25011 
+== kuai_shou ==
+  [api] kuaishou_search: code=0 
+  [api] kuaishou_detail: code=0 
+  [api] kuaishou_account_info: code=0 
+  [dl] kuaishou_video_dl: status=206 bytes=546455 video=True
+== xiao_hong_shu ==
+  [api] xhs_search: code=0 
+  [api] xhs_detail: code=0 
+== zhi_hu ==
+  [api] zhihu_search: code=10000 
+  [api] zhihu_search_retry: code=10000 
+== bilibili ==
+  [api] bili_search: code=0 
+  [api] bili_detail: code=0 
+== wei_xin / gzh ==
+  [api] gzh_search: code=0 
+  [api] gzh_detail: code=0 
+  [api] gzh_account_info: code=0 
+== github ==
+  [api] github_search: code=0 
+== youtube ==
+  [api] youtube_search: code=0 
+  [api] youtube_detail: code=0 
+== tou_tiao_hao ==
+  [api] toutiao_search: code=10000 
+  [api] toutiao_search_retry: code=10000 

+ 74 - 0
数据接口与来源/captures/bili_detail.json

@@ -0,0 +1,74 @@
+{
+ "label": "bili_detail",
+ "url": "http://crawler.aiddit.com/crawler/bilibili/detail",
+ "request_body": {
+  "content_id": "BV1qd4y1x76w"
+ },
+ "response": {
+  "code": 0,
+  "msg": null,
+  "data": {
+   "has_more": false,
+   "next_cursor": null,
+   "data": {
+    "is_cache": true,
+    "channel": 8,
+    "channel_content_id": "BV1qd4y1x76w",
+    "content_link": "https://www.bilibili.com/video/BV1qd4y1x76w/",
+    "wx_sn": null,
+    "biz_info": null,
+    "title": "《彩虹》TimeZ~在夕阳下最后的拥抱 记得你甜美的心跳",
+    "content_type": "video",
+    "body_text": "作词: 宋秉洋\n作曲: 宋秉洋\n制作人: 司捷",
+    "location": null,
+    "source_url": null,
+    "mini_program": null,
+    "topic_list": [
+     "发现《彩虹》",
+     "音乐分享官",
+     "彩虹",
+     "TimeZ",
+     "音乐分享官5.0"
+    ],
+    "image_url_list": [
+     {
+      "image_type": 2,
+      "image_url": "http://i1.hdslb.com/bfs/archive/70c0159b529a300e77c20790b72c53462b58d38f.jpg"
+     }
+    ],
+    "video_url_list": [
+     {
+      "video_url": "https://xy115x231x41x20xy.mcdn.bilivideo.cn:8082/v1/resource/upgcxcode/83/03/907810383/907810383_nb3-1-30016.m4s?agrr=1&build=0&buvid=C1960389-FA32-8A09-0F3F-BCFBEF610D6791015infoc&bvc=vod&bw=59616&deadline=1781166245&dl=0&e=ig8euxZM2rNcNbdlhoNvNC8BqJIzNbfqXBvEqxTEto8BTrNvN0GvT90W5JZMkX_YN0MvXg8gNEV4NC8xNEV4N03eN0B5tZlqNxTEto8BTrNvNeZVuJ10Kj_g2UB02J0mN0B5tZlqNCNEto8BTrNvNC7MTX502C8f2jmMQJ6mqF2fka1mqx6gqj0eN0B599M%3D&f=u_0_0&gen=playurlv3&lrs=-1&mid=0&nbs=1&nettype=0&og=cos&oi=2947180651&orderid=0%2C3&os=coso1bv&platform=pc&qn_dyeid=756463a5266994400077d6f46a2a5485&sign=cada6d&traceid=trihGTYyDmnpJc_0_e_N&uipk=5&uparams=e%2Cnbs%2Cuipk%2Coi%2Cmid%2Cdeadline%2Cog%2Cplatform%2Ctrid%2Cgen%2Cos&upsig=e887c326ddc64700ab67fbd7dd5e7672",
+      "video_duration": 238
+     }
+    ],
+    "multi_bitrate": null,
+    "bgm_data": null,
+    "ad_info": null,
+    "is_original": false,
+    "voice_data": {
+     "is_cache": true,
+     "id_str": "30216",
+     "title": null,
+     "author": null,
+     "duration": 238,
+     "play_url": "https://xy111x32x167x77xy.mcdn.bilivideo.cn:8082/v1/resource/upgcxcode/83/03/907810383/907810383_nb3-1-30216.m4s?agrr=1&build=0&buvid=C1960389-FA32-8A09-0F3F-BCFBEF610D6791015infoc&bvc=vod&bw=50654&deadline=1781166245&dl=0&e=ig8euxZM2rNcNbdlhoNvNC8BqJIzNbfqXBvEqxTEto8BTrNvN0GvT90W5JZMkX_YN0MvXg8gNEV4NC8xNEV4N03eN0B5tZlqNxTEto8BTrNvNeZVuJ10Kj_g2UB02J0mN0B5tZlqNCNEto8BTrNvNC7MTX502C8f2jmMQJ6mqF2fka1mqx6gqj0eN0B599M%3D&f=u_0_0&gen=playurlv3&lrs=-1&mid=0&nbs=1&nettype=0&og=hw&oi=2947180651&orderid=0%2C3&os=bdbv&platform=pc&qn_dyeid=756463a5266994400077d6f46a2a5485&sign=96b04d&traceid=trHszcrFuJEses_0_e_N&uipk=5&uparams=e%2Cog%2Cnbs%2Cuipk%2Ctrid%2Cdeadline%2Cgen%2Cos%2Cplatform%2Coi%2Cmid&upsig=5dfff1ecc66a6212141f9b653b1c5fc1"
+    },
+    "channel_account_id": "1919171246",
+    "channel_account_name": "碍音乐",
+    "channel_account_avatar": null,
+    "item_index": null,
+    "view_count": null,
+    "play_count": 2602076,
+    "like_count": 33628,
+    "collect_count": 74847,
+    "comment_count": 1181,
+    "share_count": 5367,
+    "looking_count": null,
+    "publish_timestamp": 1669795676000,
+    "modify_timestamp": null,
+    "update_timestamp": 1781159045761
+   }
+  }
+ }
+}

+ 2932 - 0
数据接口与来源/captures/bili_search.json

@@ -0,0 +1,2932 @@
+{
+ "label": "bili_search",
+ "url": "http://crawler.aiddit.com/crawler/bilibili/keyword",
+ "request_body": {
+  "keyword": "彩虹"
+ },
+ "response": {
+  "code": 0,
+  "msg": null,
+  "data": {
+   "has_more": true,
+   "next_cursor": "2",
+   "data": [
+    {
+     "type": "video",
+     "id": 390658123,
+     "author": "碍音乐",
+     "mid": 1919171246,
+     "typeid": "130",
+     "typename": "音乐综合",
+     "arcurl": "http://www.bilibili.com/video/av390658123",
+     "aid": 390658123,
+     "bvid": "BV1qd4y1x76w",
+     "title": "《<em class=\"keyword\">彩虹</em>》TimeZ~在夕阳下最后的拥抱 记得你甜美的心跳",
+     "description": "作词: 宋秉洋\n作曲: 宋秉洋\n制作人: 司捷",
+     "pic": "//i1.hdslb.com/bfs/archive/70c0159b529a300e77c20790b72c53462b58d38f.jpg",
+     "play": 2602076,
+     "video_review": 3521,
+     "favorites": 74847,
+     "tag": "音乐分享官5.0,TimeZ,音乐分享官,彩虹",
+     "review": 1181,
+     "pubdate": 1669795676,
+     "senddate": 1669795676,
+     "duration": "3:58",
+     "badgepay": false,
+     "hit_columns": [
+      "title",
+      "tag"
+     ],
+     "view_type": "",
+     "is_pay": 0,
+     "is_union_video": 0,
+     "rec_tags": null,
+     "new_rec_tags": [],
+     "like": 32770,
+     "upic": "https://i2.hdslb.com/bfs/face/e1451a3190d10a3478edb748fd2a5056cee4db59.jpg",
+     "corner": "",
+     "cover": "",
+     "desc": "",
+     "url": "",
+     "rec_reason": "",
+     "danmaku": 3521,
+     "biz_data": null,
+     "is_charge_video": 0,
+     "vt": 0,
+     "enable_vt": 0,
+     "vt_display": "",
+     "subtitle": "",
+     "episode_count_text": "",
+     "release_status": 0,
+     "is_intervene": 0,
+     "area": 0,
+     "style": 0,
+     "cate_name": "",
+     "is_live_room_inline": 0,
+     "live_status": 0,
+     "live_time": "",
+     "online": 0,
+     "rank_index": 1,
+     "rank_offset": 1,
+     "roomid": 0,
+     "short_id": 0,
+     "spread_id": 0,
+     "tags": "",
+     "uface": "",
+     "uid": 0,
+     "uname": "",
+     "user_cover": "",
+     "parent_area_id": 0,
+     "parent_area_name": "",
+     "watched_show": null,
+     "cny_flag": 0,
+     "card_status": 0
+    },
+    {
+     "type": "video",
+     "id": 116567526545446,
+     "author": "VV音乐局",
+     "mid": 9666167,
+     "typeid": "130",
+     "typename": "音乐综合",
+     "arcurl": "http://www.bilibili.com/video/av116567526545446",
+     "aid": 116567526545446,
+     "bvid": "BV1Be5y6fEiA",
+     "title": "【𝐇𝐢-𝐑𝐞𝐬无损音质】|《<em class=\"keyword\">彩虹</em>》- 周杰伦 -‘看不见你的笑 我怎么睡得着’",
+     "description": "【Hi-Res无损音质】《彩虹》- 周杰伦\n——————————————\n你们的三连是我更新的最大动力!\n——————————————\n仅用于音乐分享,请支持正版!\n——————————————\n有其他想听的欢迎评论区留言~!",
+     "pic": "//i0.hdslb.com/bfs/archive/9ce72e354253bfbc103db3422fe5d9870166ef93.jpg",
+     "play": 59767,
+     "video_review": 222,
+     "favorites": 1199,
+     "tag": "hi-res无损,音乐分享官,听歌,周杰伦,音响,彩虹,华语,无损音质",
+     "review": 11,
+     "pubdate": 1778679620,
+     "senddate": 1779391828,
+     "duration": "4:24",
+     "badgepay": false,
+     "hit_columns": [
+      "title",
+      "description",
+      "tag"
+     ],
+     "view_type": "",
+     "is_pay": 0,
+     "is_union_video": 0,
+     "rec_tags": null,
+     "new_rec_tags": [],
+     "like": 492,
+     "upic": "https://i2.hdslb.com/bfs/face/ae0d28f7a465137bb6a95909ca859829863ada90.jpg",
+     "corner": "",
+     "cover": "",
+     "desc": "",
+     "url": "",
+     "rec_reason": "",
+     "danmaku": 222,
+     "biz_data": null,
+     "is_charge_video": 0,
+     "vt": 0,
+     "enable_vt": 0,
+     "vt_display": "",
+     "subtitle": "",
+     "episode_count_text": "",
+     "release_status": 0,
+     "is_intervene": 0,
+     "area": 0,
+     "style": 0,
+     "cate_name": "",
+     "is_live_room_inline": 0,
+     "live_status": 0,
+     "live_time": "",
+     "online": 0,
+     "rank_index": 2,
+     "rank_offset": 2,
+     "roomid": 0,
+     "short_id": 0,
+     "spread_id": 0,
+     "tags": "",
+     "uface": "",
+     "uid": 0,
+     "uname": "",
+     "user_cover": "",
+     "parent_area_id": 0,
+     "parent_area_name": "",
+     "watched_show": null,
+     "cny_flag": 0,
+     "card_status": 0
+    },
+    {
+     "type": "video",
+     "id": 116721071494832,
+     "author": "随安SuiAan",
+     "mid": 3546966858401857,
+     "typeid": "130",
+     "typename": "音乐综合",
+     "arcurl": "http://www.bilibili.com/video/av116721071494832",
+     "aid": 116721071494832,
+     "bvid": "BV1zhE26VEuc",
+     "title": "【循环歌单】|「<em class=\"keyword\">彩虹</em>」|『治愈の小曲』『毕业季の小曲』| “离别的眼泪我还不懂,回忆淡淡的就像风,期待一道<em class=\"keyword\">彩虹</em> 连接我们的天空”",
+     "description": "歌曲:《彩虹》\nwallpaper:[宵宫&amp;可莉]永远の夏天-原神\n\n-作品相关素材均来源于网络,若内容存在侵权行为,请联系我删除/下架处理,谢谢!",
+     "pic": "//i1.hdslb.com/bfs/archive/4c03b444a594ed4169db1b0f9e99c9bc14dd4ac0.jpg",
+     "play": 1856,
+     "video_review": 8,
+     "favorites": 164,
+     "tag": "电台新星征集令,歌单,听歌,彩虹,循环",
+     "review": 7,
+     "pubdate": 1781049600,
+     "senddate": 1781049646,
+     "duration": "63:55",
+     "badgepay": false,
+     "hit_columns": [
+      "title",
+      "description",
+      "tag"
+     ],
+     "view_type": "",
+     "is_pay": 0,
+     "is_union_video": 0,
+     "rec_tags": null,
+     "new_rec_tags": [],
+     "like": 103,
+     "upic": "https://i1.hdslb.com/bfs/face/53a0d66090ffd0a031f8f653da82cc95d4f587ca.jpg",
+     "corner": "",
+     "cover": "",
+     "desc": "",
+     "url": "",
+     "rec_reason": "",
+     "danmaku": 8,
+     "biz_data": null,
+     "is_charge_video": 0,
+     "vt": 0,
+     "enable_vt": 0,
+     "vt_display": "",
+     "subtitle": "",
+     "episode_count_text": "",
+     "release_status": 0,
+     "is_intervene": 0,
+     "area": 0,
+     "style": 0,
+     "cate_name": "",
+     "is_live_room_inline": 0,
+     "live_status": 0,
+     "live_time": "",
+     "online": 0,
+     "rank_index": 3,
+     "rank_offset": 3,
+     "roomid": 0,
+     "short_id": 0,
+     "spread_id": 0,
+     "tags": "",
+     "uface": "",
+     "uid": 0,
+     "uname": "",
+     "user_cover": "",
+     "parent_area_id": 0,
+     "parent_area_name": "",
+     "watched_show": null,
+     "cny_flag": 0,
+     "card_status": 0
+    },
+    {
+     "type": "video",
+     "id": 116668239977471,
+     "author": "七彩熊",
+     "mid": 85516461,
+     "typeid": "27",
+     "typename": "动画综合",
+     "arcurl": "http://www.bilibili.com/video/av116668239977471",
+     "aid": 116668239977471,
+     "bvid": "BV1niVJ64EY9",
+     "title": "耗费1000小时⚡⚡⚡用166部动画拼凑出一首《<em class=\"keyword\">彩虹</em>》",
+     "description": "bgm:《彩虹》——演唱:TimeZ(孔舒航/刘冠希等)\n作词/作曲:宋秉洋\n剪辑:七彩熊\n提前祝屏幕前的小朋友们儿童节快乐,祝屏幕前的大朋友们永远保持童心,永远快乐",
+     "pic": "//i0.hdslb.com/bfs/archive/7e0712b10c82b3720932d2bdd191656fc344f2da.jpg",
+     "play": 1555016,
+     "video_review": 2997,
+     "favorites": 172569,
+     "tag": "童年动画,童年回忆,彩虹,儿童节,六一",
+     "review": 3476,
+     "pubdate": 1780216339,
+     "senddate": 1780361231,
+     "duration": "3:25",
+     "badgepay": false,
+     "hit_columns": [
+      "title",
+      "description",
+      "tag"
+     ],
+     "view_type": "",
+     "is_pay": 0,
+     "is_union_video": 0,
+     "rec_tags": null,
+     "new_rec_tags": [],
+     "like": 284240,
+     "upic": "https://i0.hdslb.com/bfs/face/e65e80a90b1e8dc276a735e9c2f8d6c4409eca19.jpg",
+     "corner": "",
+     "cover": "",
+     "desc": "",
+     "url": "",
+     "rec_reason": "",
+     "danmaku": 2997,
+     "biz_data": null,
+     "is_charge_video": 0,
+     "vt": 0,
+     "enable_vt": 0,
+     "vt_display": "",
+     "subtitle": "",
+     "episode_count_text": "",
+     "release_status": 0,
+     "is_intervene": 0,
+     "area": 0,
+     "style": 0,
+     "cate_name": "",
+     "is_live_room_inline": 0,
+     "live_status": 0,
+     "live_time": "",
+     "online": 0,
+     "rank_index": 4,
+     "rank_offset": 4,
+     "roomid": 0,
+     "short_id": 0,
+     "spread_id": 0,
+     "tags": "",
+     "uface": "",
+     "uid": 0,
+     "uname": "",
+     "user_cover": "",
+     "parent_area_id": 0,
+     "parent_area_name": "",
+     "watched_show": null,
+     "cny_flag": 0,
+     "card_status": 0
+    },
+    {
+     "type": "video",
+     "id": 68874407,
+     "author": "zyl2012_音乐无限",
+     "mid": 13838234,
+     "typeid": "193",
+     "typename": "MV",
+     "arcurl": "http://www.bilibili.com/video/av68874407",
+     "aid": 68874407,
+     "bvid": "BV1fJ411M7fh",
+     "title": "【4K修复】周杰伦 - <em class=\"keyword\">彩虹</em> MV 2160P修复版",
+     "description": "转载自我自己修复\nDVD修复伪1080P,修复仅为提升观感\n--------------\n2020.3.17\n用简体版DVD重新修复,比原来的版本效果更好。字幕未改\n-----------------\n2022.03.14\n4K修复 音频修正",
+     "pic": "//i1.hdslb.com/bfs/archive/aa65476454f7fb7a72846556a55e4ada7ed0582f.jpg",
+     "play": 4079287,
+     "video_review": 6934,
+     "favorites": 44415,
+     "tag": "JAY,华语MV,MV,周董,我很忙,周杰伦,音乐,小公举,说好不哭",
+     "review": 1725,
+     "pubdate": 1569332335,
+     "senddate": 1738665096,
+     "duration": "4:33",
+     "badgepay": false,
+     "hit_columns": [
+      "title"
+     ],
+     "view_type": "",
+     "is_pay": 0,
+     "is_union_video": 0,
+     "rec_tags": null,
+     "new_rec_tags": [],
+     "like": 45816,
+     "upic": "https://i2.hdslb.com/bfs/face/e47b5bebf9947b04a092ee7553232736c164c4c8.jpg",
+     "corner": "",
+     "cover": "",
+     "desc": "",
+     "url": "",
+     "rec_reason": "",
+     "danmaku": 6934,
+     "biz_data": null,
+     "is_charge_video": 0,
+     "vt": 0,
+     "enable_vt": 0,
+     "vt_display": "",
+     "subtitle": "",
+     "episode_count_text": "",
+     "release_status": 0,
+     "is_intervene": 0,
+     "area": 0,
+     "style": 0,
+     "cate_name": "",
+     "is_live_room_inline": 0,
+     "live_status": 0,
+     "live_time": "",
+     "online": 0,
+     "rank_index": 5,
+     "rank_offset": 5,
+     "roomid": 0,
+     "short_id": 0,
+     "spread_id": 0,
+     "tags": "",
+     "uface": "",
+     "uid": 0,
+     "uname": "",
+     "user_cover": "",
+     "parent_area_id": 0,
+     "parent_area_name": "",
+     "watched_show": null,
+     "cny_flag": 0,
+     "card_status": 0
+    },
+    {
+     "type": "video",
+     "id": 613479442,
+     "author": "谢帝CoupleHunnid",
+     "mid": 618733904,
+     "typeid": "28",
+     "typename": "原创音乐",
+     "arcurl": "http://www.bilibili.com/video/av613479442",
+     "aid": 613479442,
+     "bvid": "BV1Wh4y1b7GR",
+     "title": "谢帝 <em class=\"keyword\">彩虹</em>(Official Lyrical Video)",
+     "description": "",
+     "pic": "//i0.hdslb.com/bfs/archive/af4b9c909357a30219dc990afad1f9bb541f0457.jpg",
+     "play": 1616693,
+     "video_review": 1181,
+     "favorites": 30020,
+     "tag": "说唱巅峰对决,嘻哈,说唱,歌词,中文说唱,音乐,说唱会馆,成都集团,谢帝",
+     "review": 2330,
+     "pubdate": 1683604800,
+     "senddate": 1683627722,
+     "duration": "3:15",
+     "badgepay": false,
+     "hit_columns": [
+      "title"
+     ],
+     "view_type": "",
+     "is_pay": 0,
+     "is_union_video": 0,
+     "rec_tags": null,
+     "new_rec_tags": [
+      {
+       "tag_name": "官方MV",
+       "tag_style": 2
+      }
+     ],
+     "like": 53854,
+     "upic": "https://i2.hdslb.com/bfs/face/f58941c7114b0623736bcf776087ab19f2f348e7.jpg",
+     "corner": "",
+     "cover": "",
+     "desc": "",
+     "url": "",
+     "rec_reason": "",
+     "danmaku": 1181,
+     "biz_data": null,
+     "is_charge_video": 0,
+     "vt": 0,
+     "enable_vt": 0,
+     "vt_display": "",
+     "subtitle": "",
+     "episode_count_text": "",
+     "release_status": 0,
+     "is_intervene": 0,
+     "area": 0,
+     "style": 0,
+     "cate_name": "",
+     "is_live_room_inline": 0,
+     "live_status": 0,
+     "live_time": "",
+     "online": 0,
+     "rank_index": 6,
+     "rank_offset": 6,
+     "roomid": 0,
+     "short_id": 0,
+     "spread_id": 0,
+     "tags": "",
+     "uface": "",
+     "uid": 0,
+     "uname": "",
+     "user_cover": "",
+     "parent_area_id": 0,
+     "parent_area_name": "",
+     "watched_show": null,
+     "cny_flag": 0,
+     "card_status": 0
+    },
+    {
+     "type": "video",
+     "id": 23060822,
+     "author": "守望天琴",
+     "mid": 46850964,
+     "typeid": "193",
+     "typename": "MV",
+     "arcurl": "http://www.bilibili.com/video/av23060822",
+     "aid": 23060822,
+     "bvid": "BV1xW411G7xL",
+     "title": "小马大法好!大张伟单曲《阳光<em class=\"keyword\">彩虹</em>小白马》官方MV",
+     "description": "网易云~\n马迷注意力,看大张伟衣服!",
+     "pic": "//i2.hdslb.com/bfs/archive/bee7203a94f73b4bf252e9804a563f3c74426158.jpg",
+     "play": 6616001,
+     "video_review": 10005,
+     "favorites": 68072,
+     "tag": "循环,阳光彩虹小白马,音乐,歌曲,彩虹小马,大张伟,单曲,MV,明星",
+     "review": 7480,
+     "pubdate": 1525593880,
+     "senddate": 1546519274,
+     "duration": "4:19",
+     "badgepay": false,
+     "hit_columns": [
+      "title",
+      "tag"
+     ],
+     "view_type": "",
+     "is_pay": 0,
+     "is_union_video": 0,
+     "rec_tags": null,
+     "new_rec_tags": [],
+     "like": 125229,
+     "upic": "https://i0.hdslb.com/bfs/face/d8d36525121618a1ab342537e7341605224ffb0d.jpg",
+     "corner": "",
+     "cover": "",
+     "desc": "",
+     "url": "",
+     "rec_reason": "",
+     "danmaku": 10005,
+     "biz_data": null,
+     "is_charge_video": 0,
+     "vt": 0,
+     "enable_vt": 0,
+     "vt_display": "",
+     "subtitle": "",
+     "episode_count_text": "",
+     "release_status": 0,
+     "is_intervene": 0,
+     "area": 0,
+     "style": 0,
+     "cate_name": "",
+     "is_live_room_inline": 0,
+     "live_status": 0,
+     "live_time": "",
+     "online": 0,
+     "rank_index": 7,
+     "rank_offset": 7,
+     "roomid": 0,
+     "short_id": 0,
+     "spread_id": 0,
+     "tags": "",
+     "uface": "",
+     "uid": 0,
+     "uname": "",
+     "user_cover": "",
+     "parent_area_id": 0,
+     "parent_area_name": "",
+     "watched_show": null,
+     "cny_flag": 0,
+     "card_status": 0
+    },
+    {
+     "type": "video",
+     "id": 807414608,
+     "author": "上海彩虹室内合唱团",
+     "mid": 21562856,
+     "typeid": "130",
+     "typename": "音乐综合",
+     "arcurl": "http://www.bilibili.com/video/av807414608",
+     "aid": 807414608,
+     "bvid": "BV1E34y1679J",
+     "title": "【<em class=\"keyword\">彩虹</em>合唱】《道别是一件难事》首演和唯一演出现场,既然忘不掉,不如就装着吧。",
+     "description": "今年新歌《道别是一件难事》演于 2021 年 11 月武汉琴台音乐厅。\n歌词中唱了“故乡”或“爱人”,“既然都忘不掉,不如就装着吧”。\n装字一语双关,也希望你能在北半球最长的夜,思念放不下的那些事。\n冬至快乐,朋友们。",
+     "pic": "//i0.hdslb.com/bfs/archive/21f8a0a415a9d6c6aa85da4d15bd7799f6ed856b.jpg",
+     "play": 3666707,
+     "video_review": 4724,
+     "favorites": 118366,
+     "tag": "全能音乐挑战赛",
+     "review": 4886,
+     "pubdate": 1640083635,
+     "senddate": 1640087084,
+     "duration": "4:52",
+     "badgepay": false,
+     "hit_columns": [
+      "title",
+      "author"
+     ],
+     "view_type": "",
+     "is_pay": 0,
+     "is_union_video": 0,
+     "rec_tags": null,
+     "new_rec_tags": [],
+     "like": 138502,
+     "upic": "https://i2.hdslb.com/bfs/face/3fb0f2c15e5102e7cf73d4da4c3a56e575b47cbc.jpg",
+     "corner": "",
+     "cover": "",
+     "desc": "",
+     "url": "",
+     "rec_reason": "",
+     "danmaku": 4724,
+     "biz_data": null,
+     "is_charge_video": 0,
+     "vt": 0,
+     "enable_vt": 0,
+     "vt_display": "",
+     "subtitle": "",
+     "episode_count_text": "",
+     "release_status": 0,
+     "is_intervene": 0,
+     "area": 0,
+     "style": 0,
+     "cate_name": "",
+     "is_live_room_inline": 0,
+     "live_status": 0,
+     "live_time": "",
+     "online": 0,
+     "rank_index": 8,
+     "rank_offset": 8,
+     "roomid": 0,
+     "short_id": 0,
+     "spread_id": 0,
+     "tags": "",
+     "uface": "",
+     "uid": 0,
+     "uname": "",
+     "user_cover": "",
+     "parent_area_id": 0,
+     "parent_area_name": "",
+     "watched_show": null,
+     "cny_flag": 0,
+     "card_status": 0
+    },
+    {
+     "type": "video",
+     "id": 116680386745914,
+     "author": "sky光遇_轩少",
+     "mid": 440993185,
+     "typeid": "21",
+     "typename": "日常",
+     "arcurl": "http://www.bilibili.com/video/av116680386745914",
+     "aid": 116680386745914,
+     "bvid": "BV1BHVr6jEuJ",
+     "title": "【sky光遇】2026 <em class=\"keyword\">彩虹</em>日全物品展示/新物品&amp;返场物品/新伪无翼斗篷/新裤子/贝雷帽/超夯风筝背饰/新发型/暗<em class=\"keyword\">彩虹</em>武士裤/(14件新物品/14件返场物品)",
+     "description": "-",
+     "pic": "//i2.hdslb.com/bfs/archive/47299b36637ae577e21e8dbc9f21cfe29d0f6a6d.jpg",
+     "play": 35255,
+     "video_review": 135,
+     "favorites": 714,
+     "tag": "我的宝藏光遇,新物品展示,返场物品,缤纷飞行日,我的光遇故事,必剪创作,光·遇,彩虹日,最强攻略,活动",
+     "review": 36,
+     "pubdate": 1780401640,
+     "senddate": 1780635770,
+     "duration": "6:0",
+     "badgepay": false,
+     "hit_columns": [
+      "title",
+      "tag"
+     ],
+     "view_type": "",
+     "is_pay": 0,
+     "is_union_video": 0,
+     "rec_tags": null,
+     "new_rec_tags": [],
+     "like": 851,
+     "upic": "https://i1.hdslb.com/bfs/face/d568e3aeb1b250384543108ea0385ba4f40f3d5f.jpg",
+     "corner": "",
+     "cover": "",
+     "desc": "",
+     "url": "",
+     "rec_reason": "",
+     "danmaku": 135,
+     "biz_data": null,
+     "is_charge_video": 0,
+     "vt": 0,
+     "enable_vt": 0,
+     "vt_display": "",
+     "subtitle": "",
+     "episode_count_text": "",
+     "release_status": 0,
+     "is_intervene": 0,
+     "area": 0,
+     "style": 0,
+     "cate_name": "",
+     "is_live_room_inline": 0,
+     "live_status": 0,
+     "live_time": "",
+     "online": 0,
+     "rank_index": 9,
+     "rank_offset": 9,
+     "roomid": 0,
+     "short_id": 0,
+     "spread_id": 0,
+     "tags": "",
+     "uface": "",
+     "uid": 0,
+     "uname": "",
+     "user_cover": "",
+     "parent_area_id": 0,
+     "parent_area_name": "",
+     "watched_show": null,
+     "cny_flag": 0,
+     "card_status": 0
+    },
+    {
+     "type": "video",
+     "id": 1055127082,
+     "author": "仮面ライダーX酱-代号X",
+     "mid": 158047022,
+     "typeid": "86",
+     "typename": "特摄",
+     "arcurl": "http://www.bilibili.com/video/av1055127082",
+     "aid": 1055127082,
+     "bvid": "BV1Qn4y1o73X",
+     "title": "[个人汉化]<em class=\"keyword\">彩虹</em>歌查德战斗曲完整版《THE SKY&#x27;S THE LIMIT》让那灰色的天空 绽放出<em class=\"keyword\">彩虹</em>的光辉!",
+     "description": "审核辛苦了~~",
+     "pic": "//i0.hdslb.com/bfs/archive/6116b8ec2b36de54b7ad3132c9c91d772a7353ff.jpg",
+     "play": 3215812,
+     "video_review": 13021,
+     "favorites": 45248,
+     "tag": "MV,混剪,彩虹歌查德,歌查德,假面骑士歌察德,假面骑士,MAD,特摄",
+     "review": 11118,
+     "pubdate": 1716652279,
+     "senddate": 1754239153,
+     "duration": "3:23",
+     "badgepay": false,
+     "hit_columns": [
+      "title",
+      "tag"
+     ],
+     "view_type": "",
+     "is_pay": 0,
+     "is_union_video": 0,
+     "rec_tags": null,
+     "new_rec_tags": [],
+     "like": 55177,
+     "upic": "https://i2.hdslb.com/bfs/face/1b35abe984793e0364188d70688dc1696b8f8b6c.jpg",
+     "corner": "",
+     "cover": "",
+     "desc": "",
+     "url": "",
+     "rec_reason": "",
+     "danmaku": 13021,
+     "biz_data": null,
+     "is_charge_video": 0,
+     "vt": 0,
+     "enable_vt": 0,
+     "vt_display": "",
+     "subtitle": "",
+     "episode_count_text": "",
+     "release_status": 0,
+     "is_intervene": 0,
+     "area": 0,
+     "style": 0,
+     "cate_name": "",
+     "is_live_room_inline": 0,
+     "live_status": 0,
+     "live_time": "",
+     "online": 0,
+     "rank_index": 10,
+     "rank_offset": 10,
+     "roomid": 0,
+     "short_id": 0,
+     "spread_id": 0,
+     "tags": "",
+     "uface": "",
+     "uid": 0,
+     "uname": "",
+     "user_cover": "",
+     "parent_area_id": 0,
+     "parent_area_name": "",
+     "watched_show": null,
+     "cny_flag": 0,
+     "card_status": 0
+    },
+    {
+     "type": "video",
+     "id": 116600845896360,
+     "author": "叔映画",
+     "mid": 49861748,
+     "typeid": "21",
+     "typename": "日常",
+     "arcurl": "http://www.bilibili.com/video/av116600845896360",
+     "aid": 116600845896360,
+     "bvid": "BV1yFL66bEc2",
+     "title": "《你的名字》<em class=\"keyword\">彩虹</em>大叔版:上",
+     "description": "-",
+     "pic": "//i1.hdslb.com/bfs/archive/668cc00ac5a4de9c9b2f7e05eb215c83c8f7e024.jpg",
+     "play": 15719,
+     "video_review": 75,
+     "favorites": 470,
+     "tag": "中年大叔,短片,原创",
+     "review": 79,
+     "pubdate": 1779187911,
+     "senddate": 1780338059,
+     "duration": "45:40",
+     "badgepay": false,
+     "hit_columns": [
+      "title"
+     ],
+     "view_type": "",
+     "is_pay": 0,
+     "is_union_video": 0,
+     "rec_tags": null,
+     "new_rec_tags": [],
+     "like": 409,
+     "upic": "https://i2.hdslb.com/bfs/face/4c46e723c888ce060a117396f73b0d3770bbe63a.jpg",
+     "corner": "",
+     "cover": "",
+     "desc": "",
+     "url": "",
+     "rec_reason": "",
+     "danmaku": 75,
+     "biz_data": null,
+     "is_charge_video": 0,
+     "vt": 0,
+     "enable_vt": 0,
+     "vt_display": "",
+     "subtitle": "",
+     "episode_count_text": "",
+     "release_status": 0,
+     "is_intervene": 0,
+     "area": 0,
+     "style": 0,
+     "cate_name": "",
+     "is_live_room_inline": 0,
+     "live_status": 0,
+     "live_time": "",
+     "online": 0,
+     "rank_index": 11,
+     "rank_offset": 11,
+     "roomid": 0,
+     "short_id": 0,
+     "spread_id": 0,
+     "tags": "",
+     "uface": "",
+     "uid": 0,
+     "uname": "",
+     "user_cover": "",
+     "parent_area_id": 0,
+     "parent_area_name": "",
+     "watched_show": null,
+     "cny_flag": 0,
+     "card_status": 0
+    },
+    {
+     "type": "video",
+     "id": 999796828,
+     "author": "JLRS-LeoFM",
+     "mid": 3493093607213343,
+     "typeid": "130",
+     "typename": "音乐综合",
+     "arcurl": "http://www.bilibili.com/video/av999796828",
+     "aid": 999796828,
+     "bvid": "BV1344y1w7wo",
+     "title": "在百万豪装录音棚大声听 王心凌《<em class=\"keyword\">彩虹</em>的微笑》【Hi-res】",
+     "description": "《彩虹的微笑》是一首由左克蕙作词、王心凌演唱的歌曲。该歌曲改编自1958年Buddy Holly和The Crickets的作品《It’s So Easy》,后来此曲也由Linda Ronstadt翻唱。\n\n录音设备:\n话筒:Neumann M149 tube Pair\n调音台:SSL Duality Delta Pro Station\n工作站:PT\n音箱:Barefoot MM12\n[侵删]",
+     "pic": "//i2.hdslb.com/bfs/archive/7d64cc10bc4c6440e3e28f23c2332b7d76f8c301.jpg",
+     "play": 1894501,
+     "video_review": 205,
+     "favorites": 16051,
+     "tag": "音乐分享官,高音质,Hi-res,音响,王心凌,音乐分享官第八期,彩虹的微笑,微笑pasta,Hi-Fi",
+     "review": 298,
+     "pubdate": 1692157500,
+     "senddate": 1770731094,
+     "duration": "2:52",
+     "badgepay": false,
+     "hit_columns": [
+      "title",
+      "description",
+      "tag"
+     ],
+     "view_type": "",
+     "is_pay": 0,
+     "is_union_video": 0,
+     "rec_tags": null,
+     "new_rec_tags": [],
+     "like": 9334,
+     "upic": "https://i0.hdslb.com/bfs/face/a7176b4e205f2fae521faf3b6d22eca17a44e7a3.jpg",
+     "corner": "",
+     "cover": "",
+     "desc": "",
+     "url": "",
+     "rec_reason": "",
+     "danmaku": 205,
+     "biz_data": null,
+     "is_charge_video": 0,
+     "vt": 0,
+     "enable_vt": 0,
+     "vt_display": "",
+     "subtitle": "",
+     "episode_count_text": "",
+     "release_status": 0,
+     "is_intervene": 0,
+     "area": 0,
+     "style": 0,
+     "cate_name": "",
+     "is_live_room_inline": 0,
+     "live_status": 0,
+     "live_time": "",
+     "online": 0,
+     "rank_index": 12,
+     "rank_offset": 12,
+     "roomid": 0,
+     "short_id": 0,
+     "spread_id": 0,
+     "tags": "",
+     "uface": "",
+     "uid": 0,
+     "uname": "",
+     "user_cover": "",
+     "parent_area_id": 0,
+     "parent_area_name": "",
+     "watched_show": null,
+     "cny_flag": 0,
+     "card_status": 0
+    },
+    {
+     "type": "video",
+     "id": 290485021,
+     "author": "天一清源的小窝",
+     "mid": 478128570,
+     "typeid": "130",
+     "typename": "音乐综合",
+     "arcurl": "http://www.bilibili.com/video/av290485021",
+     "aid": 290485021,
+     "bvid": "BV18f4y1a79v",
+     "title": "《绿野仙踪》(1969)主题曲《Over the Rainbow飞越<em class=\"keyword\">彩虹</em>》",
+     "description": "《绿野仙踪》(1969)主题曲《Over the Rainbow飞越彩虹》",
+     "pic": "//i0.hdslb.com/bfs/archive/d2da0159750c87dad6c4e07241ff971f6b4b7ce9.jpg",
+     "play": 93877,
+     "video_review": 15,
+     "favorites": 2202,
+     "tag": "影视金曲,怀旧金曲,飞越彩虹,欧美音乐,绿野仙踪",
+     "review": 78,
+     "pubdate": 1620090155,
+     "senddate": 1620090155,
+     "duration": "2:13",
+     "badgepay": false,
+     "hit_columns": [],
+     "view_type": "",
+     "is_pay": 0,
+     "is_union_video": 0,
+     "rec_tags": null,
+     "new_rec_tags": [],
+     "like": 1294,
+     "upic": "http://i0.hdslb.com/bfs/face/02e425a87c17a0d40072037c3799e748dc2939fa.jpg",
+     "corner": "",
+     "cover": "",
+     "desc": "",
+     "url": "",
+     "rec_reason": "",
+     "danmaku": 15,
+     "biz_data": null,
+     "is_charge_video": 0,
+     "vt": 0,
+     "enable_vt": 0,
+     "vt_display": "",
+     "subtitle": "",
+     "episode_count_text": "",
+     "release_status": 0,
+     "is_intervene": 0,
+     "area": 0,
+     "style": 0,
+     "cate_name": "",
+     "is_live_room_inline": 0,
+     "live_status": 0,
+     "live_time": "",
+     "online": 0,
+     "rank_index": 13,
+     "rank_offset": 13,
+     "roomid": 0,
+     "short_id": 0,
+     "spread_id": 0,
+     "tags": "",
+     "uface": "",
+     "uid": 0,
+     "uname": "",
+     "user_cover": "",
+     "parent_area_id": 0,
+     "parent_area_name": "",
+     "watched_show": null,
+     "cny_flag": 0,
+     "card_status": 0
+    },
+    {
+     "type": "video",
+     "id": 116277599278191,
+     "author": "唯一8090",
+     "mid": 329725181,
+     "typeid": "193",
+     "typename": "MV",
+     "arcurl": "http://www.bilibili.com/video/av116277599278191",
+     "aid": 116277599278191,
+     "bvid": "BV1sQQRBoEB4",
+     "title": "【真.4K重制】周杰伦《<em class=\"keyword\">彩虹</em>》MV HiRes无损音质 爷青回!",
+     "description": "DVD简体档修复,画质提升到4K,观看效果更佳~\n喜欢看我视频的小朋友们,记得“关注我”哦!\n--------------------------------------------------------\n这次还是由好兄弟@莼粹恋  帮忙跑的seedVR2模型~~\n最后搭配我多年修复经验,重制而成!~~~",
+     "pic": "//i0.hdslb.com/bfs/archive/55f3b09a741c6e00f89baffa686e12d3458b7513.jpg",
+     "play": 92729,
+     "video_review": 18,
+     "favorites": 1489,
+     "tag": "4K,开口跪,高音质,周杰伦,MV,周杰伦太阳之子,周杰伦新专辑二创大赛,新专辑周杰伦,电影不能说的秘密,太阳之子",
+     "review": 45,
+     "pubdate": 1774255960,
+     "senddate": 1780558807,
+     "duration": "4:32",
+     "badgepay": false,
+     "hit_columns": [
+      "title"
+     ],
+     "view_type": "",
+     "is_pay": 0,
+     "is_union_video": 1,
+     "rec_tags": null,
+     "new_rec_tags": [],
+     "like": 1545,
+     "upic": "https://i2.hdslb.com/bfs/face/f2bdb0afbd1423e950e24bd96f9e6b920e439abc.jpg",
+     "corner": "",
+     "cover": "",
+     "desc": "",
+     "url": "",
+     "rec_reason": "",
+     "danmaku": 18,
+     "biz_data": null,
+     "is_charge_video": 0,
+     "vt": 0,
+     "enable_vt": 0,
+     "vt_display": "",
+     "subtitle": "",
+     "episode_count_text": "",
+     "release_status": 0,
+     "is_intervene": 0,
+     "area": 0,
+     "style": 0,
+     "cate_name": "",
+     "is_live_room_inline": 0,
+     "live_status": 0,
+     "live_time": "",
+     "online": 0,
+     "rank_index": 14,
+     "rank_offset": 14,
+     "roomid": 0,
+     "short_id": 0,
+     "spread_id": 0,
+     "tags": "",
+     "uface": "",
+     "uid": 0,
+     "uname": "",
+     "user_cover": "",
+     "parent_area_id": 0,
+     "parent_area_name": "",
+     "watched_show": null,
+     "cny_flag": 0,
+     "card_status": 0
+    },
+    {
+     "type": "video",
+     "id": 78977350,
+     "author": "舞蹈区小锦鲤",
+     "mid": 32708657,
+     "typeid": "20",
+     "typename": "宅舞",
+     "arcurl": "http://www.bilibili.com/video/av78977350",
+     "aid": 78977350,
+     "bvid": "BV1KJ411C7SB",
+     "title": "【BDF2020主题曲MV】<em class=\"keyword\">彩虹</em>节拍【2020拜年祭单品】",
+     "description": "歌曲伴奏下载请戳活动页:https://www.bilibili.com/blackboard/activity-bdf2020.html\n今年的BDF也如约而至啦!感谢所有为了这支视频付出了努力的人,也感谢每一个愿意观看视频的你。\n别再继续等待也不要一直观望啦!Bilibili Dancing Festival2020将于3月正式启动,快来加入我们,一起开心地跳舞吧!",
+     "pic": "//i0.hdslb.com/bfs/archive/5b7e5741de56951919c330c6269956b85675b1bc.png",
+     "play": 5645258,
+     "video_review": 10002,
+     "favorites": 107368,
+     "tag": "2020拜年祭单品,彩虹节拍,BDF2020",
+     "review": 4748,
+     "pubdate": 1579877678,
+     "senddate": 1672469553,
+     "duration": "3:56",
+     "badgepay": false,
+     "hit_columns": [
+      "title",
+      "tag"
+     ],
+     "view_type": "",
+     "is_pay": 0,
+     "is_union_video": 0,
+     "rec_tags": null,
+     "new_rec_tags": [],
+     "like": 160018,
+     "upic": "https://i2.hdslb.com/bfs/face/46f7a6c5eff4bb44b3962ad9832e3d021eabc82b.jpg",
+     "corner": "",
+     "cover": "",
+     "desc": "",
+     "url": "",
+     "rec_reason": "",
+     "danmaku": 10002,
+     "biz_data": null,
+     "is_charge_video": 0,
+     "vt": 0,
+     "enable_vt": 0,
+     "vt_display": "",
+     "subtitle": "",
+     "episode_count_text": "",
+     "release_status": 0,
+     "is_intervene": 0,
+     "area": 0,
+     "style": 0,
+     "cate_name": "",
+     "is_live_room_inline": 0,
+     "live_status": 0,
+     "live_time": "",
+     "online": 0,
+     "rank_index": 15,
+     "rank_offset": 15,
+     "roomid": 0,
+     "short_id": 0,
+     "spread_id": 0,
+     "tags": "",
+     "uface": "",
+     "uid": 0,
+     "uname": "",
+     "user_cover": "",
+     "parent_area_id": 0,
+     "parent_area_name": "",
+     "watched_show": null,
+     "cny_flag": 0,
+     "card_status": 0
+    },
+    {
+     "type": "video",
+     "id": 116437721025655,
+     "author": "艾风视频-获取看主页",
+     "mid": 518824401,
+     "typeid": "193",
+     "typename": "MV",
+     "arcurl": "http://www.bilibili.com/video/av116437721025655",
+     "aid": 116437721025655,
+     "bvid": "BV1rKdCBYEQs",
+     "title": "《<em class=\"keyword\">彩虹</em>的微笑》王心凌原唱版,动感旋律,快乐满满!舞台背景视频",
+     "description": "《彩虹的微笑》王心凌原唱版,动感旋律,快乐满满!舞台背景视频。原创作品,请勿搬运!#王心凌 #背景视频 #文艺汇演 #快歌 #彩虹的微笑",
+     "pic": "//i0.hdslb.com/bfs/archive/ddb34da28546a37ab4e8b5a8a0bb1483a366ea43.jpg",
+     "play": 14789,
+     "video_review": 3,
+     "favorites": 89,
+     "tag": "舞台背景视频,彩虹的微笑,快歌,文艺汇演,舞曲,王心凌,经典",
+     "review": 3,
+     "pubdate": 1776698828,
+     "senddate": 1779701868,
+     "duration": "2:53",
+     "badgepay": false,
+     "hit_columns": [],
+     "view_type": "",
+     "is_pay": 0,
+     "is_union_video": 0,
+     "rec_tags": null,
+     "new_rec_tags": [],
+     "like": 44,
+     "upic": "https://i0.hdslb.com/bfs/face/ef4d955643422f26def76092ca818af805cbb749.jpg",
+     "corner": "",
+     "cover": "",
+     "desc": "",
+     "url": "",
+     "rec_reason": "",
+     "danmaku": 3,
+     "biz_data": null,
+     "is_charge_video": 0,
+     "vt": 0,
+     "enable_vt": 0,
+     "vt_display": "",
+     "subtitle": "",
+     "episode_count_text": "",
+     "release_status": 0,
+     "is_intervene": 0,
+     "area": 0,
+     "style": 0,
+     "cate_name": "",
+     "is_live_room_inline": 0,
+     "live_status": 0,
+     "live_time": "",
+     "online": 0,
+     "rank_index": 16,
+     "rank_offset": 16,
+     "roomid": 0,
+     "short_id": 0,
+     "spread_id": 0,
+     "tags": "",
+     "uface": "",
+     "uid": 0,
+     "uname": "",
+     "user_cover": "",
+     "parent_area_id": 0,
+     "parent_area_name": "",
+     "watched_show": null,
+     "cny_flag": 0,
+     "card_status": 0
+    },
+    {
+     "type": "video",
+     "id": 113542779048284,
+     "author": "梵思奇动漫",
+     "mid": 1784746052,
+     "typeid": "27",
+     "typename": "动画综合",
+     "arcurl": "http://www.bilibili.com/video/av113542779048284",
+     "aid": 113542779048284,
+     "bvid": "BV1ZUzcYqEHR",
+     "title": "不好了,<em class=\"keyword\">彩虹</em>被敌人控制住了!",
+     "description": "🌈  跟随《彩虹护卫队》的公主们,\n🚀一起踏上色彩斑斓的冒险之旅!\n🌟准备好,和我们一起守护这个充满爱的世界!\n#彩虹护卫队 #儿童动画 #女孩玩具 #儿童礼物推荐",
+     "pic": "//i2.hdslb.com/bfs/archive/bfeb612beaf080c1ba6e015cb14547408bd45704.jpg",
+     "play": 816029,
+     "video_review": 21,
+     "favorites": 940,
+     "tag": "动画种草激励计划7.0,国漫,国产动画,彩虹,动画短片,童年,动画种草激励计划",
+     "review": 23,
+     "pubdate": 1732525422,
+     "senddate": 1732525423,
+     "duration": "0:27",
+     "badgepay": false,
+     "hit_columns": [
+      "title",
+      "description",
+      "tag"
+     ],
+     "view_type": "",
+     "is_pay": 0,
+     "is_union_video": 0,
+     "rec_tags": null,
+     "new_rec_tags": [],
+     "like": 696,
+     "upic": "https://i2.hdslb.com/bfs/face/e9eb2307621e937d5c5af11eb48cd0e5b9a9d91a.jpg",
+     "corner": "",
+     "cover": "",
+     "desc": "",
+     "url": "",
+     "rec_reason": "",
+     "danmaku": 21,
+     "biz_data": null,
+     "is_charge_video": 0,
+     "vt": 0,
+     "enable_vt": 0,
+     "vt_display": "",
+     "subtitle": "",
+     "episode_count_text": "",
+     "release_status": 0,
+     "is_intervene": 0,
+     "area": 0,
+     "style": 0,
+     "cate_name": "",
+     "is_live_room_inline": 0,
+     "live_status": 0,
+     "live_time": "",
+     "online": 0,
+     "rank_index": 17,
+     "rank_offset": 17,
+     "roomid": 0,
+     "short_id": 0,
+     "spread_id": 0,
+     "tags": "",
+     "uface": "",
+     "uid": 0,
+     "uname": "",
+     "user_cover": "",
+     "parent_area_id": 0,
+     "parent_area_name": "",
+     "watched_show": null,
+     "cny_flag": 0,
+     "card_status": 0
+    },
+    {
+     "type": "video",
+     "id": 116628763183954,
+     "author": "音乐教师之家",
+     "mid": 1291433144,
+     "typeid": "31",
+     "typename": "翻唱",
+     "arcurl": "http://www.bilibili.com/video/av116628763183954",
+     "aid": 116628763183954,
+     "bvid": "BV15ZGJ6EE9x",
+     "title": "《<em class=\"keyword\">彩虹</em>》二声部合唱低声部范唱。#简谱分享#合唱 #<em class=\"keyword\">彩虹</em>合唱团<em class=\"keyword\">彩虹</em> #金承志",
+     "description": "-",
+     "pic": "//i2.hdslb.com/bfs/archive/e650557af79ef0d2c3221125a01d99f74fd74783.jpg",
+     "play": 304,
+     "video_review": 0,
+     "favorites": 7,
+     "tag": "合唱团,彩虹,合唱",
+     "review": 0,
+     "pubdate": 1779613846,
+     "senddate": 1779613848,
+     "duration": "2:18",
+     "badgepay": false,
+     "hit_columns": [],
+     "view_type": "",
+     "is_pay": 0,
+     "is_union_video": 0,
+     "rec_tags": null,
+     "new_rec_tags": [],
+     "like": 7,
+     "upic": "https://i2.hdslb.com/bfs/face/2b40b17b13ad82f85f8b67ac91307b3fe0d84305.jpg",
+     "corner": "",
+     "cover": "",
+     "desc": "",
+     "url": "",
+     "rec_reason": "",
+     "danmaku": 0,
+     "biz_data": null,
+     "is_charge_video": 0,
+     "vt": 0,
+     "enable_vt": 0,
+     "vt_display": "",
+     "subtitle": "",
+     "episode_count_text": "",
+     "release_status": 0,
+     "is_intervene": 0,
+     "area": 0,
+     "style": 0,
+     "cate_name": "",
+     "is_live_room_inline": 0,
+     "live_status": 0,
+     "live_time": "",
+     "online": 0,
+     "rank_index": 18,
+     "rank_offset": 18,
+     "roomid": 0,
+     "short_id": 0,
+     "spread_id": 0,
+     "tags": "",
+     "uface": "",
+     "uid": 0,
+     "uname": "",
+     "user_cover": "",
+     "parent_area_id": 0,
+     "parent_area_name": "",
+     "watched_show": null,
+     "cny_flag": 0,
+     "card_status": 0
+    },
+    {
+     "type": "video",
+     "id": 873029667,
+     "author": "麻园诗人乐队",
+     "mid": 340450341,
+     "typeid": "29",
+     "typename": "音乐现场",
+     "arcurl": "http://www.bilibili.com/video/av873029667",
+     "aid": 873029667,
+     "bvid": "BV1rN4y1X7nr",
+     "title": "笑中含泪!麻园诗人改编王心凌《<em class=\"keyword\">彩虹</em>的微笑》",
+     "description": "王心凌老师这首《彩虹的微笑》我们做了颠覆性的改编,内容上也做了延伸。相信热爱,保持乐观,为七彩世界而动容,过往的不安苦难,生活波折,被风雨洗净后犹如彩虹高挂天空。\n在这次舞台表演中我们塑造与年少自己对话的意象,时光不停向前,跨越尘世,一次次为心底留下色彩,是否还会坚守那份纯洁,珍爱每次遇见,我们一起在歌里寻找答案吧。",
+     "pic": "//i2.hdslb.com/bfs/archive/962fc376c1e96013db5270e45d2bc3f940161b88.jpg",
+     "play": 1105075,
+     "video_review": 1882,
+     "favorites": 16089,
+     "tag": "LIVE,麻园诗人,乐队的夏天,王心凌,一起来看乐队的夏天3,彩虹的微笑,音乐追综记2.0",
+     "review": 1672,
+     "pubdate": 1693625661,
+     "senddate": 1693641136,
+     "duration": "5:2",
+     "badgepay": false,
+     "hit_columns": [
+      "title",
+      "description",
+      "tag"
+     ],
+     "view_type": "",
+     "is_pay": 0,
+     "is_union_video": 0,
+     "rec_tags": null,
+     "new_rec_tags": [],
+     "like": 31207,
+     "upic": "https://i0.hdslb.com/bfs/face/861371d681fb12443035fe01737812f129d24c1d.jpg",
+     "corner": "",
+     "cover": "",
+     "desc": "",
+     "url": "",
+     "rec_reason": "",
+     "danmaku": 1882,
+     "biz_data": null,
+     "is_charge_video": 0,
+     "vt": 0,
+     "enable_vt": 0,
+     "vt_display": "",
+     "subtitle": "",
+     "episode_count_text": "",
+     "release_status": 0,
+     "is_intervene": 0,
+     "area": 0,
+     "style": 0,
+     "cate_name": "",
+     "is_live_room_inline": 0,
+     "live_status": 0,
+     "live_time": "",
+     "online": 0,
+     "rank_index": 19,
+     "rank_offset": 19,
+     "roomid": 0,
+     "short_id": 0,
+     "spread_id": 0,
+     "tags": "",
+     "uface": "",
+     "uid": 0,
+     "uname": "",
+     "user_cover": "",
+     "parent_area_id": 0,
+     "parent_area_name": "",
+     "watched_show": null,
+     "cny_flag": 0,
+     "card_status": 0
+    },
+    {
+     "type": "video",
+     "id": 363093125,
+     "author": "JLRS-LeoFM",
+     "mid": 3493093607213343,
+     "typeid": "130",
+     "typename": "音乐综合",
+     "arcurl": "http://www.bilibili.com/video/av363093125",
+     "aid": 363093125,
+     "bvid": "BV1h94y1s7vE",
+     "title": "在百万豪装录音棚大声听 李玖哲《夏天》【Hi-res】",
+     "description": "《夏天》是一首流行歌曲,由古小力填词,周杰伦作曲,李玖哲演唱。这首歌收录在李玖哲2010年发行的专辑《好玖》。\n\n录音设备:\n话筒:Neumann M149 tube Pair\n调音台:SSL Duality Delta Pro Station\n工作站:PT\n音箱:Barefoot MM12\n[侵删]",
+     "pic": "//i2.hdslb.com/bfs/archive/ccdf8e8f18f56bdae309a4858124915436d29f94.jpg",
+     "play": 2166006,
+     "video_review": 622,
+     "favorites": 29141,
+     "tag": "音响,夏天,音乐分享官第八期,高音质,李玖哲,音乐分享官,Hi-res,Hi-Fi",
+     "review": 403,
+     "pubdate": 1693798627,
+     "senddate": 1770730799,
+     "duration": "3:48",
+     "badgepay": false,
+     "hit_columns": [],
+     "view_type": "",
+     "is_pay": 0,
+     "is_union_video": 0,
+     "rec_tags": null,
+     "new_rec_tags": [],
+     "like": 15670,
+     "upic": "https://i0.hdslb.com/bfs/face/a7176b4e205f2fae521faf3b6d22eca17a44e7a3.jpg",
+     "corner": "",
+     "cover": "",
+     "desc": "",
+     "url": "",
+     "rec_reason": "",
+     "danmaku": 622,
+     "biz_data": null,
+     "is_charge_video": 0,
+     "vt": 0,
+     "enable_vt": 0,
+     "vt_display": "",
+     "subtitle": "",
+     "episode_count_text": "",
+     "release_status": 0,
+     "is_intervene": 0,
+     "area": 0,
+     "style": 0,
+     "cate_name": "",
+     "is_live_room_inline": 0,
+     "live_status": 0,
+     "live_time": "",
+     "online": 0,
+     "rank_index": 20,
+     "rank_offset": 20,
+     "roomid": 0,
+     "short_id": 0,
+     "spread_id": 0,
+     "tags": "",
+     "uface": "",
+     "uid": 0,
+     "uname": "",
+     "user_cover": "",
+     "parent_area_id": 0,
+     "parent_area_name": "",
+     "watched_show": null,
+     "cny_flag": 0,
+     "card_status": 0
+    },
+    {
+     "type": "video",
+     "id": 115813592012833,
+     "author": "VV音乐局",
+     "mid": 9666167,
+     "typeid": "130",
+     "typename": "音乐综合",
+     "arcurl": "http://www.bilibili.com/video/av115813592012833",
+     "aid": 115813592012833,
+     "bvid": "BV17viTBgED1",
+     "title": "【𝐇𝐢-𝐑𝐞𝐬无损音质】|《颜色》- Gareth.T -‘我会学会懂事  令你安心’",
+     "description": "【Hi-Res无损音质】《颜色》- Gareth.T\n——————————————\n你们的三连是我更新的最大动力!\n——————————————\n仅用于音乐分享,请支持正版!\n——————————————\n有其他想听的欢迎评论区留言~!",
+     "pic": "//i2.hdslb.com/bfs/archive/23419fb73caae99cf4194c2871961b5b2a9d1215.jpg",
+     "play": 271528,
+     "video_review": 528,
+     "favorites": 3856,
+     "tag": "hi-res无损,音乐分享官,听歌,Gareth.T,音箱,颜色,华语,无损音质",
+     "review": 64,
+     "pubdate": 1767403800,
+     "senddate": 1768575183,
+     "duration": "3:32",
+     "badgepay": false,
+     "hit_columns": [],
+     "view_type": "",
+     "is_pay": 0,
+     "is_union_video": 0,
+     "rec_tags": null,
+     "new_rec_tags": [],
+     "like": 1644,
+     "upic": "https://i2.hdslb.com/bfs/face/ae0d28f7a465137bb6a95909ca859829863ada90.jpg",
+     "corner": "",
+     "cover": "",
+     "desc": "",
+     "url": "",
+     "rec_reason": "",
+     "danmaku": 528,
+     "biz_data": null,
+     "is_charge_video": 0,
+     "vt": 0,
+     "enable_vt": 0,
+     "vt_display": "",
+     "subtitle": "",
+     "episode_count_text": "",
+     "release_status": 0,
+     "is_intervene": 0,
+     "area": 0,
+     "style": 0,
+     "cate_name": "",
+     "is_live_room_inline": 0,
+     "live_status": 0,
+     "live_time": "",
+     "online": 0,
+     "rank_index": 21,
+     "rank_offset": 21,
+     "roomid": 0,
+     "short_id": 0,
+     "spread_id": 0,
+     "tags": "",
+     "uface": "",
+     "uid": 0,
+     "uname": "",
+     "user_cover": "",
+     "parent_area_id": 0,
+     "parent_area_name": "",
+     "watched_show": null,
+     "cny_flag": 0,
+     "card_status": 0
+    },
+    {
+     "type": "video",
+     "id": 530900486,
+     "author": "战双帕弥什",
+     "mid": 382651856,
+     "typeid": "28",
+     "typename": "原创音乐",
+     "arcurl": "http://www.bilibili.com/video/av530900486",
+     "aid": 530900486,
+     "bvid": "BV1iu41157u6",
+     "title": "【战双帕弥什×<em class=\"keyword\">彩虹</em>合唱】法奥斯学院毕业曲《长路归航》",
+     "description": "与昨日道别,回忆与教诲收藏在彼此心间;\n向明天出发,坎坷与艰险有先行者的脚印;\n随歌声唱起,握紧黑夜中那束光接力向前。\n\n希望指挥官能在歌曲中找到过去那些珍贵的记忆,坚定迈出通向未来的步伐。\n\n——————————\n演唱:@上海彩虹室内合唱团  \n作曲:语轩\n作词:小伙\n编曲:徐肖@Alnova\n录音:陆晓幸@三友录音棚\n混音:阿烈@Soundhub Studios\n乐队:辉音国际爱乐乐团\n导摄团队:褒茂策划",
+     "pic": "//i2.hdslb.com/bfs/archive/7cb182a02169ffd32f17e5074670a66c47c5d498.jpg",
+     "play": 1938703,
+     "video_review": 11613,
+     "favorites": 46854,
+     "tag": "手游,毕业季,合唱,战双,彩虹合唱团,上海彩虹室内合唱团,战双帕弥什,游戏,MV,原创音乐",
+     "review": 6992,
+     "pubdate": 1689393600,
+     "senddate": 1689399020,
+     "duration": "3:28",
+     "badgepay": false,
+     "hit_columns": [
+      "title",
+      "description",
+      "tag"
+     ],
+     "view_type": "",
+     "is_pay": 0,
+     "is_union_video": 1,
+     "rec_tags": null,
+     "new_rec_tags": [],
+     "like": 111660,
+     "upic": "https://i2.hdslb.com/bfs/face/29d40886bc649fd2b81793c17077728820d411b6.jpg",
+     "corner": "",
+     "cover": "",
+     "desc": "",
+     "url": "",
+     "rec_reason": "",
+     "danmaku": 11613,
+     "biz_data": null,
+     "is_charge_video": 0,
+     "vt": 0,
+     "enable_vt": 0,
+     "vt_display": "",
+     "subtitle": "",
+     "episode_count_text": "",
+     "release_status": 0,
+     "is_intervene": 0,
+     "area": 0,
+     "style": 0,
+     "cate_name": "",
+     "is_live_room_inline": 0,
+     "live_status": 0,
+     "live_time": "",
+     "online": 0,
+     "rank_index": 22,
+     "rank_offset": 22,
+     "roomid": 0,
+     "short_id": 0,
+     "spread_id": 0,
+     "tags": "",
+     "uface": "",
+     "uid": 0,
+     "uname": "",
+     "user_cover": "",
+     "parent_area_id": 0,
+     "parent_area_name": "",
+     "watched_show": null,
+     "cny_flag": 0,
+     "card_status": 0
+    },
+    {
+     "type": "video",
+     "id": 229303699,
+     "author": "JLRS-LeoFM",
+     "mid": 3493093607213343,
+     "typeid": "130",
+     "typename": "音乐综合",
+     "arcurl": "http://www.bilibili.com/video/av229303699",
+     "aid": 229303699,
+     "bvid": "BV118411f7cz",
+     "title": "在百万豪装录音棚大声听 张韶涵&amp;王赫野《篇章》【Hi-res】",
+     "description": "《篇章》是张韶涵、王赫野演唱的歌曲,由李浩瑞、赵大白、刘涛、林晨阳作词,李浩瑞、刘涛、林晨阳作曲,黎子琨编曲,2022年5月1日发行。\n\n录音设备:\n话筒:Neumann M149 tube Pair\n调音台:SSL Duality Delta Pro Station\n工作站:PT\n音箱:Barefoot MM12\n[侵删]",
+     "pic": "//i1.hdslb.com/bfs/archive/d061b162ef13340b75a3689cee581411104a3b11.jpg",
+     "play": 2382908,
+     "video_review": 2435,
+     "favorites": 37205,
+     "tag": "Hi-res,录音棚,音乐分享官7.0,王赫野,高音质,音响,张韶涵,Hi-Fi,篇章,音乐分享官",
+     "review": 904,
+     "pubdate": 1685676994,
+     "senddate": 1770731096,
+     "duration": "4:9",
+     "badgepay": false,
+     "hit_columns": [],
+     "view_type": "",
+     "is_pay": 0,
+     "is_union_video": 0,
+     "rec_tags": null,
+     "new_rec_tags": [],
+     "like": 18582,
+     "upic": "https://i0.hdslb.com/bfs/face/a7176b4e205f2fae521faf3b6d22eca17a44e7a3.jpg",
+     "corner": "",
+     "cover": "",
+     "desc": "",
+     "url": "",
+     "rec_reason": "",
+     "danmaku": 2435,
+     "biz_data": null,
+     "is_charge_video": 0,
+     "vt": 0,
+     "enable_vt": 0,
+     "vt_display": "",
+     "subtitle": "",
+     "episode_count_text": "",
+     "release_status": 0,
+     "is_intervene": 0,
+     "area": 0,
+     "style": 0,
+     "cate_name": "",
+     "is_live_room_inline": 0,
+     "live_status": 0,
+     "live_time": "",
+     "online": 0,
+     "rank_index": 23,
+     "rank_offset": 23,
+     "roomid": 0,
+     "short_id": 0,
+     "spread_id": 0,
+     "tags": "",
+     "uface": "",
+     "uid": 0,
+     "uname": "",
+     "user_cover": "",
+     "parent_area_id": 0,
+     "parent_area_name": "",
+     "watched_show": null,
+     "cny_flag": 0,
+     "card_status": 0
+    },
+    {
+     "type": "video",
+     "id": 827124184,
+     "author": "JLRS-LeoFM",
+     "mid": 3493093607213343,
+     "typeid": "130",
+     "typename": "音乐综合",
+     "arcurl": "http://www.bilibili.com/video/av827124184",
+     "aid": 827124184,
+     "bvid": "BV1Bu4y1d7KJ",
+     "title": "在百万豪装录音棚大声听 S.H.E《你曾是少年》【Hi-res】",
+     "description": "《你曾是少年》是肖洋作词,杨子朴谱曲,S.H.E演唱的歌曲,于2015年5月20日发行,该曲也是电影《少年班》的主题曲。\n\n录音设备:\n话筒:Neumann M149 tube Pair\n调音台:SSL Duality Delta Pro Station\n工作站:PT\n音箱:Barefoot MM12\n[侵删]",
+     "pic": "//i0.hdslb.com/bfs/archive/8e1cdc7d2c6e4ce598abc5c62b02894d0a52ea6f.jpg",
+     "play": 3713752,
+     "video_review": 1418,
+     "favorites": 53030,
+     "tag": "你曾是少年,录音棚,S.H.E,Hi-Fi,Hi-res,高音质,儿童节,音响",
+     "review": 2274,
+     "pubdate": 1686279600,
+     "senddate": 1770731096,
+     "duration": "4:25",
+     "badgepay": false,
+     "hit_columns": [],
+     "view_type": "",
+     "is_pay": 0,
+     "is_union_video": 0,
+     "rec_tags": null,
+     "new_rec_tags": [],
+     "like": 32692,
+     "upic": "https://i0.hdslb.com/bfs/face/a7176b4e205f2fae521faf3b6d22eca17a44e7a3.jpg",
+     "corner": "",
+     "cover": "",
+     "desc": "",
+     "url": "",
+     "rec_reason": "",
+     "danmaku": 1418,
+     "biz_data": null,
+     "is_charge_video": 0,
+     "vt": 0,
+     "enable_vt": 0,
+     "vt_display": "",
+     "subtitle": "",
+     "episode_count_text": "",
+     "release_status": 0,
+     "is_intervene": 0,
+     "area": 0,
+     "style": 0,
+     "cate_name": "",
+     "is_live_room_inline": 0,
+     "live_status": 0,
+     "live_time": "",
+     "online": 0,
+     "rank_index": 24,
+     "rank_offset": 24,
+     "roomid": 0,
+     "short_id": 0,
+     "spread_id": 0,
+     "tags": "",
+     "uface": "",
+     "uid": 0,
+     "uname": "",
+     "user_cover": "",
+     "parent_area_id": 0,
+     "parent_area_name": "",
+     "watched_show": null,
+     "cny_flag": 0,
+     "card_status": 0
+    },
+    {
+     "type": "video",
+     "id": 665696774,
+     "author": "JLRS-LeoFM",
+     "mid": 3493093607213343,
+     "typeid": "130",
+     "typename": "音乐综合",
+     "arcurl": "http://www.bilibili.com/video/av665696774",
+     "aid": 665696774,
+     "bvid": "BV1Ba4y1q7UJ",
+     "title": "在百万豪装录音棚大声听 张韶涵《有形的翅膀》【Hi-res】",
+     "description": "《有形的翅膀》是中国台湾女歌手张韶涵演唱的一首流行歌曲。由吴青峰作词及谱曲。2012年10月12日由美妙音乐发行,收录于张韶涵第七张国语专辑《有形的翅膀》中。\n\n录音设备:\n话筒:Neumann M149 tube Pair\n调音台:SSL Duality Delta Pro Station\n工作站:PT\n音箱:Barefoot MM12\n[侵删]",
+     "pic": "//i2.hdslb.com/bfs/archive/563445bfaeb132a6c31f90fb47dfc3556be24332.jpg",
+     "play": 3238098,
+     "video_review": 1894,
+     "favorites": 54243,
+     "tag": "有形的翅膀,音乐分享官,张韶涵,音响,高音质,Hi-res,录音棚,Hi-Fi",
+     "review": 1015,
+     "pubdate": 1704191820,
+     "senddate": 1704191820,
+     "duration": "3:38",
+     "badgepay": false,
+     "hit_columns": [],
+     "view_type": "",
+     "is_pay": 0,
+     "is_union_video": 0,
+     "rec_tags": null,
+     "new_rec_tags": [],
+     "like": 30465,
+     "upic": "https://i0.hdslb.com/bfs/face/a7176b4e205f2fae521faf3b6d22eca17a44e7a3.jpg",
+     "corner": "",
+     "cover": "",
+     "desc": "",
+     "url": "",
+     "rec_reason": "",
+     "danmaku": 1894,
+     "biz_data": null,
+     "is_charge_video": 0,
+     "vt": 0,
+     "enable_vt": 0,
+     "vt_display": "",
+     "subtitle": "",
+     "episode_count_text": "",
+     "release_status": 0,
+     "is_intervene": 0,
+     "area": 0,
+     "style": 0,
+     "cate_name": "",
+     "is_live_room_inline": 0,
+     "live_status": 0,
+     "live_time": "",
+     "online": 0,
+     "rank_index": 25,
+     "rank_offset": 25,
+     "roomid": 0,
+     "short_id": 0,
+     "spread_id": 0,
+     "tags": "",
+     "uface": "",
+     "uid": 0,
+     "uname": "",
+     "user_cover": "",
+     "parent_area_id": 0,
+     "parent_area_name": "",
+     "watched_show": null,
+     "cny_flag": 0,
+     "card_status": 0
+    },
+    {
+     "type": "video",
+     "id": 610711409,
+     "author": "Music小铁匠",
+     "mid": 1861661662,
+     "typeid": "267",
+     "typename": "电台",
+     "arcurl": "http://www.bilibili.com/video/av610711409",
+     "aid": 610711409,
+     "bvid": "BV1384y1N71m",
+     "title": "【Hi-Res无损】TFBOYS/CUG嘻游记《剩下的盛夏》“蝉鸣是窗外渐渐倒数的钟声 考卷的分数是往上爬的树藤”| 音乐可视化 | 动态歌词",
+     "description": "4k画质+无损音质+视频制作+音乐可视化\n\n音乐版权属于歌手以及唱片公司,仅做安利分享,有条件请支持正版音源。\n如有版权问题请及时联系。\n\n如果喜欢,麻烦点个免费的赞,点赞点赞点赞点赞点赞点赞点赞点赞点赞点赞点赞点赞点赞点赞点赞点赞点赞点赞点赞点赞点赞点赞点赞点赞点赞点赞点赞点赞点赞点赞点赞点赞点赞点赞点赞点赞点赞点赞点赞点赞点赞点赞点赞点赞点赞点赞点赞点赞点赞点赞点赞点赞点赞点赞点赞点赞点赞不点赞。",
+     "pic": "//i1.hdslb.com/bfs/archive/2ae9f62f71190f85114653c4cddd2278a946191b.jpg",
+     "play": 858079,
+     "video_review": 553,
+     "favorites": 17164,
+     "tag": "音乐研究所,音乐可视化,音乐,热门,TFBOYS,无损,听歌,剩下的盛夏,音乐玩家招募令,精选歌单,高音质",
+     "review": 351,
+     "pubdate": 1679648400,
+     "senddate": 1715679045,
+     "duration": "4:11",
+     "badgepay": false,
+     "hit_columns": [],
+     "view_type": "",
+     "is_pay": 0,
+     "is_union_video": 0,
+     "rec_tags": null,
+     "new_rec_tags": [],
+     "like": 6860,
+     "upic": "https://i1.hdslb.com/bfs/face/2c37549e3bae6e2007cdd52fab6852bd3c858ba9.jpg",
+     "corner": "",
+     "cover": "",
+     "desc": "",
+     "url": "",
+     "rec_reason": "",
+     "danmaku": 553,
+     "biz_data": null,
+     "is_charge_video": 0,
+     "vt": 0,
+     "enable_vt": 0,
+     "vt_display": "",
+     "subtitle": "",
+     "episode_count_text": "",
+     "release_status": 0,
+     "is_intervene": 0,
+     "area": 0,
+     "style": 0,
+     "cate_name": "",
+     "is_live_room_inline": 0,
+     "live_status": 0,
+     "live_time": "",
+     "online": 0,
+     "rank_index": 26,
+     "rank_offset": 26,
+     "roomid": 0,
+     "short_id": 0,
+     "spread_id": 0,
+     "tags": "",
+     "uface": "",
+     "uid": 0,
+     "uname": "",
+     "user_cover": "",
+     "parent_area_id": 0,
+     "parent_area_name": "",
+     "watched_show": null,
+     "cny_flag": 0,
+     "card_status": 0
+    },
+    {
+     "type": "video",
+     "id": 116698204084207,
+     "author": "流行音悦风云榜",
+     "mid": 250040173,
+     "typeid": "29",
+     "typename": "音乐现场",
+     "arcurl": "http://www.bilibili.com/video/av116698204084207",
+     "aid": 116698204084207,
+     "bvid": "BV1Wt7y6CE1Y",
+     "title": "周兴哲&amp;炎明熟《颜色》歌手2026.4K.HDR.50P.全网超高清电视源码",
+     "description": "-",
+     "pic": "//i2.hdslb.com/bfs/archive/bcecdd009eef5d23f3334b61463139bac3e6461a.jpg",
+     "play": 21632,
+     "video_review": 3,
+     "favorites": 225,
+     "tag": "全能音乐挑战赛,流行音乐,华语现场",
+     "review": 35,
+     "pubdate": 1780674208,
+     "senddate": 1781008224,
+     "duration": "5:21",
+     "badgepay": false,
+     "hit_columns": [],
+     "view_type": "",
+     "is_pay": 0,
+     "is_union_video": 0,
+     "rec_tags": null,
+     "new_rec_tags": [],
+     "like": 217,
+     "upic": "https://i1.hdslb.com/bfs/face/01904f1edff31092aaf339b32d5c49016defed23.jpg",
+     "corner": "",
+     "cover": "",
+     "desc": "",
+     "url": "",
+     "rec_reason": "",
+     "danmaku": 3,
+     "biz_data": null,
+     "is_charge_video": 0,
+     "vt": 0,
+     "enable_vt": 0,
+     "vt_display": "",
+     "subtitle": "",
+     "episode_count_text": "",
+     "release_status": 0,
+     "is_intervene": 0,
+     "area": 0,
+     "style": 0,
+     "cate_name": "",
+     "is_live_room_inline": 0,
+     "live_status": 0,
+     "live_time": "",
+     "online": 0,
+     "rank_index": 27,
+     "rank_offset": 27,
+     "roomid": 0,
+     "short_id": 0,
+     "spread_id": 0,
+     "tags": "",
+     "uface": "",
+     "uid": 0,
+     "uname": "",
+     "user_cover": "",
+     "parent_area_id": 0,
+     "parent_area_name": "",
+     "watched_show": null,
+     "cny_flag": 0,
+     "card_status": 0
+    },
+    {
+     "type": "video",
+     "id": 363461377,
+     "author": "JLRS-LeoFM",
+     "mid": 3493093607213343,
+     "typeid": "130",
+     "typename": "音乐综合",
+     "arcurl": "http://www.bilibili.com/video/av363461377",
+     "aid": 363461377,
+     "bvid": "BV1C94y1W7X1",
+     "title": "在百万豪装录音棚大声听 卢广仲《刻在我心底的名字》【Hi-res】",
+     "description": "《刻在我心底的名字》是电影《刻在你心底的名字》的主题曲,由卢广仲演唱,许媛婷、佳旺作曲,陈文华作词,黄雨勋担任制作人。\n\n录音设备:\n话筒:Neumann M149 tube Pair\n调音台:SSL Duality Delta Pro Station\n工作站:PT\n音箱:Barefoot MM12\n[侵删]",
+     "pic": "//i2.hdslb.com/bfs/archive/1b84d54b966232019b9d4b3d069fe11bb733c0d1.jpg",
+     "play": 3143971,
+     "video_review": 1756,
+     "favorites": 42890,
+     "tag": "高音质,Hi-Fi,录音棚,音响,音乐分享官第八期,卢广仲,Hi-res,刻在我心底的名字,音乐分享官",
+     "review": 1353,
+     "pubdate": 1694947080,
+     "senddate": 1770730799,
+     "duration": "5:20",
+     "badgepay": false,
+     "hit_columns": [],
+     "view_type": "",
+     "is_pay": 0,
+     "is_union_video": 0,
+     "rec_tags": null,
+     "new_rec_tags": [],
+     "like": 25474,
+     "upic": "https://i0.hdslb.com/bfs/face/a7176b4e205f2fae521faf3b6d22eca17a44e7a3.jpg",
+     "corner": "",
+     "cover": "",
+     "desc": "",
+     "url": "",
+     "rec_reason": "",
+     "danmaku": 1756,
+     "biz_data": null,
+     "is_charge_video": 0,
+     "vt": 0,
+     "enable_vt": 0,
+     "vt_display": "",
+     "subtitle": "",
+     "episode_count_text": "",
+     "release_status": 0,
+     "is_intervene": 0,
+     "area": 0,
+     "style": 0,
+     "cate_name": "",
+     "is_live_room_inline": 0,
+     "live_status": 0,
+     "live_time": "",
+     "online": 0,
+     "rank_index": 28,
+     "rank_offset": 28,
+     "roomid": 0,
+     "short_id": 0,
+     "spread_id": 0,
+     "tags": "",
+     "uface": "",
+     "uid": 0,
+     "uname": "",
+     "user_cover": "",
+     "parent_area_id": 0,
+     "parent_area_name": "",
+     "watched_show": null,
+     "cny_flag": 0,
+     "card_status": 0
+    },
+    {
+     "type": "video",
+     "id": 404096856,
+     "author": "JLRS-LeoFM",
+     "mid": 3493093607213343,
+     "typeid": "130",
+     "typename": "音乐综合",
+     "arcurl": "http://www.bilibili.com/video/av404096856",
+     "aid": 404096856,
+     "bvid": "BV15V411573V",
+     "title": "在百万豪装录音棚大声听 五月天《温柔》【Hi-res】",
+     "description": "《温柔》是中国台湾摇滚乐团五月天演唱的一首歌曲,由陈信宏作词、作曲,五月天编曲,收录于五月天2000年7月7日由滚石国际音乐有限公司发行的专辑《爱情万岁》中。\n\n录音设备:\n话筒:Neumann M149 tube Pair\n调音台:SSL Duality Delta Pro Station\n工作站:PT\n音箱:Barefoot MM12\n[侵删]",
+     "pic": "//i2.hdslb.com/bfs/archive/8812bed772a930571895c0e517fad68d86905798.jpg",
+     "play": 1477021,
+     "video_review": 272,
+     "favorites": 17307,
+     "tag": "Hi-res,温柔,Hi-Fi,五月天,高音质,音响,音乐玩家招募令2.0,音乐分享官",
+     "review": 367,
+     "pubdate": 1690634626,
+     "senddate": 1690634626,
+     "duration": "4:32",
+     "badgepay": false,
+     "hit_columns": [],
+     "view_type": "",
+     "is_pay": 0,
+     "is_union_video": 0,
+     "rec_tags": null,
+     "new_rec_tags": [],
+     "like": 9438,
+     "upic": "https://i0.hdslb.com/bfs/face/a7176b4e205f2fae521faf3b6d22eca17a44e7a3.jpg",
+     "corner": "",
+     "cover": "",
+     "desc": "",
+     "url": "",
+     "rec_reason": "",
+     "danmaku": 272,
+     "biz_data": null,
+     "is_charge_video": 0,
+     "vt": 0,
+     "enable_vt": 0,
+     "vt_display": "",
+     "subtitle": "",
+     "episode_count_text": "",
+     "release_status": 0,
+     "is_intervene": 0,
+     "area": 0,
+     "style": 0,
+     "cate_name": "",
+     "is_live_room_inline": 0,
+     "live_status": 0,
+     "live_time": "",
+     "online": 0,
+     "rank_index": 29,
+     "rank_offset": 29,
+     "roomid": 0,
+     "short_id": 0,
+     "spread_id": 0,
+     "tags": "",
+     "uface": "",
+     "uid": 0,
+     "uname": "",
+     "user_cover": "",
+     "parent_area_id": 0,
+     "parent_area_name": "",
+     "watched_show": null,
+     "cny_flag": 0,
+     "card_status": 0
+    },
+    {
+     "type": "video",
+     "id": 115150958890390,
+     "author": "JLRS-LeoFM",
+     "mid": 3493093607213343,
+     "typeid": "130",
+     "typename": "音乐综合",
+     "arcurl": "http://www.bilibili.com/video/av115150958890390",
+     "aid": 115150958890390,
+     "bvid": "BV1DiabzAEs7",
+     "title": "颜人中《夏夜最后的烟火》百万豪装录音棚大声听",
+     "description": "《夏夜最后的烟火》是颜人中演唱的歌曲,由陆菱纱作词,史晓天作曲,2020年9月29日以单曲形式发行。\n\n录音设备: \n话筒:Neumann M149 tube Pair \n调音台:SSL Duality Delta Pro Station \n工作站:PT",
+     "pic": "//i2.hdslb.com/bfs/archive/644beb2b029da595f9be9db4780885bb9cdcfccf.jpg",
+     "play": 1092442,
+     "video_review": 1684,
+     "favorites": 18434,
+     "tag": "录音棚,Hi-res,电台,音响,颜人中,Hi-Fi,电台新星征集令,歌单,夏夜最后的烟火",
+     "review": 270,
+     "pubdate": 1757244120,
+     "senddate": 1770729749,
+     "duration": "4:41",
+     "badgepay": false,
+     "hit_columns": [],
+     "view_type": "",
+     "is_pay": 0,
+     "is_union_video": 0,
+     "rec_tags": null,
+     "new_rec_tags": [],
+     "like": 8852,
+     "upic": "https://i0.hdslb.com/bfs/face/a7176b4e205f2fae521faf3b6d22eca17a44e7a3.jpg",
+     "corner": "",
+     "cover": "",
+     "desc": "",
+     "url": "",
+     "rec_reason": "",
+     "danmaku": 1684,
+     "biz_data": null,
+     "is_charge_video": 0,
+     "vt": 0,
+     "enable_vt": 0,
+     "vt_display": "",
+     "subtitle": "",
+     "episode_count_text": "",
+     "release_status": 0,
+     "is_intervene": 0,
+     "area": 0,
+     "style": 0,
+     "cate_name": "",
+     "is_live_room_inline": 0,
+     "live_status": 0,
+     "live_time": "",
+     "online": 0,
+     "rank_index": 30,
+     "rank_offset": 30,
+     "roomid": 0,
+     "short_id": 0,
+     "spread_id": 0,
+     "tags": "",
+     "uface": "",
+     "uid": 0,
+     "uname": "",
+     "user_cover": "",
+     "parent_area_id": 0,
+     "parent_area_name": "",
+     "watched_show": null,
+     "cny_flag": 0,
+     "card_status": 0
+    },
+    {
+     "type": "video",
+     "id": 578110738,
+     "author": "JLRS-LeoFM",
+     "mid": 3493093607213343,
+     "typeid": "130",
+     "typename": "音乐综合",
+     "arcurl": "http://www.bilibili.com/video/av578110738",
+     "aid": 578110738,
+     "bvid": "BV1Dz4y1A7jV",
+     "title": "在百万豪装录音棚大声听 艾辰《错位时空》【Hi-res】",
+     "description": "《错位时空》是艾辰演唱的歌曲,由周仁填词,张博文谱曲,收录在专辑《错位时空》中。\n\n录音设备:\n话筒:Neumann M149 tube Pair\n调音台:SSL Duality Delta Pro Station\n工作站:PT\n音箱:Barefoot MM12\n[侵删]",
+     "pic": "//i0.hdslb.com/bfs/archive/3f3827ca12c69bdbe5a6c3caecbc10842d17cbeb.jpg",
+     "play": 3002429,
+     "video_review": 486,
+     "favorites": 52111,
+     "tag": "高音质,录音棚,音乐分享官,Hi-Fi,错位时空,Hi-res,艾辰,音响,音乐玩家招募令第三期",
+     "review": 1077,
+     "pubdate": 1699242000,
+     "senddate": 1770730797,
+     "duration": "3:27",
+     "badgepay": false,
+     "hit_columns": [],
+     "view_type": "",
+     "is_pay": 0,
+     "is_union_video": 0,
+     "rec_tags": null,
+     "new_rec_tags": [],
+     "like": 24043,
+     "upic": "https://i0.hdslb.com/bfs/face/a7176b4e205f2fae521faf3b6d22eca17a44e7a3.jpg",
+     "corner": "",
+     "cover": "",
+     "desc": "",
+     "url": "",
+     "rec_reason": "",
+     "danmaku": 486,
+     "biz_data": null,
+     "is_charge_video": 0,
+     "vt": 0,
+     "enable_vt": 0,
+     "vt_display": "",
+     "subtitle": "",
+     "episode_count_text": "",
+     "release_status": 0,
+     "is_intervene": 0,
+     "area": 0,
+     "style": 0,
+     "cate_name": "",
+     "is_live_room_inline": 0,
+     "live_status": 0,
+     "live_time": "",
+     "online": 0,
+     "rank_index": 31,
+     "rank_offset": 31,
+     "roomid": 0,
+     "short_id": 0,
+     "spread_id": 0,
+     "tags": "",
+     "uface": "",
+     "uid": 0,
+     "uname": "",
+     "user_cover": "",
+     "parent_area_id": 0,
+     "parent_area_name": "",
+     "watched_show": null,
+     "cny_flag": 0,
+     "card_status": 0
+    },
+    {
+     "type": "video",
+     "id": 116022182942541,
+     "author": "VV音乐局",
+     "mid": 9666167,
+     "typeid": "130",
+     "typename": "音乐综合",
+     "arcurl": "http://www.bilibili.com/video/av116022182942541",
+     "aid": 116022182942541,
+     "bvid": "BV1f2FrzwEdd",
+     "title": "【𝐇𝐢-𝐑𝐞𝐬无损音质】|《读心术》- 卓文萱 -‘思念太明显 还是你太危险’",
+     "description": "【Hi-Res无损音质】《读心术》- 卓文萱\n——————————————\n你们的三连是我更新的最大动力!\n——————————————\n仅用于音乐分享,请支持正版!\n——————————————\n有其他想听的欢迎评论区留言~!",
+     "pic": "//i2.hdslb.com/bfs/archive/d7be98493371fecfbebd1ced1007b4dbc93df1db.jpg",
+     "play": 855312,
+     "video_review": 1760,
+     "favorites": 23871,
+     "tag": "hi-res无损,音乐分享官,卓文萱,听歌,读心术,音响,华语,无损音质",
+     "review": 428,
+     "pubdate": 1770358307,
+     "senddate": 1779271267,
+     "duration": "4:21",
+     "badgepay": false,
+     "hit_columns": [],
+     "view_type": "",
+     "is_pay": 0,
+     "is_union_video": 0,
+     "rec_tags": null,
+     "new_rec_tags": [],
+     "like": 8497,
+     "upic": "https://i2.hdslb.com/bfs/face/ae0d28f7a465137bb6a95909ca859829863ada90.jpg",
+     "corner": "",
+     "cover": "",
+     "desc": "",
+     "url": "",
+     "rec_reason": "",
+     "danmaku": 1760,
+     "biz_data": null,
+     "is_charge_video": 0,
+     "vt": 0,
+     "enable_vt": 0,
+     "vt_display": "",
+     "subtitle": "",
+     "episode_count_text": "",
+     "release_status": 0,
+     "is_intervene": 0,
+     "area": 0,
+     "style": 0,
+     "cate_name": "",
+     "is_live_room_inline": 0,
+     "live_status": 0,
+     "live_time": "",
+     "online": 0,
+     "rank_index": 32,
+     "rank_offset": 32,
+     "roomid": 0,
+     "short_id": 0,
+     "spread_id": 0,
+     "tags": "",
+     "uface": "",
+     "uid": 0,
+     "uname": "",
+     "user_cover": "",
+     "parent_area_id": 0,
+     "parent_area_name": "",
+     "watched_show": null,
+     "cny_flag": 0,
+     "card_status": 0
+    },
+    {
+     "type": "video",
+     "id": 362064812,
+     "author": "JLRS-LeoFM",
+     "mid": 3493093607213343,
+     "typeid": "130",
+     "typename": "音乐综合",
+     "arcurl": "http://www.bilibili.com/video/av362064812",
+     "aid": 362064812,
+     "bvid": "BV1d94y1r7PW",
+     "title": "在百万豪装录音棚大声听 爱情公寓3ost 陈韵若&amp;陈每文《爱的回归线》【Hi-res】",
+     "description": "《爱的回归线》由李双周、陈韵若、韦正作词、作曲,陈韵若、陈每文演唱,收录在《爱情公寓3 电视原声带》中。\n\n录音设备:\n话筒:Neumann M149 tube Pair\n调音台:SSL Duality Delta Pro Station\n工作站:PT\n音箱:Barefoot MM12\n[侵删]",
+     "pic": "//i0.hdslb.com/bfs/archive/83c4375dc4dfe3729ec4363153305dfc99330fcd.jpg",
+     "play": 6070720,
+     "video_review": 2309,
+     "favorites": 99177,
+     "tag": "爱情公寓,高音质,Hi-Fi,Hi-res,音响,音乐玩家招募令2.0,音乐分享官",
+     "review": 1810,
+     "pubdate": 1691663400,
+     "senddate": 1770731095,
+     "duration": "4:20",
+     "badgepay": false,
+     "hit_columns": [],
+     "view_type": "",
+     "is_pay": 0,
+     "is_union_video": 0,
+     "rec_tags": null,
+     "new_rec_tags": [],
+     "like": 50873,
+     "upic": "https://i0.hdslb.com/bfs/face/a7176b4e205f2fae521faf3b6d22eca17a44e7a3.jpg",
+     "corner": "",
+     "cover": "",
+     "desc": "",
+     "url": "",
+     "rec_reason": "",
+     "danmaku": 2309,
+     "biz_data": null,
+     "is_charge_video": 0,
+     "vt": 0,
+     "enable_vt": 0,
+     "vt_display": "",
+     "subtitle": "",
+     "episode_count_text": "",
+     "release_status": 0,
+     "is_intervene": 0,
+     "area": 0,
+     "style": 0,
+     "cate_name": "",
+     "is_live_room_inline": 0,
+     "live_status": 0,
+     "live_time": "",
+     "online": 0,
+     "rank_index": 33,
+     "rank_offset": 33,
+     "roomid": 0,
+     "short_id": 0,
+     "spread_id": 0,
+     "tags": "",
+     "uface": "",
+     "uid": 0,
+     "uname": "",
+     "user_cover": "",
+     "parent_area_id": 0,
+     "parent_area_name": "",
+     "watched_show": null,
+     "cny_flag": 0,
+     "card_status": 0
+    },
+    {
+     "type": "video",
+     "id": 325256086,
+     "author": "一半耳机给你",
+     "mid": 433921282,
+     "typeid": "130",
+     "typename": "音乐综合",
+     "arcurl": "http://www.bilibili.com/video/av325256086",
+     "aid": 325256086,
+     "bvid": "BV1pw41157ZR",
+     "title": "阿YueYue, 刘兆宇 - 冬眠·2023【动态歌词】『再也回不去那年的冬 不会再有人等我太久,要如何纪念曾经那些年。 』",
+     "description": "演唱:阿YueYue/刘兆宇\n作词 :桃玖/刘兆宇\n作曲:CMJ/刘兆宇\n原唱:司南\nRap改编 Adapt:刘兆宇\n编曲:侯江浩\n制作人:易泽禹(Xun)\n配唱制作人:易泽禹(Xun)\n制作协力 :侯江浩\n木吉他:Tommy Wu\n电吉他 :祝凡\n企划营销 :子蒙\n推广协力 :屈炜/希贤\n艺人统筹:李坨香\nOP:你好音乐\n❖歌曲版权为歌手本人及其音乐公司所有,本频道只作推广及宣传之用,若喜欢他们的音乐请到以上平台链接购买歌曲支持。\n\n❖喜欢的请分享及订阅本频道❖",
+     "pic": "//i0.hdslb.com/bfs/archive/bf79792ef6ff639e50f56c476c447180afedef39.jpg",
+     "play": 5626949,
+     "video_review": 7031,
+     "favorites": 101655,
+     "tag": "刘兆宇,纪念,蝴蝶,白雪,场景,冬眠·2023,世界,那些年,屏幕,阿YueYue",
+     "review": 2213,
+     "pubdate": 1703560152,
+     "senddate": 1703848385,
+     "duration": "3:8",
+     "badgepay": false,
+     "hit_columns": [],
+     "view_type": "",
+     "is_pay": 0,
+     "is_union_video": 0,
+     "rec_tags": null,
+     "new_rec_tags": [],
+     "like": 48279,
+     "upic": "https://i1.hdslb.com/bfs/face/5d7577bfe601d43687932acd7bcdf409ed5636ed.jpg",
+     "corner": "",
+     "cover": "",
+     "desc": "",
+     "url": "",
+     "rec_reason": "",
+     "danmaku": 7031,
+     "biz_data": null,
+     "is_charge_video": 0,
+     "vt": 0,
+     "enable_vt": 0,
+     "vt_display": "",
+     "subtitle": "",
+     "episode_count_text": "",
+     "release_status": 0,
+     "is_intervene": 0,
+     "area": 0,
+     "style": 0,
+     "cate_name": "",
+     "is_live_room_inline": 0,
+     "live_status": 0,
+     "live_time": "",
+     "online": 0,
+     "rank_index": 34,
+     "rank_offset": 34,
+     "roomid": 0,
+     "short_id": 0,
+     "spread_id": 0,
+     "tags": "",
+     "uface": "",
+     "uid": 0,
+     "uname": "",
+     "user_cover": "",
+     "parent_area_id": 0,
+     "parent_area_name": "",
+     "watched_show": null,
+     "cny_flag": 0,
+     "card_status": 0
+    },
+    {
+     "type": "video",
+     "id": 116652855465445,
+     "author": "陈知许",
+     "mid": 7357950,
+     "typeid": "171",
+     "typename": "电子竞技",
+     "arcurl": "http://www.bilibili.com/video/av116652855465445",
+     "aid": 116652855465445,
+     "bvid": "BV1ESVW6NEzQ",
+     "title": "在专业录音棚听 周杰伦《烟花易冷》|Hi-Res 无损",
+     "description": "在专业录音棚听 周杰伦《烟花易冷》。\nHi-Res\n专辑:跨时代\n专业录音棚\n\n录音设备:Sony C-800G\n#录音棚 #Hi-Res #无损音乐 #周杰伦 #烟花易冷",
+     "pic": "//i1.hdslb.com/bfs/archive/0459541926ac8abd3235be3206b3c36f989c85bd.jpg",
+     "play": 14727,
+     "video_review": 1,
+     "favorites": 564,
+     "tag": "无损音乐,Hi-Res,录音棚,音乐推荐,烟花易冷,听歌,周杰伦",
+     "review": 6,
+     "pubdate": 1780740000,
+     "senddate": 1780740008,
+     "duration": "4:26",
+     "badgepay": false,
+     "hit_columns": [],
+     "view_type": "",
+     "is_pay": 0,
+     "is_union_video": 0,
+     "rec_tags": null,
+     "new_rec_tags": [],
+     "like": 186,
+     "upic": "https://i0.hdslb.com/bfs/face/2cf3ad59e18f49b1f76dcbb93ab3294112055e36.jpg",
+     "corner": "",
+     "cover": "",
+     "desc": "",
+     "url": "",
+     "rec_reason": "",
+     "danmaku": 1,
+     "biz_data": null,
+     "is_charge_video": 0,
+     "vt": 0,
+     "enable_vt": 0,
+     "vt_display": "",
+     "subtitle": "",
+     "episode_count_text": "",
+     "release_status": 0,
+     "is_intervene": 0,
+     "area": 0,
+     "style": 0,
+     "cate_name": "",
+     "is_live_room_inline": 0,
+     "live_status": 0,
+     "live_time": "",
+     "online": 0,
+     "rank_index": 35,
+     "rank_offset": 35,
+     "roomid": 0,
+     "short_id": 0,
+     "spread_id": 0,
+     "tags": "",
+     "uface": "",
+     "uid": 0,
+     "uname": "",
+     "user_cover": "",
+     "parent_area_id": 0,
+     "parent_area_name": "",
+     "watched_show": null,
+     "cny_flag": 0,
+     "card_status": 0
+    },
+    {
+     "type": "video",
+     "id": 116300030414665,
+     "author": "JLRS-LeoFM",
+     "mid": 3493093607213343,
+     "typeid": "130",
+     "typename": "音乐综合",
+     "arcurl": "http://www.bilibili.com/video/av116300030414665",
+     "aid": 116300030414665,
+     "bvid": "BV1bRXABoEmm",
+     "title": "郭采洁《我的未来式》百万豪装录音棚大声听",
+     "description": "《我的未来式》是郭采洁演唱的一首歌曲,由刘伟恩作词,Jun Gyu Jeon 作曲,收录在2007年12月25日发行的专辑《隐形超人》中。\n\n录音设备: \n话筒:Neumann M149 tube Pair \n调音台:SSL Duality Delta Pro Station \n工作站:PT",
+     "pic": "//i2.hdslb.com/bfs/archive/53d8064b2891dc10e9bbbc0c2ca21128fd3324c4.jpg",
+     "play": 394193,
+     "video_review": 325,
+     "favorites": 10025,
+     "tag": "电台新星征集令,Hi-Fi,录音棚,我的未来式,郭采洁,高音质,电台,音响",
+     "review": 483,
+     "pubdate": 1774695600,
+     "senddate": 1774695608,
+     "duration": "3:15",
+     "badgepay": false,
+     "hit_columns": [],
+     "view_type": "",
+     "is_pay": 0,
+     "is_union_video": 0,
+     "rec_tags": null,
+     "new_rec_tags": [],
+     "like": 8691,
+     "upic": "https://i0.hdslb.com/bfs/face/a7176b4e205f2fae521faf3b6d22eca17a44e7a3.jpg",
+     "corner": "",
+     "cover": "",
+     "desc": "",
+     "url": "",
+     "rec_reason": "",
+     "danmaku": 325,
+     "biz_data": null,
+     "is_charge_video": 0,
+     "vt": 0,
+     "enable_vt": 0,
+     "vt_display": "",
+     "subtitle": "",
+     "episode_count_text": "",
+     "release_status": 0,
+     "is_intervene": 0,
+     "area": 0,
+     "style": 0,
+     "cate_name": "",
+     "is_live_room_inline": 0,
+     "live_status": 0,
+     "live_time": "",
+     "online": 0,
+     "rank_index": 36,
+     "rank_offset": 36,
+     "roomid": 0,
+     "short_id": 0,
+     "spread_id": 0,
+     "tags": "",
+     "uface": "",
+     "uid": 0,
+     "uname": "",
+     "user_cover": "",
+     "parent_area_id": 0,
+     "parent_area_name": "",
+     "watched_show": null,
+     "cny_flag": 0,
+     "card_status": 0
+    },
+    {
+     "type": "video",
+     "id": 585599771,
+     "author": "coral13555",
+     "mid": 401955515,
+     "typeid": "193",
+     "typename": "MV",
+     "arcurl": "http://www.bilibili.com/video/av585599771",
+     "aid": 585599771,
+     "bvid": "BV1pz4y1C7qS",
+     "title": "周杰伦-半岛铁盒_MV(超清4K修复)",
+     "description": "酷我 下载  进行画质修复",
+     "pic": "//i0.hdslb.com/bfs/archive/401bf69e7b15b5b7eac3d22e0ed5dc445fca28bb.jpg",
+     "play": 1158607,
+     "video_review": 1572,
+     "favorites": 16959,
+     "tag": "周杰伦,JAY,MV,华语MV",
+     "review": 564,
+     "pubdate": 1607608082,
+     "senddate": 1607608082,
+     "duration": "5:20",
+     "badgepay": false,
+     "hit_columns": [],
+     "view_type": "",
+     "is_pay": 0,
+     "is_union_video": 0,
+     "rec_tags": null,
+     "new_rec_tags": [],
+     "like": 12525,
+     "upic": "https://i2.hdslb.com/bfs/face/2ee92c7187cc5c50b3ffe5875f4930c7dd2d3946.jpg",
+     "corner": "",
+     "cover": "",
+     "desc": "",
+     "url": "",
+     "rec_reason": "",
+     "danmaku": 1572,
+     "biz_data": null,
+     "is_charge_video": 0,
+     "vt": 0,
+     "enable_vt": 0,
+     "vt_display": "",
+     "subtitle": "",
+     "episode_count_text": "",
+     "release_status": 0,
+     "is_intervene": 0,
+     "area": 0,
+     "style": 0,
+     "cate_name": "",
+     "is_live_room_inline": 0,
+     "live_status": 0,
+     "live_time": "",
+     "online": 0,
+     "rank_index": 37,
+     "rank_offset": 37,
+     "roomid": 0,
+     "short_id": 0,
+     "spread_id": 0,
+     "tags": "",
+     "uface": "",
+     "uid": 0,
+     "uname": "",
+     "user_cover": "",
+     "parent_area_id": 0,
+     "parent_area_name": "",
+     "watched_show": null,
+     "cny_flag": 0,
+     "card_status": 0
+    },
+    {
+     "type": "video",
+     "id": 560929500,
+     "author": "贝乐虎儿歌",
+     "mid": 1186617193,
+     "typeid": "130",
+     "typename": "音乐综合",
+     "arcurl": "http://www.bilibili.com/video/av560929500",
+     "aid": 560929500,
+     "bvid": "BV1ve4y1b7BV",
+     "title": "宝宝爱听的热门儿歌精选《贝乐虎儿歌》:小兔子乖乖",
+     "description": "好听好玩的儿歌陪宝宝一路“童”行",
+     "pic": "//i2.hdslb.com/bfs/archive/5dcc474bdb1cb7384c3f6ceaccebecb989b10717.jpg",
+     "play": 2989772,
+     "video_review": 409,
+     "favorites": 4796,
+     "tag": "育儿,早教,认知,亲子,动画,益智,音乐律动,启蒙,儿歌,贝乐虎",
+     "review": 152,
+     "pubdate": 1664176249,
+     "senddate": 1664176274,
+     "duration": "2:11",
+     "badgepay": false,
+     "hit_columns": [],
+     "view_type": "",
+     "is_pay": 0,
+     "is_union_video": 0,
+     "rec_tags": null,
+     "new_rec_tags": [],
+     "like": 5235,
+     "upic": "https://i1.hdslb.com/bfs/face/05d0fa3719479790b82c504f2b9a75b5bcaf4854.jpg",
+     "corner": "",
+     "cover": "",
+     "desc": "",
+     "url": "",
+     "rec_reason": "",
+     "danmaku": 409,
+     "biz_data": null,
+     "is_charge_video": 0,
+     "vt": 0,
+     "enable_vt": 0,
+     "vt_display": "",
+     "subtitle": "",
+     "episode_count_text": "",
+     "release_status": 0,
+     "is_intervene": 0,
+     "area": 0,
+     "style": 0,
+     "cate_name": "",
+     "is_live_room_inline": 0,
+     "live_status": 0,
+     "live_time": "",
+     "online": 0,
+     "rank_index": 38,
+     "rank_offset": 38,
+     "roomid": 0,
+     "short_id": 0,
+     "spread_id": 0,
+     "tags": "",
+     "uface": "",
+     "uid": 0,
+     "uname": "",
+     "user_cover": "",
+     "parent_area_id": 0,
+     "parent_area_name": "",
+     "watched_show": null,
+     "cny_flag": 0,
+     "card_status": 0
+    },
+    {
+     "type": "video",
+     "id": 496957816,
+     "author": "guest06",
+     "mid": 626112175,
+     "typeid": "193",
+     "typename": "MV",
+     "arcurl": "http://www.bilibili.com/video/av496957816",
+     "aid": 496957816,
+     "bvid": "BV1yK411h7BB",
+     "title": "【高清修复MV】北京东路的日子",
+     "description": "北京东路的日子\n原唱:南京外国语学校2010届高三六班\n官方MV高清修复至1080p 60fps,并替换Hi-Res高清音源。\n\n传送门\n凤凰花开的路口 BV11EKmeyEpp",
+     "pic": "//i0.hdslb.com/bfs/archive/f397df3ef5a9ff4b816255eecd2f570122d2576e.jpg",
+     "play": 632471,
+     "video_review": 987,
+     "favorites": 10837,
+     "tag": "MV,毕业,高清修复,北京东路的日子,音乐,告别,青春,校园",
+     "review": 1184,
+     "pubdate": 1706460932,
+     "senddate": 1762531795,
+     "duration": "4:40",
+     "badgepay": false,
+     "hit_columns": [],
+     "view_type": "",
+     "is_pay": 0,
+     "is_union_video": 0,
+     "rec_tags": null,
+     "new_rec_tags": [],
+     "like": 8913,
+     "upic": "https://i1.hdslb.com/bfs/face/f02d1c3d94e1de16c127a78e031d05c8d2f3cbc3.jpg",
+     "corner": "",
+     "cover": "",
+     "desc": "",
+     "url": "",
+     "rec_reason": "",
+     "danmaku": 987,
+     "biz_data": null,
+     "is_charge_video": 0,
+     "vt": 0,
+     "enable_vt": 0,
+     "vt_display": "",
+     "subtitle": "",
+     "episode_count_text": "",
+     "release_status": 0,
+     "is_intervene": 0,
+     "area": 0,
+     "style": 0,
+     "cate_name": "",
+     "is_live_room_inline": 0,
+     "live_status": 0,
+     "live_time": "",
+     "online": 0,
+     "rank_index": 39,
+     "rank_offset": 39,
+     "roomid": 0,
+     "short_id": 0,
+     "spread_id": 0,
+     "tags": "",
+     "uface": "",
+     "uid": 0,
+     "uname": "",
+     "user_cover": "",
+     "parent_area_id": 0,
+     "parent_area_name": "",
+     "watched_show": null,
+     "cny_flag": 0,
+     "card_status": 0
+    },
+    {
+     "type": "video",
+     "id": 116619116352965,
+     "author": "VV音乐局",
+     "mid": 9666167,
+     "typeid": "130",
+     "typename": "音乐综合",
+     "arcurl": "http://www.bilibili.com/video/av116619116352965",
+     "aid": 116619116352965,
+     "bvid": "BV1PWGa6cErK",
+     "title": "【𝐇𝐢-𝐑𝐞𝐬无损音质】|《春娇与志明》- 街道办GDC,欧阳耀莹 -‘我爱这少年讽刺吗’",
+     "description": "【Hi-Res无损音质】《春娇与志明》- 街道办GDC,欧阳耀莹\n——————————————\n你们的三连是我更新的最大动力!\n——————————————\n仅用于音乐分享,请支持正版!\n——————————————\n有其他想听的欢迎评论区留言~!",
+     "pic": "//i0.hdslb.com/bfs/archive/b104ff91a1f00eb54269d95c1580867b48e09ee5.jpg",
+     "play": 73400,
+     "video_review": 300,
+     "favorites": 1983,
+     "tag": "音乐分享官,hi-res无损,街道办GDC,欧阳耀莹,音响,听歌,华语,无损音质",
+     "review": 34,
+     "pubdate": 1779498000,
+     "senddate": 1779797388,
+     "duration": "3:26",
+     "badgepay": false,
+     "hit_columns": [],
+     "view_type": "",
+     "is_pay": 0,
+     "is_union_video": 0,
+     "rec_tags": null,
+     "new_rec_tags": [],
+     "like": 994,
+     "upic": "https://i2.hdslb.com/bfs/face/ae0d28f7a465137bb6a95909ca859829863ada90.jpg",
+     "corner": "",
+     "cover": "",
+     "desc": "",
+     "url": "",
+     "rec_reason": "",
+     "danmaku": 300,
+     "biz_data": null,
+     "is_charge_video": 0,
+     "vt": 0,
+     "enable_vt": 0,
+     "vt_display": "",
+     "subtitle": "",
+     "episode_count_text": "",
+     "release_status": 0,
+     "is_intervene": 0,
+     "area": 0,
+     "style": 0,
+     "cate_name": "",
+     "is_live_room_inline": 0,
+     "live_status": 0,
+     "live_time": "",
+     "online": 0,
+     "rank_index": 40,
+     "rank_offset": 40,
+     "roomid": 0,
+     "short_id": 0,
+     "spread_id": 0,
+     "tags": "",
+     "uface": "",
+     "uid": 0,
+     "uname": "",
+     "user_cover": "",
+     "parent_area_id": 0,
+     "parent_area_name": "",
+     "watched_show": null,
+     "cny_flag": 0,
+     "card_status": 0
+    },
+    {
+     "type": "video",
+     "id": 1600887742,
+     "author": "JLRS-LeoFM",
+     "mid": 3493093607213343,
+     "typeid": "130",
+     "typename": "音乐综合",
+     "arcurl": "http://www.bilibili.com/video/av1600887742",
+     "aid": 1600887742,
+     "bvid": "BV1w2421c7Bi",
+     "title": "孙燕姿《逆光》百万豪装录音棚大声听【Hi-res】",
+     "description": "《逆光》是孙燕姿演唱的歌曲,由廖莹如作词,李伟菘作曲,收录在2007年3月22日发行的专辑《逆光》中。\n\n录音设备:\n话筒:Neumann M149 tube Pair\n调音台:SSL Duality Delta Pro Station\n工作站:PT\n音箱:Barefoot MM12\n[侵删]",
+     "pic": "//i0.hdslb.com/bfs/archive/9b5fa56a7dcd84144f6da59f6bc0cbea8f991ec6.jpg",
+     "play": 2264671,
+     "video_review": 584,
+     "favorites": 34498,
+     "tag": "逆光,孙燕姿,音乐分享官,Hi-res,音响,高音质,Hi-Fi,音乐分享官-新春赏乐纪特别企划,录音棚",
+     "review": 411,
+     "pubdate": 1708598280,
+     "senddate": 1708598280,
+     "duration": "4:55",
+     "badgepay": false,
+     "hit_columns": [],
+     "view_type": "",
+     "is_pay": 0,
+     "is_union_video": 0,
+     "rec_tags": null,
+     "new_rec_tags": [],
+     "like": 17718,
+     "upic": "https://i0.hdslb.com/bfs/face/a7176b4e205f2fae521faf3b6d22eca17a44e7a3.jpg",
+     "corner": "",
+     "cover": "",
+     "desc": "",
+     "url": "",
+     "rec_reason": "",
+     "danmaku": 584,
+     "biz_data": null,
+     "is_charge_video": 0,
+     "vt": 0,
+     "enable_vt": 0,
+     "vt_display": "",
+     "subtitle": "",
+     "episode_count_text": "",
+     "release_status": 0,
+     "is_intervene": 0,
+     "area": 0,
+     "style": 0,
+     "cate_name": "",
+     "is_live_room_inline": 0,
+     "live_status": 0,
+     "live_time": "",
+     "online": 0,
+     "rank_index": 41,
+     "rank_offset": 41,
+     "roomid": 0,
+     "short_id": 0,
+     "spread_id": 0,
+     "tags": "",
+     "uface": "",
+     "uid": 0,
+     "uname": "",
+     "user_cover": "",
+     "parent_area_id": 0,
+     "parent_area_name": "",
+     "watched_show": null,
+     "cny_flag": 0,
+     "card_status": 0
+    },
+    {
+     "type": "video",
+     "id": 114988823944742,
+     "author": "VV音乐局",
+     "mid": 9666167,
+     "typeid": "130",
+     "typename": "音乐综合",
+     "arcurl": "http://www.bilibili.com/video/av114988823944742",
+     "aid": 114988823944742,
+     "bvid": "BV13yt6zXEsf",
+     "title": "【𝐇𝐢-𝐑𝐞𝐬无损音质】|《爱你没差》- 周杰伦 -‘你离开这一拳给的太重’",
+     "description": "【Hi-Res无损音质】《爱你没差》- 周杰伦\n——————————————\n你们的三连是我更新的最大动力!\n——————————————\n仅用于音乐分享,请支持正版!\n——————————————\n有其他想听的欢迎评论区留言~!",
+     "pic": "//i0.hdslb.com/bfs/archive/7324a84aa59c7ba2dc40b3ee2cbf754cfa5c7ea2.jpg",
+     "play": 1853051,
+     "video_review": 4494,
+     "favorites": 27276,
+     "tag": "周杰伦,音乐分享官,爱你没差,音质,歌曲,耳机,音响,音箱,HIFI,无损音质",
+     "review": 572,
+     "pubdate": 1755075780,
+     "senddate": 1779010834,
+     "duration": "4:41",
+     "badgepay": false,
+     "hit_columns": [],
+     "view_type": "",
+     "is_pay": 0,
+     "is_union_video": 0,
+     "rec_tags": null,
+     "new_rec_tags": [],
+     "like": 14388,
+     "upic": "https://i2.hdslb.com/bfs/face/ae0d28f7a465137bb6a95909ca859829863ada90.jpg",
+     "corner": "",
+     "cover": "",
+     "desc": "",
+     "url": "",
+     "rec_reason": "",
+     "danmaku": 4494,
+     "biz_data": null,
+     "is_charge_video": 0,
+     "vt": 0,
+     "enable_vt": 0,
+     "vt_display": "",
+     "subtitle": "",
+     "episode_count_text": "",
+     "release_status": 0,
+     "is_intervene": 0,
+     "area": 0,
+     "style": 0,
+     "cate_name": "",
+     "is_live_room_inline": 0,
+     "live_status": 0,
+     "live_time": "",
+     "online": 0,
+     "rank_index": 42,
+     "rank_offset": 42,
+     "roomid": 0,
+     "short_id": 0,
+     "spread_id": 0,
+     "tags": "",
+     "uface": "",
+     "uid": 0,
+     "uname": "",
+     "user_cover": "",
+     "parent_area_id": 0,
+     "parent_area_name": "",
+     "watched_show": null,
+     "cny_flag": 0,
+     "card_status": 0
+    }
+   ]
+  }
+ }
+}

+ 9 - 0
数据接口与来源/captures/bili_video_dl.json

@@ -0,0 +1,9 @@
+{
+ "label": "bili_video_dl",
+ "url": "https://xy115x231x41x20xy.mcdn.bilivideo.cn:8082/v1/resource/upgcxcode/83/03/907810383/907810383_nb3-1-30016.m4s?agrr=1&build=0&buvid=C1960389-FA32-8A09-0F3F-BCFBEF610D6791015infoc&bvc=vod&bw=59616&deadline=1781166245&dl=0&e=ig8euxZM2rNcNbdlhoNvNC8BqJIzNbfqXBvEqxTEto8BTrNvN0GvT90W5JZMkX_YN0MvXg8gNEV",
+ "http_status": 206,
+ "content_type": "application/octet-stream",
+ "content_range": "bytes 0-1048575/1766147",
+ "bytes_received": 1048576,
+ "looks_like_video": true
+}

File diff ditekan karena terlalu besar
+ 676 - 0
数据接口与来源/captures/douyin_blogger.json


+ 85 - 0
数据接口与来源/captures/douyin_detail.json

@@ -0,0 +1,85 @@
+{
+ "label": "douyin_detail",
+ "url": "http://crawler.aiddit.com/crawler/dou_yin/detail",
+ "request_body": {
+  "content_id": "7522164415848893735"
+ },
+ "response": {
+  "code": 0,
+  "msg": null,
+  "data": {
+   "has_more": false,
+   "next_cursor": null,
+   "data": {
+    "is_cache": true,
+    "channel": 2,
+    "channel_content_id": "7522164415848893735",
+    "content_link": "https://www.douyin.com/video/7522164415848893735",
+    "wx_sn": null,
+    "biz_info": null,
+    "title": "原来彩虹真的是圆形的,一定变得超级幸运!...",
+    "content_type": "video",
+    "body_text": "原来彩虹真的是圆形的,一定变得超级幸运!#治愈系风景 #彩虹 #旅行",
+    "location": null,
+    "source_url": null,
+    "mini_program": null,
+    "topic_list": [
+     "治愈系风景",
+     "彩虹",
+     "旅行"
+    ],
+    "image_url_list": [
+     {
+      "image_type": 2,
+      "image_url": "https://p3-pc-sign.douyinpic.com/tos-cn-p-0015/o0EeCL7OAc37FG5CgEMBvVeS7fIByQuaACCIg9~tplv-dy-360p.jpeg?biz_tag=pcweb_cover&from=327834062&lk3s=138a59ce&s=PackSourceEnum_AWEME_DETAIL&sc=origin_cover&se=false&x-expires=1782363600&x-signature=XcNH%2BvURHNPyKSiX%2FEKIElqRI5w%3D"
+     }
+    ],
+    "video_url_list": [
+     {
+      "video_url": "https://www.douyin.com/aweme/v1/play/?video_id=v0d00fg10000d1i1etvog65uanqirggg&ratio=1080p&line=0",
+      "video_duration": 13
+     }
+    ],
+    "multi_bitrate": {
+     "540p": {
+      "video_url": "https://www.douyin.com/aweme/v1/play/?video_id=v0d00fg10000d1i1etvog65uanqirggg&ratio=540p&line=0",
+      "video_duration": 13
+     },
+     "720p": {
+      "video_url": "https://www.douyin.com/aweme/v1/play/?video_id=v0d00fg10000d1i1etvog65uanqirggg&ratio=720p&line=0",
+      "video_duration": 13
+     },
+     "1080p": {
+      "video_url": "https://www.douyin.com/aweme/v1/play/?video_id=v0d00fg10000d1i1etvog65uanqirggg&ratio=1080p&line=0",
+      "video_duration": 13
+     }
+    },
+    "bgm_data": {
+     "is_cache": true,
+     "id_str": "7522164501945256742",
+     "title": "@源Dream创作的原声",
+     "author": "源Dream",
+     "duration": 13,
+     "play_url": "https://sf6-cdn-tos.douyinstatic.com/obj/ies-music/7522164536225434378.mp3"
+    },
+    "ad_info": null,
+    "is_original": false,
+    "voice_data": null,
+    "channel_account_id": "MS4wLjABAAAAZrIhB0ThEPqj37arlq_4Z6l3jW-E3koi0rGjtSb9jtA",
+    "channel_account_name": "源Dream",
+    "channel_account_avatar": null,
+    "item_index": null,
+    "view_count": null,
+    "play_count": null,
+    "like_count": 5034215,
+    "collect_count": 232359,
+    "comment_count": 121615,
+    "share_count": 2679616,
+    "looking_count": null,
+    "publish_timestamp": 1751515440000,
+    "modify_timestamp": null,
+    "update_timestamp": 1781156249537
+   }
+  }
+ }
+}

+ 1379 - 0
数据接口与来源/captures/douyin_profile_author.json

@@ -0,0 +1,1379 @@
+{
+ "label": "douyin_profile_author",
+ "url": "http://crawler.aiddit.com/crawler/dou_yin/re_dian_bao/account_fans_portrait",
+ "request_body": {
+  "account_id": "MS4wLjABAAAAZrIhB0ThEPqj37arlq_4Z6l3jW-E3koi0rGjtSb9jtA",
+  "need_age": true,
+  "need_gender": true,
+  "need_province": true
+ },
+ "response": {
+  "code": 0,
+  "msg": null,
+  "data": {
+   "has_more": false,
+   "next_cursor": null,
+   "data": {
+    "account": {
+     "fans_milestone": {
+      "first_1w_fans_date": "20230505",
+      "first_10w_fans_date": "20250702",
+      "first_30w_fans_date": "",
+      "first_100w_fans_date": "",
+      "first_500w_fans_date": "",
+      "first_1000w_fans_date": ""
+     },
+     "user_id": "MS4wLjABAAAAZrIhB0ThEPqj37arlq_4Z6l3jW-E3koi0rGjtSb9jtA",
+     "nickname": "源Dream",
+     "create_time": 1523115373,
+     "avatar_url": "https://p11.douyinpic.com/aweme/100x100/aweme-avatar/tos-cn-i-0813c001_ooAii524Ep8ACMgC0HKBvAJengAiAAfgAUAzIC.jpeg?from=2956013662",
+     "total_favorited": 17754802,
+     "follower_count": 166947,
+     "follower_count_str": "166947",
+     "aweme_count": 1101,
+     "first_tag_name": "旅行",
+     "second_tag_name": "旅行记录与分享",
+     "signature": "川西 组团 旅拍μ:Ayuan3230 (备注来意)\nSeeker追光者核心成员、8KRAW签约摄影师、\n甘孜文旅特约摄影师、星联CSVA星空摄影师、星球研究所合作摄影师",
+     "uniqueId": "Ayuan3230",
+     "fancy_qrcode": "https://p5-ex-gddgtc-sign.douyinpic.com/aweme-qrcode/lQuoSn7650018915107571466~c5_200x200.jpeg?x-expires=1781762400&x-signature=PHsc2X%2Fd2Uc6DtaBClerw7itAIM%3D&from=3370593410",
+     "is_monitor": false,
+     "monitor_id": 0,
+     "monitor_status": 1
+    },
+    "posts": {
+     "UserID": 0,
+     "avg_aweme_count": 0.43333333333333335,
+     "avg_comment_count": 8.566666666666666,
+     "avg_share_count": 160.96666666666667,
+     "avg_follower_count": 14,
+     "avg_like_count": 437.6,
+     "avg_aweme_count_c": -0.1333333333333333,
+     "avg_comment_count_c": -0.6070336391437309,
+     "avg_share_count_c": -0.40748466257668714,
+     "avg_follower_count_c": -0.18762088974854937,
+     "avg_like_count_c": -0.2624304736221135,
+     "percentile_aweme_count": 0,
+     "percentile_comment_count": 8.5,
+     "percentile_share_count": 152,
+     "percentile_follower_count": 13,
+     "percentile_like_count": 470,
+     "percentile_aweme_count_c": 0,
+     "percentile_comment_count_c": -0.5,
+     "percentile_share_count_c": -0.01935483870967742,
+     "percentile_follower_count_c": -0.10344827586206896,
+     "percentile_like_count_c": -0.06653426017874876,
+     "BaseResp": null
+    },
+    "fans": {
+     "province": {
+      "name": "粉丝省份分布",
+      "data": {
+       "广东": {
+        "percentage": "12.62%",
+        "preference": "112.10"
+       },
+       "江苏": {
+        "percentage": "7.33%",
+        "preference": "101.14"
+       },
+       "浙江": {
+        "percentage": "6.49%",
+        "preference": "100.32"
+       },
+       "山东": {
+        "percentage": "6.40%",
+        "preference": "98.04"
+       },
+       "四川": {
+        "percentage": "6.20%",
+        "preference": "118.28"
+       },
+       "河南": {
+        "percentage": "5.38%",
+        "preference": "78.39"
+       },
+       "河北": {
+        "percentage": "4.24%",
+        "preference": "92.12"
+       },
+       "北京": {
+        "percentage": "3.80%",
+        "preference": "194.46"
+       },
+       "湖北": {
+        "percentage": "3.64%",
+        "preference": "91.97"
+       },
+       "安徽": {
+        "percentage": "3.26%",
+        "preference": "75.56"
+       },
+       "福建": {
+        "percentage": "3.18%",
+        "preference": "95.39"
+       },
+       "湖南": {
+        "percentage": "3.17%",
+        "preference": "81.16"
+       },
+       "陕西": {
+        "percentage": "3.15%",
+        "preference": "102.55"
+       },
+       "上海": {
+        "percentage": "3.08%",
+        "preference": "143.84"
+       },
+       "辽宁": {
+        "percentage": "2.78%",
+        "preference": "122.73"
+       },
+       "云南": {
+        "percentage": "2.57%",
+        "preference": "77.48"
+       },
+       "山西": {
+        "percentage": "2.31%",
+        "preference": "98.40"
+       },
+       "广西": {
+        "percentage": "2.30%",
+        "preference": "74.08"
+       },
+       "江西": {
+        "percentage": "2.17%",
+        "preference": "72.80"
+       },
+       "重庆": {
+        "percentage": "2.17%",
+        "preference": "104.13"
+       },
+       "内蒙古": {
+        "percentage": "1.94%",
+        "preference": "143.88"
+       },
+       "新疆": {
+        "percentage": "1.92%",
+        "preference": "94.17"
+       },
+       "黑龙江": {
+        "percentage": "1.59%",
+        "preference": "114.03"
+       },
+       "贵州": {
+        "percentage": "1.57%",
+        "preference": "59.69"
+       },
+       "甘肃": {
+        "percentage": "1.49%",
+        "preference": "118.73"
+       },
+       "天津": {
+        "percentage": "1.42%",
+        "preference": "131.75"
+       },
+       "吉林": {
+        "percentage": "1.38%",
+        "preference": "119.54"
+       },
+       "海南": {
+        "percentage": "0.70%",
+        "preference": "83.42"
+       },
+       "宁夏": {
+        "percentage": "0.49%",
+        "preference": "113.11"
+       },
+       "青海": {
+        "percentage": "0.49%",
+        "preference": "158.38"
+       },
+       "西藏": {
+        "percentage": "0.36%",
+        "preference": "96.44"
+       },
+       "香港": {
+        "percentage": "0.33%",
+        "preference": "251.73"
+       },
+       "澳门": {
+        "percentage": "0.08%",
+        "preference": "343.49"
+       },
+       "台湾": {
+        "percentage": "0.00%",
+        "preference": "0.00"
+       }
+      }
+     },
+     "city": {
+      "name": "粉丝城市分布",
+      "data": {
+       "北京": {
+        "percentage": "4.01%",
+        "preference": "206.78"
+       },
+       "成都": {
+        "percentage": "3.40%",
+        "preference": "186.44"
+       },
+       "上海": {
+        "percentage": "3.25%",
+        "preference": "153.27"
+       },
+       "广州": {
+        "percentage": "2.99%",
+        "preference": "148.92"
+       },
+       "深圳": {
+        "percentage": "2.74%",
+        "preference": "155.64"
+       },
+       "重庆": {
+        "percentage": "2.30%",
+        "preference": "111.43"
+       },
+       "杭州": {
+        "percentage": "2.12%",
+        "preference": "156.35"
+       },
+       "西安": {
+        "percentage": "1.85%",
+        "preference": "143.65"
+       },
+       "苏州": {
+        "percentage": "1.72%",
+        "preference": "117.86"
+       },
+       "武汉": {
+        "percentage": "1.71%",
+        "preference": "138.94"
+       },
+       "郑州": {
+        "percentage": "1.65%",
+        "preference": "128.96"
+       },
+       "天津": {
+        "percentage": "1.52%",
+        "preference": "141.76"
+       },
+       "南京": {
+        "percentage": "1.43%",
+        "preference": "163.79"
+       },
+       "东莞": {
+        "percentage": "1.39%",
+        "preference": "100.55"
+       },
+       "佛山": {
+        "percentage": "1.28%",
+        "preference": "129.00"
+       },
+       "长沙": {
+        "percentage": "1.21%",
+        "preference": "122.46"
+       },
+       "昆明": {
+        "percentage": "1.15%",
+        "preference": "140.77"
+       },
+       "青岛": {
+        "percentage": "1.15%",
+        "preference": "135.85"
+       },
+       "济南": {
+        "percentage": "1.04%",
+        "preference": "125.78"
+       },
+       "合肥": {
+        "percentage": "1.03%",
+        "preference": "114.58"
+       },
+       "宁波": {
+        "percentage": "0.96%",
+        "preference": "97.36"
+       },
+       "沈阳": {
+        "percentage": "0.90%",
+        "preference": "141.68"
+       },
+       "福州": {
+        "percentage": "0.88%",
+        "preference": "129.38"
+       },
+       "石家庄": {
+        "percentage": "0.88%",
+        "preference": "116.90"
+       },
+       "无锡": {
+        "percentage": "0.79%",
+        "preference": "113.27"
+       },
+       "温州": {
+        "percentage": "0.79%",
+        "preference": "93.66"
+       },
+       "金华": {
+        "percentage": "0.77%",
+        "preference": "93.13"
+       },
+       "大连": {
+        "percentage": "0.77%",
+        "preference": "158.66"
+       },
+       "南宁": {
+        "percentage": "0.77%",
+        "preference": "105.92"
+       },
+       "哈尔滨": {
+        "percentage": "0.76%",
+        "preference": "137.99"
+       },
+       "长春": {
+        "percentage": "0.74%",
+        "preference": "137.39"
+       },
+       "太原": {
+        "percentage": "0.70%",
+        "preference": "144.58"
+       },
+       "泉州": {
+        "percentage": "0.70%",
+        "preference": "89.18"
+       },
+       "临沂": {
+        "percentage": "0.69%",
+        "preference": "116.83"
+       },
+       "惠州": {
+        "percentage": "0.68%",
+        "preference": "100.79"
+       },
+       "厦门": {
+        "percentage": "0.68%",
+        "preference": "137.48"
+       },
+       "南昌": {
+        "percentage": "0.67%",
+        "preference": "116.92"
+       },
+       "保定": {
+        "percentage": "0.66%",
+        "preference": "79.53"
+       },
+       "南通": {
+        "percentage": "0.64%",
+        "preference": "104.14"
+       },
+       "徐州": {
+        "percentage": "0.61%",
+        "preference": "93.40"
+       },
+       "贵阳": {
+        "percentage": "0.61%",
+        "preference": "108.17"
+       },
+       "乌鲁木齐": {
+        "percentage": "0.58%",
+        "preference": "155.03"
+       },
+       "潍坊": {
+        "percentage": "0.58%",
+        "preference": "86.15"
+       },
+       "常州": {
+        "percentage": "0.57%",
+        "preference": "113.09"
+       },
+       "台州": {
+        "percentage": "0.56%",
+        "preference": "96.23"
+       },
+       "兰州": {
+        "percentage": "0.56%",
+        "preference": "156.06"
+       },
+       "中山": {
+        "percentage": "0.55%",
+        "preference": "106.38"
+       },
+       "廊坊": {
+        "percentage": "0.54%",
+        "preference": "112.55"
+       },
+       "烟台": {
+        "percentage": "0.48%",
+        "preference": "101.80"
+       },
+       "南阳": {
+        "percentage": "0.48%",
+        "preference": "87.87"
+       },
+       "嘉兴": {
+        "percentage": "0.48%",
+        "preference": "84.76"
+       },
+       "绍兴": {
+        "percentage": "0.47%",
+        "preference": "100.55"
+       },
+       "洛阳": {
+        "percentage": "0.45%",
+        "preference": "88.58"
+       },
+       "呼和浩特": {
+        "percentage": "0.45%",
+        "preference": "179.11"
+       },
+       "邯郸": {
+        "percentage": "0.43%",
+        "preference": "76.53"
+       },
+       "江门": {
+        "percentage": "0.43%",
+        "preference": "121.30"
+       },
+       "赣州": {
+        "percentage": "0.41%",
+        "preference": "72.56"
+       },
+       "唐山": {
+        "percentage": "0.40%",
+        "preference": "106.11"
+       },
+       "邢台": {
+        "percentage": "0.39%",
+        "preference": "90.76"
+       },
+       "沧州": {
+        "percentage": "0.38%",
+        "preference": "92.44"
+       },
+       "绵阳": {
+        "percentage": "0.38%",
+        "preference": "129.70"
+       },
+       "盐城": {
+        "percentage": "0.37%",
+        "preference": "76.99"
+       },
+       "新乡": {
+        "percentage": "0.36%",
+        "preference": "80.42"
+       },
+       "珠海": {
+        "percentage": "0.36%",
+        "preference": "149.04"
+       },
+       "汕头": {
+        "percentage": "0.36%",
+        "preference": "77.84"
+       },
+       "淄博": {
+        "percentage": "0.35%",
+        "preference": "115.84"
+       },
+       "济宁": {
+        "percentage": "0.35%",
+        "preference": "78.21"
+       },
+       "海口": {
+        "percentage": "0.34%",
+        "preference": "125.93"
+       },
+       "银川": {
+        "percentage": "0.33%",
+        "preference": "142.59"
+       },
+       "茂名": {
+        "percentage": "0.32%",
+        "preference": "104.59"
+       },
+       "湛江": {
+        "percentage": "0.32%",
+        "preference": "85.65"
+       },
+       "肇庆": {
+        "percentage": "0.32%",
+        "preference": "113.15"
+       },
+       "扬州": {
+        "percentage": "0.31%",
+        "preference": "92.15"
+       },
+       "泰州": {
+        "percentage": "0.31%",
+        "preference": "97.43"
+       },
+       "桂林": {
+        "percentage": "0.31%",
+        "preference": "101.68"
+       },
+       "湖州": {
+        "percentage": "0.31%",
+        "preference": "89.06"
+       },
+       "咸阳": {
+        "percentage": "0.31%",
+        "preference": "82.03"
+       },
+       "泰安": {
+        "percentage": "0.30%",
+        "preference": "108.00"
+       },
+       "菏泽": {
+        "percentage": "0.30%",
+        "preference": "61.80"
+       },
+       "周口": {
+        "percentage": "0.29%",
+        "preference": "53.01"
+       },
+       "镇江": {
+        "percentage": "0.29%",
+        "preference": "113.09"
+       },
+       "阜阳": {
+        "percentage": "0.28%",
+        "preference": "60.95"
+       },
+       "包头": {
+        "percentage": "0.28%",
+        "preference": "177.44"
+       },
+       "芜湖": {
+        "percentage": "0.28%",
+        "preference": "94.32"
+       },
+       "鄂尔多斯": {
+        "percentage": "0.28%",
+        "preference": "163.78"
+       },
+       "连云港": {
+        "percentage": "0.28%",
+        "preference": "90.53"
+       },
+       "晋中": {
+        "percentage": "0.28%",
+        "preference": "107.02"
+       },
+       "榆林": {
+        "percentage": "0.28%",
+        "preference": "122.42"
+       },
+       "揭阳": {
+        "percentage": "0.27%",
+        "preference": "71.44"
+       },
+       "聊城": {
+        "percentage": "0.26%",
+        "preference": "93.09"
+       },
+       "信阳": {
+        "percentage": "0.26%",
+        "preference": "70.82"
+       },
+       "西宁": {
+        "percentage": "0.26%",
+        "preference": "165.69"
+       },
+       "漳州": {
+        "percentage": "0.26%",
+        "preference": "66.03"
+       },
+       "德阳": {
+        "percentage": "0.26%",
+        "preference": "125.38"
+       },
+       "衡阳": {
+        "percentage": "0.26%",
+        "preference": "78.90"
+       },
+       "商丘": {
+        "percentage": "0.26%",
+        "preference": "51.45"
+       },
+       "宜昌": {
+        "percentage": "0.26%",
+        "preference": "97.04"
+       },
+       "赤峰": {
+        "percentage": "0.26%",
+        "preference": "138.03"
+       },
+       "襄阳": {
+        "percentage": "0.26%",
+        "preference": "85.53"
+       },
+       "淮安": {
+        "percentage": "0.26%",
+        "preference": "77.58"
+       },
+       "许昌": {
+        "percentage": "0.26%",
+        "preference": "88.77"
+       },
+       "伊犁": {
+        "percentage": "0.25%",
+        "preference": "113.44"
+       },
+       "安阳": {
+        "percentage": "0.25%",
+        "preference": "69.08"
+       },
+       "南充": {
+        "percentage": "0.25%",
+        "preference": "91.13"
+       },
+       "遵义": {
+        "percentage": "0.25%",
+        "preference": "53.70"
+       },
+       "宜宾": {
+        "percentage": "0.25%",
+        "preference": "83.43"
+       },
+       "清远": {
+        "percentage": "0.25%",
+        "preference": "97.79"
+       },
+       "平顶山": {
+        "percentage": "0.25%",
+        "preference": "80.25"
+       },
+       "威海": {
+        "percentage": "0.24%",
+        "preference": "116.32"
+       },
+       "德州": {
+        "percentage": "0.24%",
+        "preference": "87.71"
+       },
+       "运城": {
+        "percentage": "0.24%",
+        "preference": "70.89"
+       },
+       "柳州": {
+        "percentage": "0.24%",
+        "preference": "88.35"
+       },
+       "张家口": {
+        "percentage": "0.24%",
+        "preference": "108.31"
+       },
+       "大同": {
+        "percentage": "0.23%",
+        "preference": "153.01"
+       },
+       "上饶": {
+        "percentage": "0.23%",
+        "preference": "62.91"
+       },
+       "株洲": {
+        "percentage": "0.23%",
+        "preference": "95.63"
+       },
+       "宿迁": {
+        "percentage": "0.23%",
+        "preference": "63.20"
+       },
+       "九江": {
+        "percentage": "0.23%",
+        "preference": "75.75"
+       },
+       "开封": {
+        "percentage": "0.23%",
+        "preference": "69.77"
+       },
+       "吉林": {
+        "percentage": "0.23%",
+        "preference": "138.27"
+       },
+       "莆田": {
+        "percentage": "0.23%",
+        "preference": "89.72"
+       },
+       "黄冈": {
+        "percentage": "0.23%",
+        "preference": "67.50"
+       },
+       "驻马店": {
+        "percentage": "0.22%",
+        "preference": "53.91"
+       },
+       "衡水": {
+        "percentage": "0.22%",
+        "preference": "110.72"
+       },
+       "临汾": {
+        "percentage": "0.21%",
+        "preference": "86.33"
+       },
+       "枣庄": {
+        "percentage": "0.21%",
+        "preference": "97.32"
+       },
+       "邵阳": {
+        "percentage": "0.21%",
+        "preference": "74.13"
+       },
+       "滨州": {
+        "percentage": "0.21%",
+        "preference": "93.08"
+       },
+       "六安": {
+        "percentage": "0.21%",
+        "preference": "72.55"
+       },
+       "泸州": {
+        "percentage": "0.21%",
+        "preference": "83.37"
+       },
+       "大理": {
+        "percentage": "0.21%",
+        "preference": "90.10"
+       },
+       "秦皇岛": {
+        "percentage": "0.21%",
+        "preference": "136.95"
+       },
+       "焦作": {
+        "percentage": "0.20%",
+        "preference": "80.67"
+       },
+       "曲靖": {
+        "percentage": "0.20%",
+        "preference": "58.26"
+       },
+       "滁州": {
+        "percentage": "0.20%",
+        "preference": "71.70"
+       },
+       "荆州": {
+        "percentage": "0.20%",
+        "preference": "66.25"
+       },
+       "宿州": {
+        "percentage": "0.20%",
+        "preference": "62.26"
+       },
+       "常德": {
+        "percentage": "0.20%",
+        "preference": "71.05"
+       },
+       "蚌埠": {
+        "percentage": "0.19%",
+        "preference": "82.22"
+       },
+       "东营": {
+        "percentage": "0.19%",
+        "preference": "118.06"
+       },
+       "鞍山": {
+        "percentage": "0.19%",
+        "preference": "122.64"
+       },
+       "岳阳": {
+        "percentage": "0.19%",
+        "preference": "70.49"
+       },
+       "玉林": {
+        "percentage": "0.19%",
+        "preference": "63.72"
+       },
+       "宝鸡": {
+        "percentage": "0.19%",
+        "preference": "90.01"
+       },
+       "日照": {
+        "percentage": "0.19%",
+        "preference": "99.33"
+       },
+       "大庆": {
+        "percentage": "0.18%",
+        "preference": "152.85"
+       },
+       "宁德": {
+        "percentage": "0.18%",
+        "preference": "82.99"
+       },
+       "渭南": {
+        "percentage": "0.18%",
+        "preference": "58.95"
+       },
+       "红河": {
+        "percentage": "0.18%",
+        "preference": "64.33"
+       },
+       "眉山": {
+        "percentage": "0.18%",
+        "preference": "91.20"
+       },
+       "承德": {
+        "percentage": "0.18%",
+        "preference": "112.42"
+       },
+       "孝感": {
+        "percentage": "0.18%",
+        "preference": "71.50"
+       },
+       "恩施": {
+        "percentage": "0.18%",
+        "preference": "80.34"
+       },
+       "乐山": {
+        "percentage": "0.18%",
+        "preference": "96.06"
+       },
+       "韶关": {
+        "percentage": "0.18%",
+        "preference": "106.07"
+       },
+       "汉中": {
+        "percentage": "0.18%",
+        "preference": "94.16"
+       },
+       "丽水": {
+        "percentage": "0.18%",
+        "preference": "97.62"
+       },
+       "淮南": {
+        "percentage": "0.17%",
+        "preference": "89.97"
+       },
+       "汕尾": {
+        "percentage": "0.17%",
+        "preference": "87.78"
+       },
+       "濮阳": {
+        "percentage": "0.17%",
+        "preference": "83.95"
+       },
+       "亳州": {
+        "percentage": "0.17%",
+        "preference": "56.18"
+       },
+       "湘潭": {
+        "percentage": "0.17%",
+        "preference": "103.57"
+       },
+       "龙岩": {
+        "percentage": "0.17%",
+        "preference": "102.51"
+       },
+       "潮州": {
+        "percentage": "0.17%",
+        "preference": "81.08"
+       },
+       "吕梁": {
+        "percentage": "0.17%",
+        "preference": "91.89"
+       },
+       "阳江": {
+        "percentage": "0.17%",
+        "preference": "105.35"
+       },
+       "拉萨": {
+        "percentage": "0.17%",
+        "preference": "137.84"
+       },
+       "十堰": {
+        "percentage": "0.17%",
+        "preference": "92.03"
+       },
+       "怀化": {
+        "percentage": "0.17%",
+        "preference": "67.52"
+       },
+       "毕节": {
+        "percentage": "0.16%",
+        "preference": "44.83"
+       },
+       "呼伦贝尔": {
+        "percentage": "0.16%",
+        "preference": "147.21"
+       },
+       "吉安": {
+        "percentage": "0.16%",
+        "preference": "63.83"
+       },
+       "梅州": {
+        "percentage": "0.16%",
+        "preference": "87.14"
+       },
+       "宜春": {
+        "percentage": "0.16%",
+        "preference": "55.50"
+       },
+       "三亚": {
+        "percentage": "0.16%",
+        "preference": "141.00"
+       },
+       "巴音郭楞": {
+        "percentage": "0.16%",
+        "preference": "114.68"
+       },
+       "衢州": {
+        "percentage": "0.16%",
+        "preference": "96.03"
+       },
+       "达州": {
+        "percentage": "0.16%",
+        "preference": "71.16"
+       },
+       "郴州": {
+        "percentage": "0.16%",
+        "preference": "64.78"
+       },
+       "忻州": {
+        "percentage": "0.15%",
+        "preference": "117.61"
+       },
+       "齐齐哈尔": {
+        "percentage": "0.15%",
+        "preference": "113.63"
+       },
+       "长治": {
+        "percentage": "0.15%",
+        "preference": "66.41"
+       },
+       "安庆": {
+        "percentage": "0.15%",
+        "preference": "59.37"
+       },
+       "甘孜": {
+        "percentage": "0.15%",
+        "preference": "178.39"
+       },
+       "黄石": {
+        "percentage": "0.15%",
+        "preference": "98.71"
+       },
+       "永州": {
+        "percentage": "0.15%",
+        "preference": "61.89"
+       },
+       "河源": {
+        "percentage": "0.14%",
+        "preference": "89.77"
+       },
+       "凉山": {
+        "percentage": "0.14%",
+        "preference": "66.08"
+       },
+       "昌吉": {
+        "percentage": "0.14%",
+        "preference": "100.51"
+       },
+       "喀什": {
+        "percentage": "0.14%",
+        "preference": "48.93"
+       },
+       "咸宁": {
+        "percentage": "0.14%",
+        "preference": "89.64"
+       },
+       "南平": {
+        "percentage": "0.14%",
+        "preference": "83.07"
+       },
+       "延安": {
+        "percentage": "0.14%",
+        "preference": "97.92"
+       },
+       "漯河": {
+        "percentage": "0.14%",
+        "preference": "92.38"
+       },
+       "通辽": {
+        "percentage": "0.14%",
+        "preference": "119.35"
+       },
+       "黔南": {
+        "percentage": "0.14%",
+        "preference": "56.93"
+       },
+       "抚州": {
+        "percentage": "0.14%",
+        "preference": "64.77"
+       },
+       "延边": {
+        "percentage": "0.13%",
+        "preference": "139.65"
+       },
+       "宣城": {
+        "percentage": "0.13%",
+        "preference": "67.37"
+       },
+       "广安": {
+        "percentage": "0.13%",
+        "preference": "88.47"
+       },
+       "阿克苏": {
+        "percentage": "0.13%",
+        "preference": "65.03"
+       },
+       "三明": {
+        "percentage": "0.13%",
+        "preference": "88.15"
+       },
+       "黔东南": {
+        "percentage": "0.13%",
+        "preference": "54.57"
+       },
+       "百色": {
+        "percentage": "0.13%",
+        "preference": "57.04"
+       },
+       "云浮": {
+        "percentage": "0.13%",
+        "preference": "102.78"
+       },
+       "营口": {
+        "percentage": "0.13%",
+        "preference": "111.95"
+       },
+       "三门峡": {
+        "percentage": "0.12%",
+        "preference": "94.91"
+       },
+       "马鞍山": {
+        "percentage": "0.12%",
+        "preference": "79.09"
+       },
+       "酒泉": {
+        "percentage": "0.12%",
+        "preference": "150.68"
+       },
+       "娄底": {
+        "percentage": "0.12%",
+        "preference": "64.21"
+       },
+       "锦州": {
+        "percentage": "0.12%",
+        "preference": "109.14"
+       },
+       "遂宁": {
+        "percentage": "0.12%",
+        "preference": "89.94"
+       },
+       "钦州": {
+        "percentage": "0.12%",
+        "preference": "67.85"
+       },
+       "锡林郭勒": {
+        "percentage": "0.12%",
+        "preference": "139.74"
+       },
+       "玉溪": {
+        "percentage": "0.12%",
+        "preference": "73.83"
+       },
+       "内江": {
+        "percentage": "0.12%",
+        "preference": "80.04"
+       },
+       "乌兰察布": {
+        "percentage": "0.12%",
+        "preference": "164.84"
+       },
+       "楚雄": {
+        "percentage": "0.11%",
+        "preference": "85.61"
+       },
+       "贵港": {
+        "percentage": "0.11%",
+        "preference": "58.71"
+       },
+       "葫芦岛": {
+        "percentage": "0.11%",
+        "preference": "119.20"
+       },
+       "荆门": {
+        "percentage": "0.11%",
+        "preference": "73.24"
+       },
+       "益阳": {
+        "percentage": "0.11%",
+        "preference": "61.54"
+       },
+       "晋城": {
+        "percentage": "0.11%",
+        "preference": "69.18"
+       },
+       "舟山": {
+        "percentage": "0.11%",
+        "preference": "102.85"
+       },
+       "梧州": {
+        "percentage": "0.11%",
+        "preference": "74.41"
+       },
+       "安康": {
+        "percentage": "0.11%",
+        "preference": "72.44"
+       },
+       "朔州": {
+        "percentage": "0.11%",
+        "preference": "156.26"
+       },
+       "香港": {
+        "percentage": "0.11%",
+        "preference": "189.56"
+       },
+       "丹东": {
+        "percentage": "0.11%",
+        "preference": "97.34"
+       },
+       "佳木斯": {
+        "percentage": "0.11%",
+        "preference": "113.73"
+       },
+       "景德镇": {
+        "percentage": "0.11%",
+        "preference": "85.22"
+       },
+       "抚顺": {
+        "percentage": "0.11%",
+        "preference": "122.66"
+       },
+       "北海": {
+        "percentage": "0.11%",
+        "preference": "82.85"
+       },
+       "新界": {
+        "percentage": "0.11%",
+        "preference": "270.21"
+       },
+       "绥化": {
+        "percentage": "0.11%",
+        "preference": "97.57"
+       },
+       "广元": {
+        "percentage": "0.11%",
+        "preference": "74.74"
+       },
+       "黔西南": {
+        "percentage": "0.10%",
+        "preference": "53.70"
+       },
+       "庆阳": {
+        "percentage": "0.10%",
+        "preference": "112.59"
+       },
+       "自贡": {
+        "percentage": "0.10%",
+        "preference": "80.55"
+       },
+       "文山": {
+        "percentage": "0.10%",
+        "preference": "54.19"
+       },
+       "天水": {
+        "percentage": "0.10%",
+        "preference": "93.98"
+       },
+       "六盘水": {
+        "percentage": "0.10%",
+        "preference": "54.06"
+       },
+       "丽江": {
+        "percentage": "0.10%",
+        "preference": "112.14"
+       },
+       "昭通": {
+        "percentage": "0.10%",
+        "preference": "41.04"
+       },
+       "牡丹江": {
+        "percentage": "0.10%",
+        "preference": "101.38"
+       },
+       "张掖": {
+        "percentage": "0.10%",
+        "preference": "157.36"
+       },
+       "阿坝": {
+        "percentage": "0.10%",
+        "preference": "157.74"
+       },
+       "定西": {
+        "percentage": "0.10%",
+        "preference": "136.13"
+       },
+       "淮北": {
+        "percentage": "0.10%",
+        "preference": "76.52"
+       },
+       "巴彦淖尔": {
+        "percentage": "0.10%",
+        "preference": "130.69"
+       },
+       "其他": {
+        "percentage": "0.02%",
+        "preference": "0.00"
+       }
+      }
+     },
+     "city_level": {
+      "name": "粉丝城市等级分布",
+      "data": {
+       "新一线": {
+        "percentage": "22.99%",
+        "preference": "126.73"
+       },
+       "二线": {
+        "percentage": "19.44%",
+        "preference": "104.86"
+       },
+       "三线": {
+        "percentage": "19.24%",
+        "preference": "81.63"
+       },
+       "四线": {
+        "percentage": "14.74%",
+        "preference": "82.94"
+       },
+       "一线": {
+        "percentage": "12.24%",
+        "preference": "156.74"
+       },
+       "五线": {
+        "percentage": "9.87%",
+        "preference": "80.51"
+       },
+       "六线及以下": {
+        "percentage": "1.08%",
+        "preference": "120.06"
+       },
+       "特区": {
+        "percentage": "0.40%",
+        "preference": "265.90"
+       }
+      }
+     },
+     "gender": {
+      "name": "粉丝性别分布",
+      "data": {
+       "male": {
+        "percentage": "71.30%",
+        "preference": "135.57"
+       },
+       "female": {
+        "percentage": "28.70%",
+        "preference": "62.07"
+       }
+      }
+     },
+     "age": {
+      "name": "粉丝年龄分布",
+      "data": {
+       "31-40": {
+        "percentage": "29.00%",
+        "preference": "74.13"
+       },
+       "24-30": {
+        "percentage": "26.88%",
+        "preference": "138.36"
+       },
+       "18-23": {
+        "percentage": "26.48%",
+        "preference": "164.31"
+       },
+       "50-": {
+        "percentage": "10.13%",
+        "preference": "35.53"
+       },
+       "41-50": {
+        "percentage": "7.51%",
+        "preference": "39.54"
+       }
+      }
+     },
+     "phone_brand": {
+      "name": "粉丝手机品牌分布",
+      "data": {
+       "苹果": {
+        "percentage": "39.62%",
+        "preference": "129.22"
+       },
+       "华为": {
+        "percentage": "18.79%",
+        "preference": "96.26"
+       },
+       "VIVO": {
+        "percentage": "11.72%",
+        "preference": "80.56"
+       },
+       "OPPO": {
+        "percentage": "10.98%",
+        "preference": "72.85"
+       },
+       "小米": {
+        "percentage": "9.51%",
+        "preference": "144.80"
+       },
+       "荣耀": {
+        "percentage": "7.78%",
+        "preference": "69.22"
+       },
+       "华为荣耀": {
+        "percentage": "1.59%",
+        "preference": "66.90"
+       }
+      }
+     },
+     "phone_price": {
+      "name": "粉丝手机价格分布",
+      "data": {
+       "2000~2999": {
+        "percentage": "19.83%",
+        "preference": "94.61"
+       },
+       "5000~5999": {
+        "percentage": "15.66%",
+        "preference": "118.91"
+       },
+       "1000~1999": {
+        "percentage": "14.10%",
+        "preference": "55.41"
+       },
+       "3000~3999": {
+        "percentage": "12.56%",
+        "preference": "128.71"
+       },
+       "8000~8999": {
+        "percentage": "8.57%",
+        "preference": "136.40"
+       },
+       "9000~9999": {
+        "percentage": "8.07%",
+        "preference": "155.09"
+       },
+       "6000~6999": {
+        "percentage": "7.22%",
+        "preference": "131.04"
+       },
+       "4000~4999": {
+        "percentage": "6.70%",
+        "preference": "131.22"
+       },
+       "7000~7999": {
+        "percentage": "4.60%",
+        "preference": "156.16"
+       },
+       "10000及以上": {
+        "percentage": "1.98%",
+        "preference": "171.42"
+       },
+       "0~999": {
+        "percentage": "0.71%",
+        "preference": "45.07"
+       }
+      }
+     }
+    }
+   }
+  }
+ }
+}

+ 12 - 0
数据接口与来源/captures/douyin_profile_content.json

@@ -0,0 +1,12 @@
+{
+ "label": "douyin_profile_content",
+ "url": "http://crawler.aiddit.com/crawler/dou_yin/re_dian_bao/video_like_portrait",
+ "request_body": {
+  "content_id": "7522164415848893735",
+  "need_age": true,
+  "need_gender": true,
+  "need_province": true
+ },
+ "http_error": 404,
+ "error_body": "<html><title>404: Not Found</title><body>404: Not Found</body></html>"
+}

File diff ditekan karena terlalu besar
+ 788 - 0
数据接口与来源/captures/douyin_search.json


+ 10 - 0
数据接口与来源/captures/douyin_video_dl.json

@@ -0,0 +1,10 @@
+{
+ "label": "douyin_video_dl",
+ "url": "https://v11-wha.douyinvod.com/6f3d93d7f4dc6f8ef1f14ab3825f891d/6a2a6182/video/tos/cn/tos-cn-ve-15/oEC76gaGQC15h1bLIEkCQAQVBBpMeyeAe7IE7v/?a=1128&ch=11&cr=3&dr=0&lr=all&cd=0%7C0%7C0%7C3&cv=1&br=1411&bt=1411&cs=2&ds=4&ft=Ocnbvrh7VVyw3CRKm8hmo~O5pQX4D0iX39joRlMyeF~4&mime_type=video_mp4&qs=0&rc=ZDs0N2U5",
+ "http_status": 206,
+ "content_type": "video/mp4",
+ "content_length_header": "1048576",
+ "content_range": "bytes 0-1048575/2399605",
+ "bytes_received": 1048576,
+ "looks_like_video": true
+}

+ 331 - 0
数据接口与来源/captures/github_search.json

@@ -0,0 +1,331 @@
+{
+ "label": "github_search",
+ "url": "http://crawler.aiddit.com/crawler/github/keyword",
+ "request_body": {
+  "keyword": "彩虹",
+  "token": ""
+ },
+ "response": {
+  "code": 0,
+  "msg": null,
+  "data": {
+   "has_more": true,
+   "next_cursor": "1",
+   "data": [
+    {
+     "id": "403254193",
+     "archived": false,
+     "color": null,
+     "followers": 20209,
+     "has_funding_file": false,
+     "hl_name": "Dujltqzv/Some-Many-Books",
+     "hl_trunc_description": "... 》PDF下载_姚立波主编,《C语言程序设计-精选范例解析与习题》PDF下载_颜晖,《Photoshop CS4中文版实训标准教程》PDF下载_许莉.于辉主编,《网页色<em>彩</em>搭配设计师必备宝典》PDF下载_张晓景,《PHP5.5从零开始学-(视频教学版)》PDF下载_刘增…",
+     "language": null,
+     "mirror": false,
+     "owned_by_organization": false,
+     "public": true,
+     "repo": {
+      "repository": {
+       "id": 403254193,
+       "name": "Some-Many-Books",
+       "owner_id": 89769584,
+       "owner_login": "Dujltqzv",
+       "updated_at": "2025-12-03T01:54:08.096Z",
+       "has_issues": false
+      }
+     },
+     "sponsorable": false,
+     "topics": [],
+     "type": "Public",
+     "help_wanted_issues_count": 0,
+     "good_first_issue_issues_count": 0,
+     "starred_by_current_user": false
+    },
+    {
+     "id": "702272852",
+     "archived": false,
+     "color": "#00ADD8",
+     "followers": 1626,
+     "has_funding_file": false,
+     "hl_name": "v03413/BEpusdt",
+     "hl_trunc_description": "一款更好用的个人加密货币收款网关,兼容所有 Epusdt 插件,可无缝切换,支持动态汇率、支持Docker部署;支持独角数卡 <em>彩</em><em>虹</em>易支付",
+     "language": "Go",
+     "mirror": false,
+     "owned_by_organization": false,
+     "public": true,
+     "repo": {
+      "repository": {
+       "id": 702272852,
+       "name": "BEpusdt",
+       "owner_id": 49953737,
+       "owner_login": "v03413",
+       "updated_at": "2026-06-10T01:28:04.341Z",
+       "has_issues": true
+      }
+     },
+     "sponsorable": false,
+     "topics": [],
+     "type": "Public",
+     "help_wanted_issues_count": 0,
+     "good_first_issue_issues_count": 0,
+     "starred_by_current_user": false
+    },
+    {
+     "id": "781466201",
+     "archived": false,
+     "color": "#4F5D95",
+     "followers": 1392,
+     "has_funding_file": false,
+     "hl_name": "netcccyun/dnsmgr",
+     "hl_trunc_description": "<em>彩</em><em>虹</em>聚合DNS管理系统",
+     "language": "PHP",
+     "mirror": false,
+     "owned_by_organization": false,
+     "public": true,
+     "repo": {
+      "repository": {
+       "id": 781466201,
+       "name": "dnsmgr",
+       "owner_id": 8541489,
+       "owner_login": "netcccyun",
+       "updated_at": "2026-06-06T08:07:00.393Z",
+       "has_issues": true
+      }
+     },
+     "sponsorable": false,
+     "topics": [],
+     "type": "Public",
+     "help_wanted_issues_count": 0,
+     "good_first_issue_issues_count": 0,
+     "starred_by_current_user": false
+    },
+    {
+     "id": "818703165",
+     "archived": false,
+     "color": "#f1e05a",
+     "followers": 524,
+     "has_funding_file": false,
+     "hl_name": "zjk2017/ArcadiaScriptPublic",
+     "hl_trunc_description": "青龙脚本库&amp; Issues接投稿 天瑞地安|移动云盘|爱奇艺|奇瑞|金山小程序打卡|雪花|节卡|厚工坊|屈臣氏|掌上瓯海积分|上啥班|永辉|丽影云街|杜蕾斯会员中心|一点万象|所有女生|途虎|沪碳行签到|钉钉ai签到领算粒|哪吒汽车|新战马能量星球|pp停车|桃色|江铃智行…",
+     "language": "JavaScript",
+     "mirror": false,
+     "owned_by_organization": false,
+     "public": true,
+     "repo": {
+      "repository": {
+       "id": 818703165,
+       "name": "ArcadiaScriptPublic",
+       "owner_id": 27203847,
+       "owner_login": "zjk2017",
+       "updated_at": "2024-12-26T14:57:22.124Z",
+       "has_issues": true
+      }
+     },
+     "sponsorable": false,
+     "topics": [],
+     "type": "Public",
+     "help_wanted_issues_count": 0,
+     "good_first_issue_issues_count": 0,
+     "starred_by_current_user": false
+    },
+    {
+     "id": "878959547",
+     "archived": false,
+     "color": "#4F5D95",
+     "followers": 480,
+     "has_funding_file": false,
+     "hl_name": "maajiko/Epay",
+     "hl_trunc_description": "Epay<em>彩</em><em>虹</em>易支付源码分享",
+     "language": "PHP",
+     "mirror": false,
+     "owned_by_organization": false,
+     "public": true,
+     "repo": {
+      "repository": {
+       "id": 878959547,
+       "name": "Epay",
+       "owner_id": 83452696,
+       "owner_login": "maajiko",
+       "updated_at": "2026-06-08T15:22:21.837Z",
+       "has_issues": true
+      }
+     },
+     "sponsorable": false,
+     "topics": [],
+     "type": "Public",
+     "help_wanted_issues_count": 0,
+     "good_first_issue_issues_count": 0,
+     "starred_by_current_user": false
+    },
+    {
+     "id": "347977662",
+     "archived": false,
+     "color": null,
+     "followers": 472,
+     "has_funding_file": false,
+     "hl_name": "pxvr-official/1",
+     "hl_trunc_description": "... 园,奥日与黑暗森林,拳击俱乐部,见证者,星球基地,以撒的结合:胎衣,天空之山,监狱建筑师,环世界,崩溃大陆,荒神,星界边境,无人之境,风之旅人,旅途,机械迷城,堡垒,菲斯,地狱边境,死亡细胞,终结将至,缺氧,逃脱者,茶杯头,街头霸王,量子破碎,黑暗之魂,羞辱,地铁:…",
+     "language": null,
+     "mirror": false,
+     "owned_by_organization": true,
+     "public": true,
+     "repo": {
+      "repository": {
+       "id": 347977662,
+       "name": "1",
+       "owner_id": 80693114,
+       "owner_login": "pxvr-official",
+       "updated_at": "2021-03-15T13:23:42.611Z",
+       "has_issues": false
+      }
+     },
+     "sponsorable": false,
+     "topics": [
+      "markdown",
+      "youtube",
+      "niconico",
+      "pixiv",
+      "shaco",
+      "ao3",
+      "archive-of-our-own",
+      "996icu",
+      "musedash",
+      "shinka-musume",
+      "kagura-nana",
+      "hiseki-erio",
+      "ding-zhen",
+      "zheng-shuang",
+      "cierra-runis",
+      "mia-runis",
+      "paryi",
+      "shen-xiaoya",
+      "kyou-ka",
+      "overidea"
+     ],
+     "type": "Public",
+     "help_wanted_issues_count": 0,
+     "good_first_issue_issues_count": 0,
+     "starred_by_current_user": false
+    },
+    {
+     "id": "697663708",
+     "archived": false,
+     "color": "#e34c26",
+     "followers": 403,
+     "has_funding_file": false,
+     "hl_name": "netcccyun/toolbox",
+     "hl_trunc_description": "<em>彩</em><em>虹</em>工具箱,一个在线工具箱",
+     "language": "HTML",
+     "mirror": false,
+     "owned_by_organization": false,
+     "public": true,
+     "repo": {
+      "repository": {
+       "id": 697663708,
+       "name": "toolbox",
+       "owner_id": 8541489,
+       "owner_login": "netcccyun",
+       "updated_at": "2026-01-26T04:33:27.549Z",
+       "has_issues": true
+      }
+     },
+     "sponsorable": false,
+     "topics": [],
+     "type": "Public",
+     "help_wanted_issues_count": 0,
+     "good_first_issue_issues_count": 0,
+     "starred_by_current_user": false
+    },
+    {
+     "id": "479939480",
+     "archived": false,
+     "color": "#4F5D95",
+     "followers": 374,
+     "has_funding_file": false,
+     "hl_name": "v03413/epay_usdt",
+     "hl_trunc_description": "<em>彩</em><em>虹</em>易支付 USDT收款插件 bepusdt epusdt 发卡 独角发卡 异次元发卡",
+     "language": "PHP",
+     "mirror": false,
+     "owned_by_organization": false,
+     "public": true,
+     "repo": {
+      "repository": {
+       "id": 479939480,
+       "name": "epay_usdt",
+       "owner_id": 49953737,
+       "owner_login": "v03413",
+       "updated_at": "2023-11-14T04:00:35.684Z",
+       "has_issues": false
+      }
+     },
+     "sponsorable": false,
+     "topics": [],
+     "type": "Public",
+     "help_wanted_issues_count": 0,
+     "good_first_issue_issues_count": 0,
+     "starred_by_current_user": false
+    },
+    {
+     "id": "140165530",
+     "archived": false,
+     "color": "#41b883",
+     "followers": 327,
+     "has_funding_file": false,
+     "hl_name": "muzishuiji/vue-ins-progress-bar",
+     "hl_trunc_description": "Rainbow progress bar Vue component in instagram style 🌈 Instagram 风格的 Vue <em>彩</em><em>虹</em>进度条组件 ",
+     "language": "Vue",
+     "mirror": false,
+     "owned_by_organization": false,
+     "public": true,
+     "repo": {
+      "repository": {
+       "id": 140165530,
+       "name": "vue-ins-progress-bar",
+       "owner_id": 18276045,
+       "owner_login": "muzishuiji",
+       "updated_at": "2024-12-07T14:24:12.465Z",
+       "has_issues": true
+      }
+     },
+     "sponsorable": false,
+     "topics": [
+      "vue"
+     ],
+     "type": "Public",
+     "help_wanted_issues_count": 0,
+     "good_first_issue_issues_count": 1,
+     "starred_by_current_user": false
+    },
+    {
+     "id": "606611916",
+     "archived": false,
+     "color": "#4F5D95",
+     "followers": 312,
+     "has_funding_file": false,
+     "hl_name": "netcccyun/pan",
+     "hl_trunc_description": "<em>彩</em><em>虹</em>外链网盘",
+     "language": "PHP",
+     "mirror": false,
+     "owned_by_organization": false,
+     "public": true,
+     "repo": {
+      "repository": {
+       "id": 606611916,
+       "name": "pan",
+       "owner_id": 8541489,
+       "owner_login": "netcccyun",
+       "updated_at": "2025-04-02T03:31:39.232Z",
+       "has_issues": true
+      }
+     },
+     "sponsorable": false,
+     "topics": [],
+     "type": "Public",
+     "help_wanted_issues_count": 0,
+     "good_first_issue_issues_count": 0,
+     "starred_by_current_user": false
+    }
+   ]
+  }
+ }
+}

+ 41 - 0
数据接口与来源/captures/gzh_account_info.json

@@ -0,0 +1,41 @@
+{
+ "label": "gzh_account_info",
+ "url": "http://crawler.aiddit.com/crawler/wei_xin/account_info",
+ "request_body": {
+  "content_link": "http://mp.weixin.qq.com/s?__biz=MzI5NjAxMTgzNg==&mid=2247483744&idx=1&sn=eb484d234c5579d567c87d9519351b74&chksm=ed2ce2d3b0195928fcde4aedf052e1445c1ecac5ede7b3013ba7d8e103e3175fb50f68649226&scene=7#rd"
+ },
+ "response": {
+  "code": 0,
+  "msg": null,
+  "data": {
+   "has_more": false,
+   "next_cursor": null,
+   "data": {
+    "is_cache": true,
+    "channel": 5,
+    "channel_account_id": "969a9ad954ec605c67110cdb8c42f301",
+    "xhs_id": null,
+    "dy_id": null,
+    "ks_id": null,
+    "digit_id": null,
+    "account_link": "https://mp.weixin.qq.com/mp/profile_ext?action=home&__biz=MzI5NjAxMTgzNg==&scene=124#wechat_redirect",
+    "account_name": "韭菜看透本质",
+    "avatar_url": null,
+    "background_url": null,
+    "gender": "其他",
+    "description": "",
+    "ip_location": null,
+    "tags": null,
+    "follower_count": null,
+    "publish_count": null,
+    "like_count": null,
+    "collect_count": null,
+    "comment_count": null,
+    "looking_count": null,
+    "biz_info": "MzI5NjAxMTgzNg==",
+    "wx_gh": "gh_d6a68990fe9c",
+    "update_timestamp": 1781159104578
+   }
+  }
+ }
+}

File diff ditekan karena terlalu besar
+ 21 - 0
数据接口与来源/captures/gzh_detail.json


+ 178 - 0
数据接口与来源/captures/gzh_search.json

@@ -0,0 +1,178 @@
+{
+ "label": "gzh_search",
+ "url": "http://crawler.aiddit.com/crawler/wei_xin/keyword",
+ "request_body": {
+  "keyword": "彩虹",
+  "cursor": "0"
+ },
+ "response": {
+  "code": 0,
+  "msg": null,
+  "data": {
+   "has_more": true,
+   "next_cursor": "1",
+   "data": [
+    {
+     "title": "<em class=\"highlight\">彩虹</em>股份(600707)深度分析报告",
+     "time": 1781151948,
+     "nick_name": "",
+     "url": "http://mp.weixin.qq.com/s?__biz=MzI5NjAxMTgzNg==&mid=2247483744&idx=1&sn=eb484d234c5579d567c87d9519351b74&chksm=ed2ce2d3b0195928fcde4aedf052e1445c1ecac5ede7b3013ba7d8e103e3175fb50f68649226&scene=7#rd",
+     "cover_url": "https://mmbiz.qpic.cn/mmbiz_jpg/fNx5Iic5WA7X9043u89nrflAaFGGGrgd6YbIHfajKwUDcZ27KLYclBKMglMTCibHibtcOloGMzibvSPOk00tricExZxhLzQDibib3KXt5WIvqQDpwo/0?wx_fmt=jpeg",
+     "biz": ""
+    },
+    {
+     "title": "今天的<em class=\"highlight\">彩虹</em>你看见了吗?",
+     "time": 1780837538,
+     "nick_name": "",
+     "url": "http://mp.weixin.qq.com/s?__biz=MzAxNDQ2MzYxOQ==&mid=2247487096&idx=1&sn=f23530c91fb49a819e31d98fc9108cfd&chksm=9a1c96844a112c606265085fc56251131086812380883fffc2baf756a6b85ecd16ac8b604c93&scene=7#rd",
+     "cover_url": "https://mmbiz.qpic.cn/sz_mmbiz_jpg/gNycRvkwy1Pvtg5mEdbWDuvAE57ncdCEhH5GiaHJsGJEzohljHiafh0eC4M1mqxkjmenoiayQibbjfVhib9LQgnI24T3b0WY28tQVmHibHugcTYicE/0?wx_fmt=jpeg",
+     "biz": ""
+    },
+    {
+     "title": "分享朋友圈<em class=\"highlight\">彩虹</em>",
+     "time": 1780571083,
+     "nick_name": "",
+     "url": "http://mp.weixin.qq.com/s?__biz=Mzk2NDQ1MjA0NA==&mid=2247488081&idx=1&sn=5d75a7241b9276142a9b505474718dec&chksm=c598da5c12e7af8407157dd65d70bdc253686ebacfd6547fbbb421eeca0e38c579bc6f04f16b&scene=7#rd",
+     "cover_url": "https://mmbiz.qpic.cn/sz_mmbiz_jpg/CM1b4m16ibKRSWBwEQW6YGfn8L8nMMhNkfoUwh5qgMjHTDtBXQktoskA6CDy2ic1uQp6ib3TX2qnNwt7jGTY6cosBlCK7AWibQWpP3xXsEnjS3I/0?wx_fmt=jpeg",
+     "biz": ""
+    },
+    {
+     "title": "天津现雨后<em class=\"highlight\">彩虹</em>",
+     "time": 1780564075,
+     "nick_name": "",
+     "url": "http://mp.weixin.qq.com/s?__biz=MjM5MzEzNDUwNQ==&mid=2652435057&idx=2&sn=6520d1faa1618c648a0092e924ca57db&chksm=bc0e7b48f66b953589d4e3979a434de6a4e5f48f08aa7f815f5a47f5b8e4786e1843e479cb28&scene=7#rd",
+     "cover_url": "https://mmbiz.qpic.cn/sz_mmbiz_jpg/zbI2Sn1QlriaLe36TgJZVibpjEtlEW3yQibP13xvMGyEz78RvBmoxlwq2gdACTJtcwVkqlsOWyXRFssiagqRKeWB0ONOUed62opFsCuqNcbnQok/0?wx_fmt=jpeg",
+     "biz": ""
+    },
+    {
+     "title": "美丽<em class=\"highlight\">彩虹</em>",
+     "time": 1778169660,
+     "nick_name": "",
+     "url": "http://mp.weixin.qq.com/s?__biz=MzI2NzM2NDIxOQ==&mid=2248654489&idx=5&sn=20a15df91eddf4082eaeacb242d8b25e&chksm=e86055c271073d5e359638ccc6f7b2a4197faaaa0a40a0f83ea834e4ef512ad6ed6e026d24c1&scene=7#rd",
+     "cover_url": "https://mmbiz.qpic.cn/mmbiz_jpg/qnmVSt9z8iaicg4OUZEQp1aDxDx6IjerxGvInr5nuF0utbtOuMKdRqpXHWagqFoapfFYEcXNjkApkK15fWjI5JeSgBsUf3s1wkI7VPpJ5SBJI/0?wx_fmt=jpeg",
+     "biz": ""
+    },
+    {
+     "title": "周杰伦《<em class=\"highlight\">彩虹</em>》",
+     "time": 1766842980,
+     "nick_name": "",
+     "url": "http://mp.weixin.qq.com/s?__biz=MzIwMTY0MDU1OQ==&mid=2654288288&idx=1&sn=256a81ba0ce24b354016f0fb494a9f57&chksm=8c3ff79f74bbed02f2a0b2262dfaaf4fb60b92abc5287e99f676c261a40d27bb4496a8887b80&scene=7#rd",
+     "cover_url": "https://mmbiz.qpic.cn/sz_mmbiz_jpg/UCExwmpFJSzrQUV1vZKkH8icr1mTwwKmStjovqIpSWcdYibc8iag7iczV9dEh8d2KCESNaHl3ZdnMCPyuF01OKpEuQ/0?wx_fmt=jpeg",
+     "biz": ""
+    },
+    {
+     "title": "能带来好运的<em class=\"highlight\">彩虹</em>壁纸",
+     "time": 1775688960,
+     "nick_name": "",
+     "url": "http://mp.weixin.qq.com/s?__biz=MzU3MTU3ODUzOA==&mid=2247497251&idx=1&sn=4bbc32d65f5a856de167ae045531fb5b&chksm=fd701af3b1af544a1c27c5f36492a6334c5600ec67185a42f88552b4e97a035b67ac820305d0&scene=7#rd",
+     "cover_url": "https://mmbiz.qpic.cn/mmbiz_jpg/P3Y2XzYrMFHGo3J589BgabetTch1ZthUGwUibVw40moRibgicUXSXFyEOtPCkXIlr2NT4eXY3uW3ibU8vEaKxAPB2CE8NXVCjbGntehJ9NdRg6g/0?wx_fmt=jpeg",
+     "biz": ""
+    },
+    {
+     "title": "大美<em class=\"highlight\">彩虹</em>",
+     "time": 1774713660,
+     "nick_name": "",
+     "url": "http://mp.weixin.qq.com/s?__biz=MzI2NzM2NDIxOQ==&mid=2248637080&idx=7&sn=6990796d8035c32a5756a903d4cc5cc3&chksm=e890885abec490c9df094ce1034fe64e839353a386f6399653e46dd953524b4f15d6270fe050&scene=7#rd",
+     "cover_url": "https://mmbiz.qpic.cn/sz_mmbiz_jpg/qnmVSt9z8iaicibnKP2RtiaMJVcxrGMyE76uCKTEMImWicLPXxVnR5Avcamflu2RzcRFhNWnKJXARzZDbdV7IaPccgJdSCh2Er9RIibKgEVkIgra8/0?wx_fmt=jpeg",
+     "biz": ""
+    },
+    {
+     "title": "教学设计| 王林慧:架想象之桥    品童真之美——《<em class=\"highlight\">彩虹</em>》教学设计",
+     "time": 1768950000,
+     "nick_name": "",
+     "url": "http://mp.weixin.qq.com/s?__biz=MzI0MjQzNzA2Ng==&mid=2247484688&idx=4&sn=67cb012379c38e5b470701ad519d1440&chksm=e8072b871a26a853c80e2d8a1ac12466f4a35e84f544d5485575faad4a0efdea8f584e345508&scene=7#rd",
+     "cover_url": "https://mmbiz.qpic.cn/mmbiz_jpg/Tic9PDuPnb9Fia5RMvawuNpZia2W3XOcicc7bt2o3nOgs5qdd7NxX24PZpHGiatABdUqdsR4IXIucBO25Y1icyBjwTzQ/0?wx_fmt=jpeg",
+     "biz": ""
+    },
+    {
+     "title": "统编版语文二年级上册第4课《<em class=\"highlight\">彩虹</em>》同步课堂",
+     "time": 1758974295,
+     "nick_name": "",
+     "url": "http://mp.weixin.qq.com/s?__biz=MzIwNDIzOTMxMw==&mid=2657483118&idx=1&sn=5c7809043d61fce6963d2a78c39f1911&chksm=8c8667b4822de1490ec6f096be70a8ac6ad0c232223c249ee640ba341022c7a06053f3f4faf5&scene=7#rd",
+     "cover_url": "https://mmbiz.qpic.cn/mmbiz_jpg/YOfpltPx2hnNpdTAtgAmUj3QJZnoGNxjTmRjFU3twZXcIMJ3Ggp8QoaibYt9NM4xeE7ictmibkRRnTibV7b8mBHxnQ/0?wx_fmt=jpeg",
+     "biz": ""
+    },
+    {
+     "title": "一年级语文下册《<em class=\"highlight\">彩虹</em>》课堂笔记",
+     "time": 1778143753,
+     "nick_name": "",
+     "url": "http://mp.weixin.qq.com/s?__biz=MzkzNDY5MTE2NQ==&mid=2247520059&idx=1&sn=7027a95dd8da2bed521fb16783f871b4&chksm=c3f7537dde1b3ced75b261cabf2241015268d352b0bc37991b40f601d9f2b2b05222dd0bc44a&scene=7#rd",
+     "cover_url": "https://mmbiz.qpic.cn/sz_mmbiz_jpg/sUCPYialq9iaICXdxS8eUAAOyshlk88fRT4kJ2dzOZ2yAB4WcXOaMPWojib1FfrdlSsicUIic62xFunTIdqDQ1GVHtY9nMLSe5ZEu3VKEiabDgjgI/0?wx_fmt=jpeg",
+     "biz": ""
+    },
+    {
+     "title": "《<em class=\"highlight\">彩虹</em>》-许巍、叶蓓",
+     "time": 1777991400,
+     "nick_name": "",
+     "url": "http://mp.weixin.qq.com/s?__biz=MzUyMjkwMjAwNw==&mid=2247486511&idx=1&sn=ceb334c800674bc3beafb50aea620a28&chksm=f862979a12807802ca1cc461ceb7b4de4cf614f1f837ba2c287b97bdfc19b64d38e4de1a09d5&scene=7#rd",
+     "cover_url": "http://mmbiz.qpic.cn/sz_mmbiz_jpg/jGYas3UiauzvrZ4QMuIPjq70qNHjfb4AEibPR1ULvkvlM4ykibJMASYnaZyKEJicDSHUrejVibZdXdH3wT0siaeThmjl1Vp4pDAF9IEY9bFjrylAk/0?wx_fmt=jpeg",
+     "biz": ""
+    },
+    {
+     "title": "<em class=\"highlight\">彩虹</em>是怎么形成的?",
+     "time": 1777193081,
+     "nick_name": "",
+     "url": "http://mp.weixin.qq.com/s?__biz=MzkyMjUyNjEyMw==&mid=2247488856&idx=4&sn=347851f5b79f7831a8d8be63a4c3a02f&chksm=c020ac31f2282c0200c1e39f02f2b9fc496af9d1890666abd672cc0a972040cb5f877d396b39&scene=7#rd",
+     "cover_url": "http://mmecoa.qpic.cn/sz_mmecoa_jpg/EF8Uib1pY7zCyYDxeT53c0chySv4kSicjQ9ak80cmucBNoXxyzBJibJuatNpudHaovyGAlkUqsxDia44dTwrIdtK0MzugPkeDictJY3upQvWK53c/0?wx_fmt=jpeg",
+     "biz": ""
+    },
+    {
+     "title": "每日科普——<em class=\"highlight\">彩虹</em>",
+     "time": 1776147709,
+     "nick_name": "",
+     "url": "http://mp.weixin.qq.com/s?__biz=MjM5MTY2Mzc5NQ==&mid=2655052085&idx=5&sn=160e24cf8ac6f50daede77ce69a3dac8&chksm=bccd846baca299b60318b18b0c475a51d91495f4d73b4c2c8100caacda2239bd51f2728bf368&scene=7#rd",
+     "cover_url": "https://mmbiz.qpic.cn/sz_mmbiz_jpg/H5VuEyD3iaOsSglTo7pFCfqyy2S0qticWwXSWZZEicWvGSaxaMdA32ibJqYItmaZiczf6D3RNuJhBiaYoFJ4L4awD2fCZgbJkJcWE9laYpga6avfM/0?wx_fmt=jpeg",
+     "biz": ""
+    },
+    {
+     "title": "别被眼睛骗了!<em class=\"highlight\">彩虹</em>其实是个完整的“大圆圈”",
+     "time": 1770620099,
+     "nick_name": "",
+     "url": "http://mp.weixin.qq.com/s?__biz=MzU0Nzc2NjQ4MA==&mid=2247496681&idx=2&sn=a6d7a425f628c6fa2ca7a05ed9958d2d&chksm=fa228f2292186ba229d4754f3fa7a1880cf1499a02e8b1ff8bea19669ac96da698edcf4f2871&scene=7#rd",
+     "cover_url": "https://mmbiz.qpic.cn/sz_mmbiz_jpg/GRW5XwVJKf1zTicfUnWYqwjKTD9j2pHRiaibiaWH6RyiaiaZNdOg7nSe9ukN9niazkhg0RiaxjOthEoMO4hl8Eh4QHUCv8Vldwe1IvibrKRhkLdVafWM/0?wx_fmt=jpeg",
+     "biz": ""
+    },
+    {
+     "title": "周杰伦《<em class=\"highlight\">彩虹</em>》歌词",
+     "time": 1780963329,
+     "nick_name": "",
+     "url": "http://mp.weixin.qq.com/s?__biz=Mzk2NDU5MzgyOA==&mid=2247483800&idx=1&sn=f8b48081945e65f2d56ef3837d5a9ed2&chksm=c5835cfdd776fa2a80e42a159c21d0f0caaccbf4ee30c33b10b095437a935d43fcc0be8978ca&scene=7#rd",
+     "cover_url": "https://mmbiz.qpic.cn/mmbiz_jpg/XXs5Px495ZaALPuw3MiaCsyFqwZKREjVmdnFGMOv87eSUFMK7ibvZJ7icsC1QySYXnol5lNfVog2l2iahR7zeVicDtEALWCAXQASTq4ry1M9Uru8/0?wx_fmt=jpeg",
+     "biz": ""
+    },
+    {
+     "title": "<em class=\"highlight\">彩虹</em> / 叶蓓",
+     "time": 1776520800,
+     "nick_name": "",
+     "url": "http://mp.weixin.qq.com/s?__biz=MzYyNTU2NTA5Mw==&mid=2247512088&idx=1&sn=3a35079b3518a6bc3043c2b13f0ec0be&chksm=f19d4370ea819aca04bf696dd7788fcbde0b5d6551aedfca013332d68f796317c07aad36c402&scene=7#rd",
+     "cover_url": "https://mmbiz.qpic.cn/sz_mmbiz_jpg/uZ8MJhLQNz30QAhib243ykFPJibxz5Y3Jp8HItFcIL4Rp5riaVepXvx4vE6iaiazewrXTlZd2ZyDQZt4aaEaIcJUG9dTicAju56T8fhcdqCKRmb6M/0?wx_fmt=jpeg",
+     "biz": ""
+    },
+    {
+     "title": "生活物理丨<em class=\"highlight\">彩虹</em>为什么是弯的?这是怎么形成的呢",
+     "time": 1780318851,
+     "nick_name": "",
+     "url": "http://mp.weixin.qq.com/s?__biz=MzkzNzgxNzEzMQ==&mid=2247500424&idx=2&sn=31fdba00d47503188d52237d3fc2347f&chksm=c31653766d8c48178f008fdb66ebf15396e607c004dbaab30efbfe332247c838744b50e2ae86&scene=7#rd",
+     "cover_url": "http://mmecoa.qpic.cn/sz_mmecoa_jpg/yiaevUphaCmj0VSjRc0teBzfnIogUIcrzvcNicRRB7g91YKfciaAEthKu0CxcymBhiaxLia9pibperXicuPKt2UicgsXFmN89tGiapOxNhcDWXrypghU/0?wx_fmt=jpeg",
+     "biz": ""
+    },
+    {
+     "title": "【小学语文】32-课文《<em class=\"highlight\">彩虹</em>》",
+     "time": 1774927800,
+     "nick_name": "",
+     "url": "http://mp.weixin.qq.com/s?__biz=MzI1NzQ2Nzk0MA==&mid=2247487105&idx=1&sn=560d19a77d8480aa2729a5475afb3699&chksm=eb7c81f7f7bca1c347f4bb9d81f1e109c9166f87225d2eb8582c43b51f619058aa41e0f834cb&scene=7#rd",
+     "cover_url": "https://mmbiz.qpic.cn/mmbiz_jpg/11P2x2waFsNa1VnYAqpMPWNOxSEDSDLYcB1sp2ZgZQichQxLXuHVJn1nJltGIj7icGJpssB3pWxmc1Eu6nWVn1hOsLuInQCJhO5Md2zmKA0DA/0?wx_fmt=jpeg",
+     "biz": ""
+    },
+    {
+     "title": "5月2日,52位摄影师拍摄北京<em class=\"highlight\">彩虹</em>,惊艳全城!",
+     "time": 1777730263,
+     "nick_name": "",
+     "url": "http://mp.weixin.qq.com/s?__biz=MzA3NjE4MTA3Nw==&mid=2651731364&idx=1&sn=1a1f4bd1b34ee10a0bd3004b151931ea&chksm=85c17d6bfc749bace4093ab5104fc151a7f6b36232569eb599e91b321e9c09581b3204ac1404&scene=7#rd",
+     "cover_url": "https://mmbiz.qpic.cn/mmbiz_jpg/Wo0Lwcudtzj0oBkRMib4LCBby43NaZ3DViawVGOHwFEuV6Qeo0uBZkPiaAp32bByOlZ1XST2vibWhbhgMeUnDDkeNDdic0EibuqKRE9CzfOqeuc8I/0?wx_fmt=jpeg",
+     "biz": ""
+    }
+   ]
+  }
+ }
+}

+ 45 - 0
数据接口与来源/captures/kuaishou_account_info.json

@@ -0,0 +1,45 @@
+{
+ "label": "kuaishou_account_info",
+ "url": "http://crawler.aiddit.com/crawler/kuai_shou/account_info",
+ "request_body": {
+  "account_id": "3xfkwajatdh7p7i",
+  "is_cache": true
+ },
+ "response": {
+  "code": 0,
+  "msg": null,
+  "data": {
+   "has_more": false,
+   "next_cursor": null,
+   "data": {
+    "channel": 7,
+    "channel_account_id": "3xfkwajatdh7p7i",
+    "xhs_id": null,
+    "dy_id": null,
+    "ks_id": "1514225378",
+    "digit_id": "1514225378",
+    "account_link": "https://www.kuaishou.com/profile/3xfkwajatdh7p7i",
+    "account_name": "夏若.",
+    "avatar_url": "http://p4.a.yximgs.com/kimg/uhead/AB/2025/09/28/21/CjtCTWpBeU5UQTVNamd5TVRNMU1UUmZNVFV4TkRJeU5UTTNPRjh5WDJoa05qYzVYekUyTUE9PV9iLmpwZxCVzNcv:750x750.heif",
+    "background_url": "http://static.yximgs.com/udata/pkg/KS-PROFILE/BG2.png",
+    "gender": "女",
+    "description": "可以帮我破1000吗\n谢谢🙏\n想要什么随便提(说的是惩罚)\n到了1000不会让你们打卡的\n不要太过分,不要太过分,不要太过分,重要的事情说三遍\n谢谢大家了",
+    "ip_location": null,
+    "tags": [
+     "摩羯座",
+     "贵州 安顺市"
+    ],
+    "follower_count": 511,
+    "publish_count": 184,
+    "like_count": 1598,
+    "collect_count": null,
+    "comment_count": null,
+    "looking_count": null,
+    "biz_info": null,
+    "wx_gh": null,
+    "create_timestamp": null,
+    "update_timestamp": 1781158922013
+   }
+  }
+ }
+}

+ 63 - 0
数据接口与来源/captures/kuaishou_detail.json

@@ -0,0 +1,63 @@
+{
+ "label": "kuaishou_detail",
+ "url": "http://crawler.aiddit.com/crawler/kuai_shou/detail",
+ "request_body": {
+  "content_id": "3xepqgwddgbickc"
+ },
+ "response": {
+  "code": 0,
+  "msg": null,
+  "data": {
+   "has_more": false,
+   "next_cursor": null,
+   "data": {
+    "channel": 7,
+    "channel_content_id": "3xepqgwddgbickc",
+    "content_link": "https://www.gifshow.com/fw/photo/3xepqgwddgbickc",
+    "wx_sn": null,
+    "title": null,
+    "content_type": "video",
+    "body_text": null,
+    "location": null,
+    "source_url": null,
+    "mini_program": null,
+    "topic_list": null,
+    "image_url_list": [
+     {
+      "image_type": 2,
+      "image_url": "http://hw2.a.kwimgs.com/upic/2025/05/11/07/BMjAyNTA1MTEwNzIxNDFfMTUxNDIyNTM3OF8xNjM5NzU2OTQ5NjhfMl8z_540p_B93922096ede56255be2e8b1daac210ef.kvif?tag=1-1781158904-sp-0-hwt9l25a94-beb401816b64f0a1&clientCacheKey=3xepqgwddgbickc_540p.kvif&di=75adb03e&bp=10321"
+     }
+    ],
+    "video_url_list": [
+     {
+      "video_url": "http://v4.kwaicdn.com/ksc1/IZkU_mTcl1TyjALwItfi6aGOlAoQKFhVh5D0rjX3J-p_QKl7S8GRJkxrVAcc09vw1EJM6W9sOMuCbziZpZponbIZMv9E2PHW_QgI8wMvAxynhsmN7euTZ3dSewezH_VI-CDI5jNoHM4_3t3i0wsmh4qq9pHoUTR8BgmEIid2FqE1Z7hBwIu0iQ1gabOkE4Mg.mp4?pkey=AAWiyDHhYJyag1LX3LHOrvdyVKS2pRAKPvrmTEkvLVY_vRKFVcXqiGNHs8rbfXmCbX3y2h1UIc60nVycHLDCgGC2VDpFyI6GqXmICa5hwrz-mKmrNB711f8vMxFsi-apGFM&tag=1-1781158904-sp-0-6r6ktwphci-fe3294ac783529d6&clientCacheKey=3xepqgwddgbickc_b.mp4&tt=b&di=75adb03e&bp=10321",
+      "video_duration": 4
+     }
+    ],
+    "bgm_data": {
+     "id_str": "5xhvzawmfe67bpu",
+     "title": "没去学校(DJ版)",
+     "author": "kiss",
+     "duration": 60,
+     "play_url": "https://v4-plat-fdl.wsukwai.com/ksc2/4_w7QPLfc5ml_HTfSjAXGxPAjyoqZdXLS1o5xYQwN9zH6503HOa3pkPFbnW8_x3_ZujoILnExA4oWQUa_95KyQ.m4a?pkey=AAWeMBTBhoC6-9Fva-wlCN3pNjp_-C5Npy_AMgGv7SKNNhdmk66t4uInoBQ1_dwJQZS9CqFCqsQUEOlvBZPhUJP4sxAsEyDD0fcVCUo-X38PAIQSCIWyo0wjeZcLlHyZZyw"
+    },
+    "ad_info": null,
+    "voice_data": null,
+    "channel_account_id": "3xfkwajatdh7p7i",
+    "channel_account_name": "夏若.",
+    "avatar": "http://p4.a.yximgs.com/kimg/uhead/AB/2025/09/28/21/CjtCTWpBeU5UQTVNamd5TVRNMU1UUmZNVFV4TkRJeU5UTTNPRjh5WDJoa05qYzVYekUyTUE9PV9zLmpwZxCVzNcv:200x200.heif",
+    "item_index": null,
+    "view_count": 18472,
+    "play_count": null,
+    "like_count": 75,
+    "collect_count": 4,
+    "comment_count": 0,
+    "share_count": 7,
+    "looking_count": null,
+    "publish_timestamp": 1746919311784,
+    "modify_timestamp": null,
+    "update_timestamp": 1781158904642
+   }
+  }
+ }
+}

+ 431 - 0
数据接口与来源/captures/kuaishou_search.json

@@ -0,0 +1,431 @@
+{
+ "label": "kuaishou_search",
+ "url": "http://crawler.aiddit.com/crawler/kuai_shou/keyword_v2",
+ "request_body": {
+  "keyword": "彩虹"
+ },
+ "response": {
+  "code": 0,
+  "msg": null,
+  "data": {
+   "has_more": false,
+   "next_cursor": null,
+   "data": [
+    {
+     "is_cache": true,
+     "channel": 7,
+     "channel_content_id": "3xepqgwddgbickc",
+     "content_link": "https://www.gifshow.com/fw/photo/3xepqgwddgbickc",
+     "wx_sn": null,
+     "biz_info": null,
+     "title": null,
+     "content_type": "video",
+     "body_text": null,
+     "location": null,
+     "source_url": null,
+     "mini_program": null,
+     "topic_list": null,
+     "image_url_list": [
+      {
+       "image_type": 2,
+       "image_url": "http://p66-plat.wsukwai.com/upic/2025/05/11/07/BMjAyNTA1MTEwNzIxNDFfMTUxNDIyNTM3OF8xNjM5NzU2OTQ5NjhfMl8z_540p_B93922096ede56255be2e8b1daac210ef.kvif?tag=1-1781158885-scn-0-bgbpnbmzdh-5f89b4ce73171169&clientCacheKey=3xepqgwddgbickc_540p.kvif&di=793d10d8&bp=10121"
+      }
+     ],
+     "video_url_list": [
+      {
+       "video_url": "http://v23-3.kwaicdn.com/upic/2025/05/11/07/BMjAyNTA1MTEwNzIxNDFfMTUxNDIyNTM3OF8xNjM5NzU2OTQ5NjhfMl8z_b_Bc26646b09047086e801f9e70c7b89c3f.mp4?pkey=AAWWYEc_X3fwwG9CFF05dH5oeA679OXHU7HSVUGJBOlKOYjZ0eyggmwGcHm8M-vG5wYJ48KtGrnwGvaVpN1gE4Kleg4oWF1O6KUrOaJq0UgsCnbIAgyRxBAjq2S4MgOVIcM&tag=1-1781158885-scn-0-gj3t7pnzpn-2dbf9439a1274fbd&clientCacheKey=3xepqgwddgbickc_b.mp4&tt=b&di=793d10d8&bp=10121",
+       "video_duration": 4
+      }
+     ],
+     "multi_bitrate": null,
+     "bgm_data": null,
+     "ad_info": null,
+     "is_original": false,
+     "voice_data": null,
+     "channel_account_id": "3xfkwajatdh7p7i",
+     "channel_account_name": "夏若.",
+     "channel_account_avatar": null,
+     "item_index": null,
+     "view_count": 18472,
+     "play_count": null,
+     "like_count": 75,
+     "collect_count": 4,
+     "comment_count": 0,
+     "share_count": 0,
+     "looking_count": null,
+     "publish_timestamp": 1746919311784,
+     "modify_timestamp": null,
+     "update_timestamp": 1781158886313
+    },
+    {
+     "is_cache": true,
+     "channel": 7,
+     "channel_content_id": "3xqh5v5vzup7cum",
+     "content_link": "https://www.gifshow.com/fw/photo/3xqh5v5vzup7cum",
+     "wx_sn": null,
+     "biz_info": null,
+     "title": "唐山雨后现双彩虹!霞光铺满天边简直太浪漫...",
+     "content_type": "video",
+     "body_text": "唐山雨后现双彩虹!霞光铺满天边简直太浪漫了!",
+     "location": null,
+     "source_url": null,
+     "mini_program": null,
+     "topic_list": null,
+     "image_url_list": [
+      {
+       "image_type": 2,
+       "image_url": "http://p66-plat.wsukwai.com/upic/2026/06/05/09/BMjAyNjA2MDUwOTUyMDVfMTg0NzM0MjM5N18xOTc5Mjc0NDM0ODNfMl8z_540p_B555a43a4620990adbc3eadc53dff5eab.kvif?tag=1-1781158885-scn-0-5azmwk006k-673fa9be5e5fb249&clientCacheKey=3xqh5v5vzup7cum_540p.kvif&di=793d10d8&bp=10121"
+      }
+     ],
+     "video_url_list": [
+      {
+       "video_url": "http://dxsc.oppass.cn/upic/2026/06/05/09/BMjAyNjA2MDUwOTUyMDVfMTg0NzM0MjM5N18xOTc5Mjc0NDM0ODNfMl8z_b_Bc937900e5e9479eace06071dbb10fb6e.mp4?tag=1-1781158885-scn-0-jf0sohvsrn-5745ba406eeb70e2&clientCacheKey=3xqh5v5vzup7cum_b.mp4&tt=b&di=793d10d8&bp=10121",
+       "video_duration": 6
+      }
+     ],
+     "multi_bitrate": null,
+     "bgm_data": null,
+     "ad_info": null,
+     "is_original": false,
+     "voice_data": null,
+     "channel_account_id": "3x7endxbes4fpxc",
+     "channel_account_name": "山西日报",
+     "channel_account_avatar": null,
+     "item_index": null,
+     "view_count": 5353,
+     "play_count": null,
+     "like_count": 82,
+     "collect_count": 7,
+     "comment_count": 10,
+     "share_count": 0,
+     "looking_count": null,
+     "publish_timestamp": 1780624339308,
+     "modify_timestamp": null,
+     "update_timestamp": 1781158886314
+    },
+    {
+     "is_cache": true,
+     "channel": 7,
+     "channel_content_id": "3x4fmu472v7swte",
+     "content_link": "https://www.gifshow.com/fw/photo/3x4fmu472v7swte",
+     "wx_sn": null,
+     "biz_info": null,
+     "title": "垂柳拂水影,心随波光静 #风雨过后终见彩...",
+     "content_type": "video",
+     "body_text": "垂柳拂水影,心随波光静 #风雨过后终见彩虹 #感受大自然的气息和美景 #雨后彩虹美景",
+     "location": null,
+     "source_url": null,
+     "mini_program": null,
+     "topic_list": null,
+     "image_url_list": [
+      {
+       "image_type": 2,
+       "image_url": "http://p66-plat.wsukwai.com/upic/2026/06/08/18/BMjAyNjA2MDgxODQ5MzVfMjkzNzE0MjQ0XzE5ODI5MjQxNzAxOV8yXzM=_540p_Bfad2665d72e1a431bba275549dcaf9c9.kvif?tag=1-1781158885-scn-0-xi7j5zyyfj-f34532f4760f54a1&clientCacheKey=3x4fmu472v7swte_540p.kvif&di=793d10d8&bp=10121"
+      }
+     ],
+     "video_url_list": [
+      {
+       "video_url": "http://dxsc.oppass.cn/upic/2026/06/08/18/BMjAyNjA2MDgxODQ5MzVfMjkzNzE0MjQ0XzE5ODI5MjQxNzAxOV8yXzM=_b_B350c39ea4e8adb848080f2459dd8c0e3.mp4?tag=1-1781158885-scn-0-wp9vio70u8-02ba2b9ca830b923&clientCacheKey=3x4fmu472v7swte_b.mp4&tt=b&di=793d10d8&bp=10121",
+       "video_duration": 3
+      }
+     ],
+     "multi_bitrate": null,
+     "bgm_data": null,
+     "ad_info": null,
+     "is_original": false,
+     "voice_data": null,
+     "channel_account_id": "3xgnpaez2sxmrs6",
+     "channel_account_name": "不习惯喊痛~",
+     "channel_account_avatar": null,
+     "item_index": null,
+     "view_count": 142,
+     "play_count": null,
+     "like_count": 5,
+     "collect_count": 0,
+     "comment_count": 2,
+     "share_count": 0,
+     "looking_count": null,
+     "publish_timestamp": 1780915788542,
+     "modify_timestamp": null,
+     "update_timestamp": 1781158886314
+    },
+    {
+     "is_cache": true,
+     "channel": 7,
+     "channel_content_id": "3xbxx3ef3x46f5g",
+     "content_link": "https://www.gifshow.com/fw/photo/3xbxx3ef3x46f5g",
+     "wx_sn": null,
+     "biz_info": null,
+     "title": "6月2日(采访),云南,见者好运!网友偶...",
+     "content_type": "video",
+     "body_text": "6月2日(采访),云南,见者好运!网友偶然拍到绝美雨后彩虹,“第一次见到颜色这么明显的彩虹”",
+     "location": null,
+     "source_url": null,
+     "mini_program": null,
+     "topic_list": null,
+     "image_url_list": [
+      {
+       "image_type": 2,
+       "image_url": "http://p66-plat.wsukwai.com/upic/2025/06/02/16/BMjAyNTA2MDIxNjU2MzFfODQyMzA4NzYzXzE2NTg0MDUxNDI1OF8wXzM=_540p_B396aef9ac59899aafcdf0b28f01c4563.kvif?tag=1-1781158885-scn-0-egd6k8gj9y-e8bb677a30a8f5f5&clientCacheKey=3xbxx3ef3x46f5g_540p.kvif&di=793d10d8&bp=10121"
+      }
+     ],
+     "video_url_list": [
+      {
+       "video_url": "http://dxsc.oppass.cn/upic/2025/06/02/16/BMjAyNTA2MDIxNjU2MzFfODQyMzA4NzYzXzE2NTg0MDUxNDI1OF8wXzM=_b_Bade77ffd98fcb265ea625c1d12b13014.mp4?tag=1-1781158885-scn-0-mlpajuqxwo-c1939ef0c6a5cd7b&clientCacheKey=3xbxx3ef3x46f5g_b.mp4&tt=b&di=793d10d8&bp=10121",
+       "video_duration": 7
+      }
+     ],
+     "multi_bitrate": null,
+     "bgm_data": null,
+     "ad_info": null,
+     "is_original": false,
+     "voice_data": null,
+     "channel_account_id": "3xgb6xe5iv7y82k",
+     "channel_account_name": "齐鲁频道",
+     "channel_account_avatar": null,
+     "item_index": null,
+     "view_count": 63863,
+     "play_count": null,
+     "like_count": 752,
+     "collect_count": 132,
+     "comment_count": 62,
+     "share_count": 0,
+     "looking_count": null,
+     "publish_timestamp": 1748854624353,
+     "modify_timestamp": null,
+     "update_timestamp": 1781158886314
+    },
+    {
+     "is_cache": true,
+     "channel": 7,
+     "channel_content_id": "3x2jarat8j2mxxy",
+     "content_link": "https://www.gifshow.com/fw/photo/3x2jarat8j2mxxy",
+     "wx_sn": null,
+     "biz_info": null,
+     "title": "都说大雨过后会有彩虹 但是没有人提及过它...",
+     "content_type": "video",
+     "body_text": "都说大雨过后会有彩虹 但是没有人提及过它是转瞬即逝的  #生活 #衣服 #手机 #真实生活",
+     "location": null,
+     "source_url": null,
+     "mini_program": null,
+     "topic_list": null,
+     "image_url_list": [
+      {
+       "image_type": 2,
+       "image_url": "http://p66-plat.wsukwai.com/upic/2025/11/20/17/BMjAyNTExMjAxNzIwMzBfMTQ0ODk3MzIyOV8xODAzNDk4OTA5MDFfMV8z_540p_Be08089ed8bdc33477898c4f344c88089.kvif?tag=1-1781158885-scn-0-it69vccy2i-e19e57264b366e49&clientCacheKey=3x2jarat8j2mxxy_540p.kvif&di=793d10d8&bp=10121"
+      }
+     ],
+     "video_url_list": [
+      {
+       "video_url": "http://tymov-s.a.kwimgs.com/upic/2025/11/20/17/BMjAyNTExMjAxNzIwMzBfMTQ0ODk3MzIyOV8xODAzNDk4OTA5MDFfMV8z_b_B683744ed0709a92f1ec75649a5d489ed.mp4?tag=1-1781158885-scn-0-j7u3punk0l-f488d2b60cbb66be&clientCacheKey=3x2jarat8j2mxxy_b.mp4&tt=b&di=793d10d8&bp=10121",
+       "video_duration": 4
+      }
+     ],
+     "multi_bitrate": null,
+     "bgm_data": null,
+     "ad_info": null,
+     "is_original": false,
+     "voice_data": null,
+     "channel_account_id": "3xz4jbvexeci3vk",
+     "channel_account_name": "米心",
+     "channel_account_avatar": null,
+     "item_index": null,
+     "view_count": 14419,
+     "play_count": null,
+     "like_count": 475,
+     "collect_count": 23,
+     "comment_count": 35,
+     "share_count": 0,
+     "looking_count": null,
+     "publish_timestamp": 1763630443466,
+     "modify_timestamp": null,
+     "update_timestamp": 1781158886314
+    },
+    {
+     "is_cache": true,
+     "channel": 7,
+     "channel_content_id": "3xx7gyypkaf9fni",
+     "content_link": "https://www.gifshow.com/fw/photo/3xx7gyypkaf9fni",
+     "wx_sn": null,
+     "biz_info": null,
+     "title": "太原雨后迎来绝美彩虹,霞光横跨楼宇氛围感...",
+     "content_type": "video",
+     "body_text": "太原雨后迎来绝美彩虹,霞光横跨楼宇氛围感拉满 #太原彩虹",
+     "location": null,
+     "source_url": null,
+     "mini_program": null,
+     "topic_list": null,
+     "image_url_list": [
+      {
+       "image_type": 2,
+       "image_url": "http://p66-plat.wsukwai.com/upic/2026/06/09/09/BMjAyNjA2MDkwOTQ4MzBfMTg0NzM0MjM5N18xOTgzMzg1NzgzNThfMF8z_540p_Bec3be86320c2d528db869821a92d9b93.kvif?tag=1-1781158885-scn-0-umvg2pqdoj-233023599de38f1f&clientCacheKey=3xx7gyypkaf9fni_540p.kvif&di=793d10d8&bp=10121"
+      }
+     ],
+     "video_url_list": [
+      {
+       "video_url": "http://dxsc.oppass.cn/upic/2026/06/09/09/BMjAyNjA2MDkwOTQ4MzBfMTg0NzM0MjM5N18xOTgzMzg1NzgzNThfMF8z_b_B20c90c757a595969f0397ce1ee7fa694.mp4?tag=1-1781158885-scn-0-ijkobvaeoh-f47c1ad9a2976730&clientCacheKey=3xx7gyypkaf9fni_b.mp4&tt=b&di=793d10d8&bp=10121",
+       "video_duration": 5
+      }
+     ],
+     "multi_bitrate": null,
+     "bgm_data": null,
+     "ad_info": null,
+     "is_original": false,
+     "voice_data": null,
+     "channel_account_id": "3x7endxbes4fpxc",
+     "channel_account_name": "山西日报",
+     "channel_account_avatar": null,
+     "item_index": null,
+     "view_count": 1738,
+     "play_count": null,
+     "like_count": 22,
+     "collect_count": 2,
+     "comment_count": 2,
+     "share_count": 0,
+     "looking_count": null,
+     "publish_timestamp": 1780969744200,
+     "modify_timestamp": null,
+     "update_timestamp": 1781158886314
+    },
+    {
+     "is_cache": true,
+     "channel": 7,
+     "channel_content_id": "3x7ny26rvxyifqy",
+     "content_link": "https://www.gifshow.com/fw/photo/3x7ny26rvxyifqy",
+     "wx_sn": null,
+     "biz_info": null,
+     "title": "手腕上的这根绳超美,看看这场景 #手链 ...",
+     "content_type": "video",
+     "body_text": "手腕上的这根绳超美,看看这场景 #手链 #手控",
+     "location": null,
+     "source_url": null,
+     "mini_program": null,
+     "topic_list": null,
+     "image_url_list": [
+      {
+       "image_type": 2,
+       "image_url": "http://p66-plat.wsukwai.com/upic/2026/02/03/22/BMjAyNjAyMDMyMjA0MzlfNTk1NTU2MjE0XzE4Njc2NjIxMDEyOV8xXzM=_540p_Bd8a1aad045b0dfd67ed3fbd8561a3fe0.kvif?tag=1-1781158885-scn-0-libjl10wxa-85f32c726735af12&clientCacheKey=3x7ny26rvxyifqy_540p.kvif&di=793d10d8&bp=10121"
+      }
+     ],
+     "video_url_list": [
+      {
+       "video_url": "http://ucmov.a.kwimgs.com/upic/2026/02/03/22/BMjAyNjAyMDMyMjA0MzlfNTk1NTU2MjE0XzE4Njc2NjIxMDEyOV8xXzM=_b_B723046d933b01c6d2032638c1127be58.mp4?tag=1-1781158885-scn-0-os2g3h8p3x-400b7de1a66c1d39&clientCacheKey=3x7ny26rvxyifqy_b.mp4&tt=b&di=793d10d8&bp=10121",
+       "video_duration": 9
+      }
+     ],
+     "multi_bitrate": null,
+     "bgm_data": null,
+     "ad_info": null,
+     "is_original": false,
+     "voice_data": null,
+     "channel_account_id": "3xv4gfyemvru92s",
+     "channel_account_name": "梁小明",
+     "channel_account_avatar": null,
+     "item_index": null,
+     "view_count": 91371,
+     "play_count": null,
+     "like_count": 509,
+     "collect_count": 128,
+     "comment_count": 82,
+     "share_count": 0,
+     "looking_count": null,
+     "publish_timestamp": 1770127496366,
+     "modify_timestamp": null,
+     "update_timestamp": 1781158886314
+    },
+    {
+     "is_cache": true,
+     "channel": 7,
+     "channel_content_id": "3xrd3qathbi5i4k",
+     "content_link": "https://www.gifshow.com/fw/photo/3xrd3qathbi5i4k",
+     "wx_sn": null,
+     "biz_info": null,
+     "title": "#深夜里的我 #一个人的夜晚 #深夜的孤...",
+     "content_type": "video",
+     "body_text": "#深夜里的我 #一个人的夜晚 #深夜的孤独",
+     "location": null,
+     "source_url": null,
+     "mini_program": null,
+     "topic_list": null,
+     "image_url_list": [
+      {
+       "image_type": 2,
+       "image_url": "http://p66-plat.wsukwai.com/upic/2025/06/22/07/BMjAyNTA2MjIwNzI4NDJfMTk0NTU3OTA5N18xNjc0MjgwMjM4MTRfMl8z_540p_B3b5a7e30ad445048dfdea250c350c5c3.kvif?tag=1-1781158885-scn-0-zf1q1sbbjq-3c0ffdad69e1038b&clientCacheKey=3xrd3qathbi5i4k_540p.kvif&di=793d10d8&bp=10121"
+      }
+     ],
+     "video_url_list": [
+      {
+       "video_url": "http://ucmov.a.kwimgs.com/upic/2025/06/22/07/BMjAyNTA2MjIwNzI4NDJfMTk0NTU3OTA5N18xNjc0MjgwMjM4MTRfMl8z_b_Bb27523a2fe34899b62a25792df6b899a.mp4?tag=1-1781158885-scn-0-gaetwbsnnf-32a7a5f9ba00988b&clientCacheKey=3xrd3qathbi5i4k_b.mp4&tt=b&di=793d10d8&bp=10121",
+       "video_duration": 4
+      }
+     ],
+     "multi_bitrate": null,
+     "bgm_data": null,
+     "ad_info": null,
+     "is_original": false,
+     "voice_data": null,
+     "channel_account_id": "3x5dp9pf269swna",
+     "channel_account_name": "彩虹",
+     "channel_account_avatar": null,
+     "item_index": null,
+     "view_count": 391,
+     "play_count": null,
+     "like_count": 11,
+     "collect_count": 0,
+     "comment_count": 1,
+     "share_count": 0,
+     "looking_count": null,
+     "publish_timestamp": 1750548535597,
+     "modify_timestamp": null,
+     "update_timestamp": 1781158886314
+    },
+    {
+     "is_cache": true,
+     "channel": 7,
+     "channel_content_id": "3xjq5hjq36zveza",
+     "content_link": "https://www.gifshow.com/fw/photo/3xjq5hjq36zveza",
+     "wx_sn": null,
+     "biz_info": null,
+     "title": null,
+     "content_type": "video",
+     "body_text": null,
+     "location": null,
+     "source_url": null,
+     "mini_program": null,
+     "topic_list": null,
+     "image_url_list": [
+      {
+       "image_type": 2,
+       "image_url": "http://p66-plat.wsukwai.com/upic/2025/05/06/18/BMjAyNTA1MDYxODMwMTBfMTIwNzQ0Nzk3OV8xNjM2MjA4NzQyMzlfMl8z_540p_B067ab3a7e4e64003c4e8339976bf9959.kvif?tag=1-1781158885-scn-0-v9mm2pqizm-cb918780805d6e67&clientCacheKey=3xjq5hjq36zveza_540p.kvif&di=793d10d8&bp=10121"
+      }
+     ],
+     "video_url_list": [
+      {
+       "video_url": "http://dxsc.oppass.cn/upic/2025/05/06/18/BMjAyNTA1MDYxODMwMTBfMTIwNzQ0Nzk3OV8xNjM2MjA4NzQyMzlfMl8z_b_Beb21ca95b333a6ad70000a7ca3d5fb5b.mp4?tag=1-1781158885-scn-0-uo20oo0oz8-a36b58fa777a2134&clientCacheKey=3xjq5hjq36zveza_b.mp4&tt=b&di=793d10d8&bp=10121",
+       "video_duration": 3
+      }
+     ],
+     "multi_bitrate": null,
+     "bgm_data": null,
+     "ad_info": null,
+     "is_original": false,
+     "voice_data": null,
+     "channel_account_id": "3xsfvkhv9deukq9",
+     "channel_account_name": "宾县吴老二",
+     "channel_account_avatar": null,
+     "item_index": null,
+     "view_count": 15509,
+     "play_count": null,
+     "like_count": 91,
+     "collect_count": 7,
+     "comment_count": 24,
+     "share_count": 0,
+     "looking_count": null,
+     "publish_timestamp": 1746527420449,
+     "modify_timestamp": null,
+     "update_timestamp": 1781158886314
+    }
+   ]
+  }
+ }
+}

+ 10 - 0
数据接口与来源/captures/kuaishou_video_dl.json

@@ -0,0 +1,10 @@
+{
+ "label": "kuaishou_video_dl",
+ "url": "http://v23-3.kwaicdn.com/upic/2025/05/11/07/BMjAyNTA1MTEwNzIxNDFfMTUxNDIyNTM3OF8xNjM5NzU2OTQ5NjhfMl8z_b_Bc26646b09047086e801f9e70c7b89c3f.mp4?pkey=AAWWYEc_X3fwwG9CFF05dH5oeA679OXHU7HSVUGJBOlKOYjZ0eyggmwGcHm8M-vG5wYJ48KtGrnwGvaVpN1gE4Kleg4oWF1O6KUrOaJq0UgsCnbIAgyRxBAjq2S4MgOVIcM&tag=1-1781158885-scn-",
+ "http_status": 206,
+ "content_type": "video/mp4",
+ "content_length_header": "546455",
+ "content_range": "bytes 0-546454/546455",
+ "bytes_received": 546455,
+ "looks_like_video": true
+}

+ 13 - 0
数据接口与来源/captures/sph_account_info.json

@@ -0,0 +1,13 @@
+{
+ "label": "sph_account_info",
+ "url": "http://crawler.aiddit.com/crawler/shi_pin_hao/account_info",
+ "request_body": {
+  "account_id": "28ee8b6605e2288793f5386abaef5769",
+  "is_cache": false
+ },
+ "response": {
+  "code": 10001,
+  "msg": "参数异常: app_id或account_name至少需要一个",
+  "data": null
+ }
+}

+ 13 - 0
数据接口与来源/captures/sph_blogger.json

@@ -0,0 +1,13 @@
+{
+ "label": "sph_blogger",
+ "url": "http://crawler.aiddit.com/crawler/shi_pin_hao/blogger",
+ "request_body": {
+  "account_id": "28ee8b6605e2288793f5386abaef5769",
+  "is_cache": false
+ },
+ "response": {
+  "code": 25011,
+  "msg": "视频号接口异常",
+  "data": null
+ }
+}

+ 13 - 0
数据接口与来源/captures/sph_search.json

@@ -0,0 +1,13 @@
+{
+ "label": "sph_search",
+ "url": "http://crawler.aiddit.com/crawler/shi_pin_hao/keyword",
+ "request_body": {
+  "keyword": "彩虹",
+  "cursor": ""
+ },
+ "response": {
+  "code": 25011,
+  "msg": "视频号接口异常: 获取搜索结果失败",
+  "data": null
+ }
+}

+ 524 - 0
数据接口与来源/captures/sph_search_retry.json

@@ -0,0 +1,524 @@
+{
+ "label": "sph_search_retry",
+ "url": "http://crawler.aiddit.com/crawler/shi_pin_hao/keyword",
+ "request_body": {
+  "keyword": "彩虹",
+  "cursor": ""
+ },
+ "response": {
+  "code": 0,
+  "msg": null,
+  "data": {
+   "has_more": true,
+   "next_cursor": 12,
+   "data": [
+    {
+     "is_cache": true,
+     "channel": 9,
+     "channel_content_id": "finderobjv03rf47ax8UTAiVchU7Uo2uexnucqpQD/XO8kw7opFqUs=",
+     "content_link": "export/UzFfBgAAxJqjXGR8HB7MjMzT4DCKvvfbr7g_Gs0eEnHpUkshIw",
+     "wx_sn": null,
+     "biz_info": null,
+     "title": "“原来彩虹真的是圆的!”网友拍到“圆形彩虹”,愿见者所愿皆如愿! #彩虹#祝你好运连连好事相伴 #见者好运 #接福接财接好运 (剪辑:张文宇)",
+     "content_type": "video",
+     "body_text": null,
+     "location": "未知",
+     "source_url": null,
+     "mini_program": null,
+     "topic_list": null,
+     "image_url_list": [
+      {
+       "image_url": "https://findermp.video.qq.com/251/20304/stodownload?encfilekey=2fG3V4WwQPkSr7cxS6mSaHCVQQTRV8BRbMZw6RUgO5cZUhGd80QqS1ZZxbfy1tq42DDQSfAUyljuF68XyUyzEhf0iapcb6v9amXnnLgRHib9c&hy=SH&idx=1&m=6531345814d8bfef56f82aca3f76ecfe&uzid=1&wxampicformat=503&picformat=200&token=AxricY7RBHdVWiaZ1JSxEttSIdPkJS3AS57UF1OVo5F7o6A2iceXhhibEG4yHZWaVIrvJe2WaIJJBsW2aBYibic3MhH065Ge0uhvLYcEeFsooLXTdE55ZsgVEHgRia7LdSBccmG4CYIsVz9yrnId9ib8VIURHa0PSB3nDgzD6pxicRfZib7Iibc7kRUTOBnZPyDL2Yc5Dgr4eEWu9mP19GjN0nKe8r0icw",
+       "image_type": 2
+      }
+     ],
+     "video_url_list": [
+      {
+       "video_url": "https://findermp.video.qq.com/251/20302/stodownload?encfilekey=Cvvj5Ix3eewQsFvYyicia1J2Fn7bP8bqda0BslGG9tX9mZA32TQp7JN7QfEsI4M1ibSictTLtVoZNHEV8KsMF7kgKrHdT2tme9q5mty8fAgwiafrNpqWsnqerhQ&hy=SH&idx=1&m=2472d1256d2b20324914a543cc9c3b3f&uzid=7a152&X-snsvideoflag=xWT114&token=ic1n0xDG6aw9Kicy8QAXnibeBK0VIHC7c8ibsoVFrfLOKLVJQIdzgHzvLnPcntSwBiaPD963pf4LeojP4qFic1BRDlrr0OXMTRr22bHkiaPibaELRFblku5wLYYBiaVeLEluLvC6W6LFjNaM4oq39E0MF3WZf7WS378K11LnbpBhy7DrhmlXf4QsHE22Un78LkauaZgd6kA0EVkQm1o5oF8na9gKib8FbEBT3wmajq&basedata=CAMSBnhXVDExNCI8CgoKBnhXVDExNBAACgoKBnhXVDExMxAACgoKBnhXVDExMhABCgoKBnhXVDExMRAACgoKBnhXUjExMRAA&sign=polHvzKD6MhoWFIrrvA4AqU1d94y4qBRk2yHxYcBZtYeR16mZgx52kCbv8j8XjP7h5u8ifrec9t4VYpJVUCsVQ",
+       "video_duration": 8
+      }
+     ],
+     "multi_bitrate": null,
+     "bgm_data": null,
+     "ad_info": null,
+     "is_original": false,
+     "voice_data": null,
+     "channel_account_id": "28ee8b6605e2288793f5386abaef5769",
+     "channel_account_name": "掌上巴彦淖尔",
+     "channel_account_avatar": "https://wx.qlogo.cn/finderhead/ver_1/N8D7iclibakCDb5pTyAFMicicIFbFIO4RE5kWYKRgWoOwwFBXqgYUnHfL80qHLKIJp4e4jaeibiaaM98Jt2OWVvgS0PWCgPBXy6OplWCw3hkPCTKXEBzHBAqibs9a1WdAiavdPiarVTIHbNnK8SH4LwONLXzGew/132",
+     "item_index": null,
+     "view_count": null,
+     "play_count": null,
+     "like_count": 92,
+     "collect_count": null,
+     "comment_count": null,
+     "share_count": null,
+     "looking_count": null,
+     "publish_timestamp": 1780904037000,
+     "modify_timestamp": null,
+     "update_timestamp": 1781159308536
+    },
+    {
+     "is_cache": true,
+     "channel": 9,
+     "channel_content_id": "finderobjv0MX9tU0re5XXtZRosf4KaWO14AOl1StrkMj8ZeVVNo2w=",
+     "content_link": "export/UzFfBgAAxNSmTEcWMnrJjMzT4DCKpLcuyL0QTyObnQN6Ur7_Kw",
+     "wx_sn": null,
+     "biz_info": null,
+     "title": "2026年6月10日18点长春彩虹🌈#长春#双彩虹#双彩虹带来好运 #城市天际线的浪漫 @芮柠檬",
+     "content_type": "video",
+     "body_text": null,
+     "location": "未知",
+     "source_url": null,
+     "mini_program": null,
+     "topic_list": null,
+     "image_url_list": [
+      {
+       "image_url": "https://findermp.video.qq.com/251/20304/stodownload?encfilekey=2fG3V4WwQPmZne78q8ntchQia5FB8qabLmIxYwiafg1XMr1hw4FIxwMLn0hk2uQNWdSGM6gRnlCpfYH3lU6z72ZBuykrzgL3DVAqwN5K582HY&hy=SH&idx=1&m=cea99ea1e6c0f97631746d4991e75b7e&uzid=1&wxampicformat=503&picformat=200&token=ic1n0xDG6awicYwrrIzRZHW7VCFjUg7SPsib3gAC1R39Z0ZkEBF1otcvZBqQibzlQXiaSOK7U20A72LgsH8EUR7wH9w3FJ2n8IT8srkyb4GnJiauoCZMICOSLO2YkNXqiaQaUtkofUZEJ0JfVNjSt14RctBtuKnyD5ec95Z7zlgZOFmychs4dAPJdiagCAic022P6wiaj1IQFE5T5nobZ5ZbmXonZ8mA",
+       "image_type": 2
+      }
+     ],
+     "video_url_list": [
+      {
+       "video_url": "https://findermp.video.qq.com/251/20302/stodownload?encfilekey=Cvvj5Ix3eewQsFvYyicia1JicicAuhurWtTTphl2acqR8BIk2yLnOQRrES98wsUhdOYZgPibOzV5L9FCic1NdfgB0KCr9ZL72YJraWQJytPb1o8W4UTjU50DCJug&hy=SH&idx=1&m=a7c50c7c6814f11a72f1015137ff9fd7&uzid=7a22e&X-snsvideoflag=xWT113&token=AxricY7RBHdWPXANAibkLxVHfUZP8tJKUIk26iblsJL3WUrH8dzFSVicT8N65Kmux5ib7Ed0L7VxZbMVHAiapIic7bwEI9GUDbXGAd1UbtjSX3tRWxDdIOcic0ibCNHfib4vibCy1QBYURlaXn22De1DGbm0SyQVibOjfDibUZqpkWw7zdtZYTgb2IXVfmEVf1VQ04D4icPl0sHZPcp63cwJZD0RGusteSMcETUkGZPbkm&basedata=CAMSBnhXVDExMyI8CgoKBnhXVDExMxAACgoKBnhXUjExMRAACgoKBnhXVDExMhABCgoKBnhXVDExMRAACgoKBnhXUjExMhAA&sign=Q3KD8DI4HhaBxNf7siAhSxH7vTOZYQB-ntoO5Pxwc4HtVDjmyhbD9e04_n9XgO7g2bsUXswvHJJAN4ocHeE7jg",
+       "video_duration": 8
+      }
+     ],
+     "multi_bitrate": null,
+     "bgm_data": null,
+     "ad_info": null,
+     "is_original": false,
+     "voice_data": null,
+     "channel_account_id": "7244a1ce8b7ed86568ef4a2d7c4738aa",
+     "channel_account_name": "海王星航拍",
+     "channel_account_avatar": "https://wx.qlogo.cn/finderhead/ver_1/w16BZfKkc4iao2pI8eTKc4XrZiblBV93OO0mUjvI6PsU9Btibk0yQLib3WtPyQvuCqXDF8cg1jlHpXUUibLicdJ4Jwv4ZuTM3c8uXZWaibZRyUXWRbou7uibnSpUU3DXNmyEutibE/132",
+     "item_index": null,
+     "view_count": null,
+     "play_count": null,
+     "like_count": 282,
+     "collect_count": null,
+     "comment_count": null,
+     "share_count": null,
+     "looking_count": null,
+     "publish_timestamp": 1781086413000,
+     "modify_timestamp": null,
+     "update_timestamp": 1781159308536
+    },
+    {
+     "is_cache": true,
+     "channel": 9,
+     "channel_content_id": "finderobjv0sQqDuJdVZOoxvxfIWMSt7UsOEphrW+WGTG4hVnQEDmU=",
+     "content_link": "export/UzFfBgAAxJGibC4LNw3MjMzT4DCK69wA3cTCIHoGmqSSg_3Bxw",
+     "wx_sn": null,
+     "biz_info": null,
+     "title": "石家庄市区惊现双彩虹!",
+     "content_type": "video",
+     "body_text": null,
+     "location": "未知",
+     "source_url": null,
+     "mini_program": null,
+     "topic_list": null,
+     "image_url_list": [
+      {
+       "image_url": "https://findermp.video.qq.com/251/20304/stodownload?encfilekey=2fG3V4WwQPlEXiaPle49748XqtZ08zkA9TBAPmGYh0k35MBHcg0UiaZic4xGgElkYFmK3nV8ueExO7ibY7WlDtSib6jS9oqphFeq0N3TbrXgTebw&hy=SH&idx=1&m=d28f036a7c129f07d9f0e650ba071d5c&uzid=1&wxampicformat=503&picformat=200&token=AxricY7RBHdUHjyocZ3JbVQtZQbUjJ5HbnYqriar3ukwRJWiayWPaibqcrFWpicZNYwnN2AZMtTuLlLSRwLvIJpq8TU8R75oxX8icibKlibB32S793D8w9lCwsJfcuPHeg6D4PIg1LdtAeHhBIxmjVrkKy7r5gh7loyDz7O8Ir2Kjxn6lQdibEClP3CnJwHf4GicnzGxZM1SBht18ibzEjIKs3JY9d1Hg",
+       "image_type": 2
+      }
+     ],
+     "video_url_list": [
+      {
+       "video_url": "https://findermp.video.qq.com/251/20302/stodownload?encfilekey=Cvvj5Ix3eewQsFvYyicia1J9aicXVEW9OO1VIOrD2kHDG65TYDbtE87iafsr9ibhAum6RgqCJmgfmicmKjx4RGkIMbK9RZgBIqiae7iaib5ZVNH0SiaWGNW5wNsGbZxA&hy=SH&idx=1&m=41d739786db78de5779c0e9dd754f142&uzid=7a22e&X-snsvideoflag=xWT113&token=2lt8WBSnjTn3OJ9ZibQ5SUTQWnuguHeM9dY1K108zsicXbW8p8YTsyIQ41tPPiajtApM0nf0b0xoxic5iaL9zJKicoicn1UkicF9YWpdx2Eb3NTjPzu7o6Hic6iaYExjyoYOlicyRP0Grk845mcpC9iawYc2xzAAgr0kcIW4EAibE7RJABgW9bAIZBJ9nQQmoA8GW1UtjFZ22LyHRT0NJp7rB5gwJYbIolUBeSBhjADBy&basedata=CAMSBnhXVDExMyI8CgoKBnhXVDExMxAACgoKBnhXVDExMhABCgoKBnhXVDExMRAACgoKBnhXVDI1OBAACgoKBnhXVDEyOBAA&sign=7bP2M9Z-z6PLYxvmREcDPW2N0H0iLlcVPd5YA4x1dolEYqX2hqJvJDg3J6AuAze-Rqy73fGF2SyoF_qkOq7Q8A",
+       "video_duration": 9
+      }
+     ],
+     "multi_bitrate": null,
+     "bgm_data": null,
+     "ad_info": null,
+     "is_original": false,
+     "voice_data": null,
+     "channel_account_id": "d898981ab42f64553e2e7b530e7a49f7",
+     "channel_account_name": "石家庄游玩",
+     "channel_account_avatar": "https://wx.qlogo.cn/finderhead/ver_1/njSzibwWbY6R6CUGnlo0Mo9gWQMMh7rZk2uJTwKS4cibAIy3VPLYBKxZpicHVI4ISfBjFs3KDK1klZOLRtTaqDujeZQAicheMBCqlQibtnXPUFsNW3ibtccOsqEZqp4eq3z19bGibvJQutnjJsNVZf4YpJI7w/132",
+     "item_index": null,
+     "view_count": null,
+     "play_count": null,
+     "like_count": 469,
+     "collect_count": null,
+     "comment_count": null,
+     "share_count": null,
+     "looking_count": null,
+     "publish_timestamp": 1780913910000,
+     "modify_timestamp": null,
+     "update_timestamp": 1781159308536
+    },
+    {
+     "is_cache": true,
+     "channel": 9,
+     "channel_content_id": "finderobjv0Ug7Ik1F9WH1zJdmDbaMQ0dnpqS68v3Uar5GWUPGYk/A=",
+     "content_link": "export/UzFfBgAAxKmDcFQufxH-jMzT4DCK6Jk3FapzyaLAlLN7ZOfdJw",
+     "wx_sn": null,
+     "biz_info": null,
+     "title": "...记得你甜美的心跳”#TimeZ#彩虹#酷狗音乐",
+     "content_type": "video",
+     "body_text": null,
+     "location": "未知",
+     "source_url": null,
+     "mini_program": null,
+     "topic_list": null,
+     "image_url_list": [
+      {
+       "image_url": "https://findermp.video.qq.com/251/20304/stodownload?encfilekey=rjD5jyTuFrIpZ2ibE8T7Ym3K77SEULgkialgWAd16eKmQ7gz1N5r3GQQOfUw3p7xsgIqT3N2XXia8JacaU1qkTZZq4TEBk42BxskibdNthG6ZpTxicuHSbRAtHA&hy=SZ&idx=1&m=&scene=2&uzid=1&wxampicformat=503&picformat=200&token=ic1n0xDG6aw8aVBlwAtibGaSfoEueYUGNV5cYtovVgtHCML06n8ficTSSt7AJhO18UUXHRwpjT79e1RRVQR00kSDYBib8t8WiaR2RHISfD9J428PzfIdZhabicrW5W4lfXSiavRibhzibOEv8ibS8yX9iaDd2KnrLB5O8m3qscQj9EuOVXiaux0FXq1GN89ET3gqh1iaThMW1ZXXImpHfNZECUrXAZFIYhA",
+       "image_type": 2
+      }
+     ],
+     "video_url_list": [
+      {
+       "video_url": "https://findermp.video.qq.com/251/20302/stodownload?encfilekey=rgjNqbibdAo2hlOibDwxCxswDqAcNceOhapUlMtP0sPpKsd4c4EOmIOlQVicC8oylQYMpHByibSfezoYKvNXu3wktw&bizid=1023&dotrans=0&hy=SH&idx=1&m=&uzid=7a1fc&X-snsvideoflag=xWT113&token=ic1n0xDG6aw9Kicy8QAXnibePGFnFU4mIu3ZSLd3dzVqHFzM1PtictlvqKMulwt9mB5sX41ibtAGgmf6SjqudLb2Uxv72c9H3g9loruN64HneCibxibBF55ickliakOkNNAhkicNzjicbSN461mGBP7hkMBtSiaNwWMxvaCTI3nqs9Ecia7Pk0QaZyWu2xN7PwmoJicbJfkpw3L6aVmbvzd5iayPPZCohGCLoUtLTrVNJXL&basedata=CAMSBnhXVDExMyI8CgoKBnhXVDExMxAACgoKBnhXVDExMhABCgoKBnhXVDExMRAACgoKBnhXVDI1OBAACgoKBnhXVDE1OBAA&sign=4iyHdI7E6NzEdnWmTdnG4yEUjh7AOokoKghdpIru-qufkMx3TOCpXsWVbjbVifsbdzgGfQM_KRI0Kl_U6TbhlQ",
+       "video_duration": 30
+      }
+     ],
+     "multi_bitrate": null,
+     "bgm_data": null,
+     "ad_info": null,
+     "is_original": false,
+     "voice_data": null,
+     "channel_account_id": "351a620f325203cf3fab9e4316ab011e",
+     "channel_account_name": "酷狗音乐",
+     "channel_account_avatar": "https://wx.qlogo.cn/finderhead/ver_1/g1ZwicKRK0ZQffZ3m23TrNpBA3jXn4nibEknbGaNquQUibhGQMsciaLqqrcF0icHWpt75mfxCmCWibcib6KrHR3Cua48kYYnyaQeuIETyNerVmCLWY/132",
+     "item_index": null,
+     "view_count": null,
+     "play_count": null,
+     "like_count": 1153,
+     "collect_count": null,
+     "comment_count": null,
+     "share_count": null,
+     "looking_count": null,
+     "publish_timestamp": 1779967801000,
+     "modify_timestamp": null,
+     "update_timestamp": 1781159308536
+    },
+    {
+     "is_cache": true,
+     "channel": 9,
+     "channel_content_id": "finderobjv0wMerMoQrU+xhfiiObbRUhj6nv1q9p9AHgnog9yXGVKk=",
+     "content_link": "export/UzFfBgAAxMGDXFZqanb3jMzT4DCKdLa3I8qv2ninRRN3RjRVTA",
+     "wx_sn": null,
+     "biz_info": null,
+     "title": "谁懂啊!青岛雨后惊现彩虹,网友:青岛真的很浪漫。(剪辑/刘宇航)",
+     "content_type": "video",
+     "body_text": null,
+     "location": "未知",
+     "source_url": null,
+     "mini_program": null,
+     "topic_list": null,
+     "image_url_list": [
+      {
+       "image_url": "https://findermp.video.qq.com/251/20304/stodownload?encfilekey=rjD5jyTuFrIpZ2ibE8T7YmwgiahniaXswqzaqSBgEdBiaaaEkQvMejMGOVfQic7oRm1YZMXYkwrwdlSPKeNy9ohmFicoD3MsUbLHj5A2TRzVFmttSHygqEicvF62w&hy=SH&idx=1&m=&scene=2&uzid=1&wxampicformat=503&picformat=200&token=ic1n0xDG6aw8MParibuuU756ibcU9u3oBL96fvXS3d1mdwkI2wmmHr8JSgWyYwCrvBdyJWtu4dsiaI5SF8qS1R7gaUS0ZlvF22zfGh5akhRSfWfs23taSGuG73cYEVPSzr5zCqYNQEMaFTbj8nd3aJ3ABcKcKckRq61YgDvB3OlqBxxmT9tJuibjQtd0lgKYIA6trhfyVaicicKafVf70iaYMYfBQQ",
+       "image_type": 2
+      }
+     ],
+     "video_url_list": [
+      {
+       "video_url": "https://findermp.video.qq.com/251/20302/stodownload?encfilekey=Cvvj5Ix3eewK0tHtibORqcsqchXNh0Gf3sJcaYqC2rQAMF2qP3EeByqR48n84ibOVic3Qy0TmIHsO7OaXcowVlicOyMFMOsZYGIaUYU2ric1PZ3CTwAgwKAzJaeRN27ibPjKx2&bizid=1023&dotrans=0&hy=SH&idx=1&m=&uzid=7a1fc&X-snsvideoflag=xWT113&token=2lt8WBSnjTn3OJ9ZibQ5SUcpqDmTnQ8JVoydgme5D15iaJtM4sGVcqwgCdgxBQUp5j9QficiabnnMZIGXvJiaClqmL3I1roTCFXiaHggO5tiat7A44XbwaWNlVphpJ7HqVFI3Ept1AbGLZ6C3LZZGyicia0iabbJHkA7GTxDwEVVLT2natDU6tYQ1LTpm8keg5X3GO28boT5xEcn8VfIiabDUl47IsibAjWtPeQzj88ia&basedata=CAMSBnhXVDExMyI8CgoKBnhXVDExMxAACgoKBnhXVDExMhABCgoKBnhXVDExMRAACgoKBnhXVDE1OBAACgoKBnhXVDE1NxAB&sign=qbLPITXkTKrib_p_ZqFsYMqWlkaRh5vn2uLAjAKSHS32VJ0K4jZj8-g4ysxmZZOeT1DVhNC2BaKpp8PwUlllVA",
+       "video_duration": 8
+      }
+     ],
+     "multi_bitrate": null,
+     "bgm_data": null,
+     "ad_info": null,
+     "is_original": false,
+     "voice_data": null,
+     "channel_account_id": "58881959a01e16c04bdad83e83b0393e",
+     "channel_account_name": "青岛早报",
+     "channel_account_avatar": "http://wx.qlogo.cn/mmhead/Q3auHgzwzM5wMVyDQ8UUXHbxTYYzuVmQhvNRsWjM5I6UQHwQWUG77A/132",
+     "item_index": null,
+     "view_count": null,
+     "play_count": null,
+     "like_count": 1272,
+     "collect_count": null,
+     "comment_count": null,
+     "share_count": null,
+     "looking_count": null,
+     "publish_timestamp": 1779347517000,
+     "modify_timestamp": null,
+     "update_timestamp": 1781159308536
+    },
+    {
+     "is_cache": true,
+     "channel": 9,
+     "channel_content_id": "finderobjv0It9ETIGzFhu+miEnj5nqDVH51HvNT7/R9qHxFdgFUZk=",
+     "content_link": "export/UzFfBgAAxOahSEFJd27JjMzT4DCKTydwaEY38s0RZHH51isg_A",
+     "wx_sn": null,
+     "biz_info": null,
+     "title": "谁拍到了?刚刚拉萨小雨过后闪现绝美彩虹🌈(记者:刘明)@西藏卫视+",
+     "content_type": "video",
+     "body_text": null,
+     "location": "未知",
+     "source_url": null,
+     "mini_program": null,
+     "topic_list": null,
+     "image_url_list": [
+      {
+       "image_url": "https://findermp.video.qq.com/251/20304/stodownload?encfilekey=KGDRibp2wkicIuR26Cyk5s6TaicHCfAxUyl1lbic9Ge2iazXAQGNXCnqyHJBicMWbSFCcMsTCeUfFONjrO6es43gE3pw&hy=SZ&idx=1&m=&scene=2&uzid=1&wxampicformat=503&picformat=200&token=AxricY7RBHdXwr9W0AQud0gjjEdIOBlGOgLyx2SIJiabicQviblWWrnjVAqxTnZDosPgJ2ibudAJcOC8iaN1V39ewAZhZWNibp097mE5n0NWPz5YCUSs6Zo2AWZjic4M31Y6FDhZmkNV1Ey6bDAplqJ4BoKJehgiatlbQThwmBtAW33OuOicFulTMknCbXSYYf3A2ZMoYBVBjEuHdRBzP9FcAfGtL2LA",
+       "image_type": 2
+      }
+     ],
+     "video_url_list": [
+      {
+       "video_url": "https://findermp.video.qq.com/251/20302/stodownload?encfilekey=Cvvj5Ix3eewK0tHtibORqcsqchXNh0Gf3sJcaYqC2rQDQJaGzTByqaibfsZQ7ZcsF8xMPbgfuIfYHSnwt9R62TF3ZxBUhc1ODgHYMZQTyUqHBJWdtvjJVeu6FMN00GzTHl&bizid=1023&dotrans=0&hy=SH&idx=1&m=&uzid=7a152&X-snsvideoflag=xWT113&token=2lt8WBSnjTn3OJ9ZibQ5SUTch3GctkzMdnjwpTxzeWHbyhqDbbxzOeGATzibtCzPpMefdicgvsrD9EZsKicEWdF89H1rtYm0zWfMT0MYGic7TU0RHPSYR2CS1icZkicyL5zDNGxdyLUdbwwm0I1d9LuhCko44MonPu8jIiaWXZGpAYfz5SqsFwdGMnFD6c9ia5Amk7xmq4LMDd25ibTGgnDtVayL1MEE5SicGRLzqUD&basedata=CAMSBnhXVDExMyI8CgoKBnhXVDExMxAACgoKBnhXVDExMhABCgoKBnhXUjExMRAACgoKBnhXUjExMhAACgoKBnhXVDExMRAA&sign=012Og-u_EfDd3PuNWCedqUQhFk67gIwallpg3xsa_ZXOltg2K_3I3Jeq8byyqIDpQ87M_iwz7Wtwq5bz-s81ug",
+       "video_duration": 62
+      }
+     ],
+     "multi_bitrate": null,
+     "bgm_data": null,
+     "ad_info": null,
+     "is_original": false,
+     "voice_data": null,
+     "channel_account_id": "fbec59d6277e3974536d349ae316bf07",
+     "channel_account_name": "西藏卫视+",
+     "channel_account_avatar": "https://wx.qlogo.cn/finderhead/ver_1/PDUA5yhetcvb5wsxpictKnqtVBMtbcpSjJqlJVxLECbUgWqAcM27XlQblvzQfaibVCVoYQUcdmib5uibvIQmQNKL3LtcHJK0ibqP81dYNShOTI5U/132",
+     "item_index": null,
+     "view_count": null,
+     "play_count": null,
+     "like_count": 286,
+     "collect_count": null,
+     "comment_count": null,
+     "share_count": null,
+     "looking_count": null,
+     "publish_timestamp": 1781096627000,
+     "modify_timestamp": null,
+     "update_timestamp": 1781159308536
+    },
+    {
+     "is_cache": true,
+     "channel": 9,
+     "channel_content_id": "finderobjv0CGRxP8P6b7VLgSoOv1gbfIdbjT5UBB8rsSHhb+fMcu0=",
+     "content_link": "export/UzFfBgAAxOiDcE40dUfCjMzT4DCKZQesWWexGzLJy6ztLNI-3A",
+     "wx_sn": null,
+     "biz_info": null,
+     "title": "谁说彩虹是弯的?网友河北拍到“圆形彩虹”,我的世界观被刷新了!#河北#彩虹#治愈系风景#美好",
+     "content_type": "video",
+     "body_text": null,
+     "location": "未知",
+     "source_url": null,
+     "mini_program": null,
+     "topic_list": null,
+     "image_url_list": [
+      {
+       "image_url": "https://findermp.video.qq.com/251/20304/stodownload?encfilekey=rjD5jyTuFrIpZ2ibE8T7YmwgiahniaXswqzy5ia74GMBHI8XVTTeb1YlW3bkre5z8FY1c8KHthRf9Rk8MzNZuWF2NIj2mDwkmtulzPVZr1QeyKnJlcxqDWG8MA&hy=SH&idx=1&m=&scene=2&uzid=1&wxampicformat=503&picformat=200&token=ic1n0xDG6aw8TkUodWR0yl1ZW2wAGaWTsEVm9hToFk39UqpYM2k7lJXzY3qK6afoUg46AYU1ibTI08iaw2KkvlibzdR0zcb47X3ZzeIQlLjVQgQLlzDMlNxRmaslxkgY53MNDD6D7G7x76JGibSP7pw92QiabFKlITZ9q9IkDKpZhqsl34joA9ZWxftDwhcWkDHSL9EncC876kAvm8Tkp5Eib1Tng",
+       "image_type": 2
+      }
+     ],
+     "video_url_list": [
+      {
+       "video_url": "https://findermp.video.qq.com/251/20302/stodownload?encfilekey=rgjNqbibdAo1hicHTjuF7Ea8mwFB1NposJRcaroCbApgp5gVaUZQyOhIQDEQ2Q6OUOuVNMiaiaaEYK8csWthjvgvAg&bizid=1023&dotrans=0&hy=SH&idx=1&m=&uzid=7a21a&X-snsvideoflag=xWT114&token=ic1n0xDG6aw9Kicy8QAXnibeAOC2r5GEOmwZ5cPibGNmAYTof9wC2GMJgt2UN1Dwia6hXYicFrvnGRFg8OSlcZ8rxvpl7DU98RmZgS9ZIE0naqdwqdfjOC1KWmRz67SG7eEcwbtIJpUTVuiaEjJjGialJC6FWBy6n2icic0JBwiaYgl7vo4XsicgyjmRZ1iaJicYYkpFvPWomicvmM5icpiaibdkFQBNS2Ot2tJic0gqyibd5RTc&basedata=CAMSBnhXVDExNCI8CgoKBnhXVDExNBAACgoKBnhXVDExMxAACgoKBnhXVDExMhABCgoKBnhXVDExMRAACgoKBnhXVDE1ORAA&sign=FDy-Pqo4CFhXBQL38AQf0Er8sdM1e7sf4w9I_2r4MhTDOF4AQPQADG4kR9XcPKP8rb4OtHKUJg7gQWZ8WRG8BQ",
+       "video_duration": 6
+      }
+     ],
+     "multi_bitrate": null,
+     "bgm_data": null,
+     "ad_info": null,
+     "is_original": false,
+     "voice_data": null,
+     "channel_account_id": "774acea70a559af2a001e02cc1cc4bf9",
+     "channel_account_name": "山西日报",
+     "channel_account_avatar": "https://wx.qlogo.cn/finderhead/ver_1/CQJGTGgs6TnU3STmoDWmSUibKC8CeCo6ia0OuZ95I9MRx95xPFbt7TB5Iicvlib7Mk4IQllo1sjSXhfjLpVzrSOhKQyoSwuHKFmgN98ycMI1yXs/132",
+     "item_index": null,
+     "view_count": null,
+     "play_count": null,
+     "like_count": 5513,
+     "collect_count": null,
+     "comment_count": null,
+     "share_count": null,
+     "looking_count": null,
+     "publish_timestamp": 1780749014000,
+     "modify_timestamp": null,
+     "update_timestamp": 1781159308537
+    },
+    {
+     "is_cache": true,
+     "channel": 9,
+     "channel_content_id": "finderobjv00ylZ6mEdHCmvMahUGzddcdmUZSa7Z47Nt2cFg55LwDs=",
+     "content_link": "export/UzFfBgAAxM-gAAckWV3OjMzT4DCK4u1QmXO-6KvSZM2wW30RrA",
+     "wx_sn": null,
+     "biz_info": null,
+     "title": "2026年6月9日19:15分,北京天空惊现三道彩虹🌈!#彩虹#我的摄影日记#三道彩虹#自然奇观#彩云#晚霞",
+     "content_type": "video",
+     "body_text": null,
+     "location": "未知",
+     "source_url": null,
+     "mini_program": null,
+     "topic_list": null,
+     "image_url_list": [
+      {
+       "image_url": "https://findermp.video.qq.com/251/20304/stodownload?encfilekey=2fG3V4WwQPkIfjiaJO6MWWZCYahNDoZj2CyygePmKfyyd0IGD7RtMOTrUfmHRWy44h32AlzUb7HK17K2YfTZQq3xmD5EjdCyVaHvicaC1LmXU&hy=SH&idx=1&m=10781efa0435e07ac816751f2e61dd94&uzid=1&wxampicformat=503&picformat=200&token=AxricY7RBHdVOzvD7fZMjcteOUWzVhMd4QjGFiavD17MZIAWmSvpPNKjqxbMOOlF6r3MjlxNz9N6IicECyQwvjtIhxMkyORSfAzeP2S1eB67Olwe0KyicUeEyGqIaYcuniaNl6ehLian8VZfbqNyia8r0tYymZNnpNUP7nW9rjPLE17TjiaD5FDWasUZ8pzJn3UtibfyxzFTPtRbBmeskrtZAYAIRicA",
+       "image_type": 2
+      }
+     ],
+     "video_url_list": [
+      {
+       "video_url": "https://findermp.video.qq.com/251/20302/stodownload?encfilekey=Cvvj5Ix3eez3Y79SxtvVL0L7CkPM6dFibFeI6caGYwFE4np9k4xpfbGmKRZhmVZAzBzauVbBibHw61UoldibmzjP0IB0SjRdKSh9icicNuibJyB4ic6ZZL18GKzrUPyfy8UfkrnPhJlkVicGj0HQeGBcpibbLpw&hy=SH&idx=1&m=c5ec271268bf89bf35095f929bf475f1&uzid=7a152&X-snsvideoflag=xWT113&token=2lt8WBSnjTn3OJ9ZibQ5SUd4927mwKyhGAumeiacegHd4GGWfw4Je6SBlbjwpe9dynicULkBQfQduw4rXfLNOam7wVenB7souWviaq7ncVF2MsyhNkFOF4LgqjqvUXGUY1JLw8kSLTSP5XQS0srR0YMb3bD19rBdx7BvV865kZjLvqUyIoLX0a2kAoTy3OxJjR6gFM6QDe3REkyuCtgxJ8mdXVRxPj8HUVOv&basedata=CAMSBnhXVDExMyI8CgoKBnhXVDExMxAACgoKBnhXVDExMhABCgoKBnhXUjExMRAACgoKBnhXUjExMhAACgoKBnhXVDExMRAA&sign=XFYA0UJ7eAcH55CDeokW2Uu7XwfnA8iRQh0jlSX14_0spP7Z8TVjCl1zS66YIuNlG2kdc-Am2Zz9iCNfAStp_g",
+       "video_duration": 14
+      }
+     ],
+     "multi_bitrate": null,
+     "bgm_data": null,
+     "ad_info": null,
+     "is_original": false,
+     "voice_data": null,
+     "channel_account_id": "3abcf5faa8ec46edda02533821856f3d",
+     "channel_account_name": "莲子荷的神奇动物园",
+     "channel_account_avatar": "https://wx.qlogo.cn/finderhead/ver_1/XXPwC5P7uHq03csDBuf3JH7elpmg5MdErKAiaAdkibb7vJsAtXaGZTXUvLv3wEhHd63Y1Ijs6FScb6c9IK3tHoXb0nlH0dicJy0VZ2ZDf9ry28/132",
+     "item_index": null,
+     "view_count": null,
+     "play_count": null,
+     "like_count": 253,
+     "collect_count": null,
+     "comment_count": null,
+     "share_count": null,
+     "looking_count": null,
+     "publish_timestamp": 1781006030000,
+     "modify_timestamp": null,
+     "update_timestamp": 1781159308537
+    },
+    {
+     "is_cache": true,
+     "channel": 9,
+     "channel_content_id": "finderobjv0oALij0V4j/ApT5gE5UVzOjXXCV2Xw6cpHT4jZQrriks=",
+     "content_link": "export/UzFfBgAAxIKiEE9rPAPMjMzT4DCKmqsi_NzPxmlam7JatB-1nw",
+     "wx_sn": null,
+     "biz_info": null,
+     "title": "男子雨后在高塔上拍到圆形彩虹,仿佛开启“时空之门”,网友:看的人超级幸运!#彩虹#雨后#涨知识",
+     "content_type": "video",
+     "body_text": null,
+     "location": "未知",
+     "source_url": null,
+     "mini_program": null,
+     "topic_list": null,
+     "image_url_list": [
+      {
+       "image_url": "https://findermp.video.qq.com/251/20304/stodownload?encfilekey=2fG3V4WwQPmiaIXyKSGwPLxR4FPxPd6dJx51CBNdASGibibTHco1w6hmD7RexsHibZtOXMibqdt2zhRoS7kNdF6ONwmp5s97YrlONc4heAPeHN4M&hy=SH&idx=1&m=813ce4e140d3791fd5a341a8ea4ce765&uzid=1&wxampicformat=503&picformat=200&token=AxricY7RBHdUqNAULx5M5licIATMmI62BnBg6PEpEaAlHuuxxgfGgbv11TW7hhdHwjcggB7dztvsAesdQEEFanWa0SoAsRfLcvKKvzu8oYouSOJKHEliaibq5Buo8wl9iaicEJnQPqJVFdqccCVLcJjaJj1Sr11nr2qIkqibG2uBkbIWAVXGusgkEmGUXLZQXRpsyOPehKfYlNRib8OgtOhSqMKCVA",
+       "image_type": 2
+      }
+     ],
+     "video_url_list": [
+      {
+       "video_url": "https://findermp.video.qq.com/251/20302/stodownload?encfilekey=Cvvj5Ix3eez3Y79SxtvVL0L7CkPM6dFibFeI6caGYwFFQWTP0ZoTrEPEnX29s0MuYzMYaeAUic8rzeOs3LpicHugia46hOPyicnHMibqRbncSXjJIlB2UKA7ISaeufhJNiaLiaOW9bVSWhb0u138B1PRxezUrQ&hy=SH&idx=1&m=e8ed34f5dc6084d1d29f8baeb48e68b8&uzid=7a1b6&X-snsvideoflag=xWT114&token=2lt8WBSnjTn3OJ9ZibQ5SURLLTRPRaiaG7Rk7dQJiaicsMRIiaybVw7o4iajciaaQcaWJ8gynzAkwnyRzW1L3YlBXMhHQ1QiccNU1Rp79kXLG8OibjarosGgYBmrSSibmxEH3tqU07bN7t750GsSlXuw1YuogYpJibibe6VNtJ7iaOicOLQI9mgwyuq9rBdcYgJUamnB4GpHKU6Yhf6GcKVRLVIXicDEFLjScZK3NywIWbF&basedata=CAMSBnhXVDExNCI8CgoKBnhXVDExNBAACgoKBnhXVDExMxAACgoKBnhXVDExMhABCgoKBnhXVDExMRAACgoKBnhXVDE1ORAA&sign=fq3ZYVIpfZEMILoPITPXBEeOTc-2WTlgw2HGgs0T05cqw7SNtBoS7_WG-tJD_QItpoy5pVdbIXGQq0sAG2k5tg",
+       "video_duration": 8
+      }
+     ],
+     "multi_bitrate": null,
+     "bgm_data": null,
+     "ad_info": null,
+     "is_original": false,
+     "voice_data": null,
+     "channel_account_id": "3db1525078ce8340d140ca0469643d07",
+     "channel_account_name": "新畿辅",
+     "channel_account_avatar": "https://wx.qlogo.cn/finderhead/ver_1/tenKOKj7DHDAJ1HAlOWfHRN4Vlkcz0r9TSU9Oq1uzuIHYxzy1woQZWLL8Cdrd262GdCub1rtElqmu9C0UsHAsQK9lhZ9PEouBoia0gUmLibg2rSmy3TmaWnC1ylicc08JgC/132",
+     "item_index": null,
+     "view_count": null,
+     "play_count": null,
+     "like_count": 1482,
+     "collect_count": null,
+     "comment_count": null,
+     "share_count": null,
+     "looking_count": null,
+     "publish_timestamp": 1780914917000,
+     "modify_timestamp": null,
+     "update_timestamp": 1781159308537
+    },
+    {
+     "is_cache": true,
+     "channel": 9,
+     "channel_content_id": "finderobjv0UVW3sV6cd1a02Jw1efG9BRJOvuaLnf4FLTuQX+f0ozI=",
+     "content_link": "export/UzFfBgAAxOKjfBN1B3vMjMzT4DCK9YIDyVoYRFfFsyoCi-oU3Q",
+     "wx_sn": null,
+     "biz_info": null,
+     "title": "原来彩虹真是圆形的!网友在雨林高空拍下完整版彩虹,因为平时站的低,彩虹下半圈被地平线挡住了,网友:动画片诚不欺我#彩虹#自然",
+     "content_type": "video",
+     "body_text": null,
+     "location": "未知",
+     "source_url": null,
+     "mini_program": null,
+     "topic_list": null,
+     "image_url_list": [
+      {
+       "image_url": "https://findermp.video.qq.com/251/20304/stodownload?encfilekey=KGDRibp2wkicLichG7evg1PQiby6XPic4yWv3xKtUIT08klppbtgiadPwSV92g4xehN4NkNxGHMwc2C6GBAJegrSYQibQ&hy=SH&idx=1&m=&scene=2&uzid=1&wxampicformat=503&picformat=200&token=ic1n0xDG6aw9EhK9JicbrlsStUc7RgmyCLBYR35629Jz9I3gLmkSfKzCGxKWrBCxK5RaGRnpSzGjiaUYtWRvqZ5icllZJTNQ51hzMPQqqsicPmW5bzzUKBBIUiaPUTfmRBuicK5X2aMWMCliaTBpO2uZTu54AmBicVbyqOQ05BMiceaDlnRA6bsJ1Z5hr3lV8c2M8oCHSz9CnLWu61bU4qJCrgPm8YKw",
+       "image_type": 2
+      }
+     ],
+     "video_url_list": [
+      {
+       "video_url": "https://findermp.video.qq.com/251/20302/stodownload?encfilekey=Cvvj5Ix3eewK0tHtibORqcsqchXNh0Gf3sJcaYqC2rQBZuXgJway35JBbJaSiawd8O4jXjLCicOjDo3CJAlaMVoKbcCedKWsav09wZtdcjV052fpiaYXLP040Bo7J7kJLvOZ&bizid=1023&dotrans=0&hy=SH&idx=1&m=&uzid=7a166&X-snsvideoflag=xWT114&token=2lt8WBSnjTn3OJ9ZibQ5SUcPtKkDBZzSxXWGvficHjO9ibvIVkJn1cC6FZtN5FOIRVoXbIWlMcibeuJG0F2DKic9ypicFaPcFJkexrkwqEugtE7yQQzw7XXKRsQ8iaHzIsVddTPbuDlwL1qvHtX6RELBtic7XtflToyXyPsATUnUvlO2aBjC0rQ6TvUQL0p7IMFVwfsPvw1TibVk8SqMGKzIq1A3O3u5VTsb6W0J7&basedata=CAMSBnhXVDExNCI8CgoKBnhXVDExNBAACgoKBnhXVDExMxAACgoKBnhXVDExMhABCgoKBnhXVDExMRAACgoKBnhXUjExMRAA&sign=5hrbONtx6dp0KLHWZ-759Bf9NifNoUhKI41KGhpWPZvs5EnL6v9lInOUEOEuoJfqGcyLJHM6ahq3NXRlEKUlRw",
+       "video_duration": 20
+      }
+     ],
+     "multi_bitrate": null,
+     "bgm_data": null,
+     "ad_info": null,
+     "is_original": false,
+     "voice_data": null,
+     "channel_account_id": "65762672b067b4dc9b71120066413148",
+     "channel_account_name": "北方频道",
+     "channel_account_avatar": "https://wx.qlogo.cn/finderhead/ver_1/ZibSJlHZSW4uTGJsFLOzVmMtlarQBWCnJ3CzjWSAjPAiag4Stl2StjTSibn16R6cJ9HjLHgjaviaVhTJcjTTGMfpds3dLHTmyaxsMSdXzq2iaZ0JguJbWcGuGXiae13LjWov96YGZtkgvLS8iaY7B1vpBNWmg/132",
+     "item_index": null,
+     "view_count": null,
+     "play_count": null,
+     "like_count": 128,
+     "collect_count": null,
+     "comment_count": null,
+     "share_count": null,
+     "looking_count": null,
+     "publish_timestamp": 1780885666000,
+     "modify_timestamp": null,
+     "update_timestamp": 1781159308537
+    },
+    {
+     "is_cache": true,
+     "channel": 9,
+     "channel_content_id": "finderobjv0oKA223HZrhFWNThQQedZJxv2fskgTEXw8pD5smdvPUY=",
+     "content_link": "export/UzFfBgAAxI6DbHA4Dzv4jMzT4DCKrjJcqkq_63NyAreLu-k8iw",
+     "wx_sn": null,
+     "biz_info": null,
+     "title": "...\n\n#周杰伦 #jay#音乐#情感#彩虹",
+     "content_type": "video",
+     "body_text": null,
+     "location": "未知",
+     "source_url": null,
+     "mini_program": null,
+     "topic_list": null,
+     "image_url_list": [
+      {
+       "image_url": "https://findermp.video.qq.com/251/20304/stodownload?encfilekey=oibeqyX228riaCwo9STVsGLPj9UYCicgttvTvWVCd358mDylIdafgCXLQLtickWJmx0trMOm76DDNYMd8Xcs9B4kAoibx1WKoPfmOxwEiczq4PI5FYjxwAhvf4IGC64RnXzf4iaMSEBiaHWzxpE&hy=SH&idx=1&m=fd0caaddb6d454c5378558995c5db5e1&uzid=1&wxampicformat=503&picformat=200&token=AxricY7RBHdWlXHzzlmfibKia3Rtaq4uibUK9EWUAGETjuic1O2iaXbOT7hvQ5eVJpf2PGMTmRXt8q04YvYCjC2j8zfY3vQgTAsAEUL4rhibwwvevH8DzkJyY3VfA0OoTibskvX5piaU5vy1xJWaAZicwGcCd0AD0OnuUm6BICHSOibIBCso7k11ow68Vgib3iabj4h1j8eoIUPwK3P5reUMg5eYXVsibQicQ",
+       "image_type": 2
+      }
+     ],
+     "video_url_list": [
+      {
+       "video_url": "https://findermp.video.qq.com/251/20302/stodownload?encfilekey=Cvvj5Ix3eez3Y79SxtvVL0L7CkPM6dFibFeI6caGYwFGSG3LrVcxdgE6VgARubIpkLHrWSrpVA8vocOrOqh67Yy1A1YcYQKrfB0O56XnjOhZpXqDhkbYKJia5uExia5ETFyBIcHXxmZfBrsLEjqJTDxTA&hy=SH&idx=1&m=b22d46943c78b413d4dd0cf92ea180a1&uzid=7a1fc&X-snsvideoflag=xWT113&token=2lt8WBSnjTn3OJ9ZibQ5SUbFwXf0wWrTpATmzCEvsXLWib5jh5V7r4gLGI7iaAgKyibWTyZJbapUG3IqBQNxP0iacRvnicc3icdLlN5597ZxghaaiaIvl48IyFGqoUrtxpFqhNNUuxfiaacduWBbvuKN1JmJw1e6TOLYVqSt00licZl9VJfsWXww6qp4TtDfcKMJ1bicsTiaUOt9XicbeAyL6FAtibMhAb2Tibwpqzcnwju&basedata=CAMSBnhXVDExMyI8CgoKBnhXVDExMxAACgoKBnhXVDExMhABCgoKBnhXVDExMRAACgoKBnhXVDI1OBAACgoKBnhXVDE1OBAA&sign=s6ZGp_SG0lUYN_EI2-MBIkpm5GHMbnhl6zqUUhQO8aXhgxxnFIf7aDJFlARzkdueq9rBfx9LBkgy59JzvUX92g",
+       "video_duration": 23
+      }
+     ],
+     "multi_bitrate": null,
+     "bgm_data": null,
+     "ad_info": null,
+     "is_original": false,
+     "voice_data": null,
+     "channel_account_id": "c623d529a98b75245d1b9db7c442ea3f",
+     "channel_account_name": "周杰伦音乐屋",
+     "channel_account_avatar": "https://wx.qlogo.cn/finderhead/ver_1/Xicwcs3RnvLm6w8K5Vym7hd9pDhRyibXafJBQegeFBmRibc2fAvcbG32cbBceoTTQ4R18JkdYdMcZBk2UOtzt4I8ibAOVnSmTq09ib9GvhZhj6XqXT2yDcqOoibr9bs5UXnM0n/132",
+     "item_index": null,
+     "view_count": null,
+     "play_count": null,
+     "like_count": 3188,
+     "collect_count": null,
+     "comment_count": null,
+     "share_count": null,
+     "looking_count": null,
+     "publish_timestamp": 1780113880000,
+     "modify_timestamp": null,
+     "update_timestamp": 1781159308537
+    }
+   ]
+  }
+ }
+}

+ 9 - 0
数据接口与来源/captures/sph_video_dl.json

@@ -0,0 +1,9 @@
+{
+ "label": "sph_video_dl",
+ "url": "https://findermp.video.qq.com/251/20302/stodownload?encfilekey=Cvvj5Ix3eewQsFvYyicia1J2Fn7bP8bqda0BslGG9tX9mZA32TQp7JN7QfEsI4M1ibSictTLtVoZNHEV8KsMF7kgKrHdT2tme9q5mty8fAgwiafrNpqWsnqerhQ&hy=SH&idx=1&m=2472d1256d2b20324914a543cc9c3b3f&uzid=7a152&X-snsvideoflag=xWT114&token=ic1n0xDG6aw9Kicy8QAXnibeBK0",
+ "http_status": 200,
+ "content_type": "video/mp4",
+ "content_range": "bytes 0-784921/784922",
+ "bytes_received": 784922,
+ "looks_like_video": true
+}

+ 14 - 0
数据接口与来源/captures/toutiao_search.json

@@ -0,0 +1,14 @@
+{
+ "label": "toutiao_search",
+ "url": "http://crawler.aiddit.com/crawler/tou_tiao_hao/keyword",
+ "request_body": {
+  "keyword": "彩虹",
+  "content_type": "video",
+  "page": 0
+ },
+ "response": {
+  "code": 10000,
+  "msg": "未知错误",
+  "data": null
+ }
+}

+ 13 - 0
数据接口与来源/captures/toutiao_search_retry.json

@@ -0,0 +1,13 @@
+{
+ "label": "toutiao_search_retry",
+ "url": "http://crawler.aiddit.com/crawler/tou_tiao_hao/keyword",
+ "request_body": {
+  "keyword": "彩虹",
+  "page": 0
+ },
+ "response": {
+  "code": 10000,
+  "msg": "未知错误",
+  "data": null
+ }
+}

+ 9 - 0
数据接口与来源/captures/xhs_blogger.json

@@ -0,0 +1,9 @@
+{
+ "label": "xhs_blogger",
+ "url": "http://crawler.aiddit.com/crawler/xiao_hong_shu/blogger",
+ "request_body": {
+  "account_id": "63ee8949000000000f0102f3",
+  "cursor": ""
+ },
+ "error": "timed out"
+}

File diff ditekan karena terlalu besar
+ 0 - 0
数据接口与来源/captures/xhs_case_67e2e39b0000000003028ff0.json


File diff ditekan karena terlalu besar
+ 0 - 0
数据接口与来源/captures/xhs_case_67e4bdf50000000006028a59.json


File diff ditekan karena terlalu besar
+ 0 - 0
数据接口与来源/captures/xhs_case_680659e8000000001a007a11.json


File diff ditekan karena terlalu besar
+ 0 - 0
数据接口与来源/captures/xhs_case_698481e1000000000a02a7c1.json


File diff ditekan karena terlalu besar
+ 0 - 0
数据接口与来源/captures/xhs_case_699308fa0000000016009697.json


+ 62 - 0
数据接口与来源/captures/xhs_detail.json

@@ -0,0 +1,62 @@
+{
+ "label": "xhs_detail",
+ "url": "http://crawler.aiddit.com/crawler/xiao_hong_shu/detail",
+ "request_body": {
+  "content_id": "696b90ce000000002102be77"
+ },
+ "response": {
+  "code": 0,
+  "msg": null,
+  "data": {
+   "has_more": false,
+   "next_cursor": null,
+   "data": {
+    "is_cache": true,
+    "channel": 1,
+    "channel_content_id": "696b90ce000000002102be77",
+    "content_link": "https://www.xiaohongshu.com/explore/696b90ce000000002102be77",
+    "wx_sn": null,
+    "biz_info": null,
+    "title": "",
+    "content_type": "video",
+    "body_text": "夏日雨后彩虹草原\n1. 核心主体:广袤的绿色草原上开满五彩野花,一道七色彩虹横跨天际,雨后的草叶挂着晶莹水珠,几匹骏马低头悠闲吃草\n​\n2. 场景与环境:夏日午后的草原,刚下过一场小雨,空气清新湿润,远处有低矮的山丘,天空飘着几朵白云,氛围明快惬意\n​\n3. 构图与视角:9:16竖屏构图,高角度俯拍结合远景延伸,主体彩虹居中上方,下方是草原与骏马,形成天地呼应的视觉结构\n​\n4. 色彩与光影:明快的暖色调,草原的翠绿、野花的缤纷、彩虹的七色相互映衬,雨后阳光柔和明亮,草叶水珠折射出细碎光斑\n​\n5. 画面风格:超写实草原风光风格,还原雨后彩虹草原的鲜活生机,适配短视频明快活泼的观感\n​\n6. 细节与质感:8K超清分辨率,草叶的纤毫纹理、水珠的透明质感、骏马的毛发肌理清晰呈现,骏马甩尾吃草的动态自然生动\n​\n7. 额外元素:无文字特效,添加清脆的鸟鸣声、骏马嘶鸣声作为背景音,画面无黑边#彩虹的约定[话题]# #美丽的景色[话题]# #草原风光无限好[话题]# #美丽的大自然[话题]# #绚丽多彩的世界[话题]#",
+    "location": "陕西",
+    "source_url": null,
+    "mini_program": null,
+    "topic_list": [
+     "彩虹的约定"
+    ],
+    "image_url_list": [
+     {
+      "image_type": 2,
+      "image_url": "https://ci.xiaohongshu.com/1040g00831remfdem006g5oveh54jq0nj784l530?imageView2/2/w/1080/format/webp"
+     },
+     {
+      "image_type": 1,
+      "image_url": "https://ci.xiaohongshu.com/1040g00831remfdem006g5oveh54jq0nj784l530?imageView2/2/w/1080/format/webp"
+     }
+    ],
+    "video_url_list": null,
+    "multi_bitrate": null,
+    "bgm_data": null,
+    "ad_info": null,
+    "is_original": false,
+    "voice_data": null,
+    "channel_account_id": "63ee8949000000000f0102f3",
+    "channel_account_name": "一方盛景",
+    "channel_account_avatar": null,
+    "item_index": null,
+    "view_count": null,
+    "play_count": null,
+    "like_count": 7,
+    "collect_count": 1,
+    "comment_count": 1,
+    "share_count": 0,
+    "looking_count": null,
+    "publish_timestamp": 1768657102000,
+    "modify_timestamp": 1768657102000,
+    "update_timestamp": 1781158973900
+   }
+  }
+ }
+}

+ 561 - 0
数据接口与来源/captures/xhs_search.json

@@ -0,0 +1,561 @@
+{
+ "label": "xhs_search",
+ "url": "http://crawler.aiddit.com/crawler/xiao_hong_shu/keyword",
+ "request_body": {
+  "keyword": "彩虹",
+  "content_type": "视频",
+  "sort_type": "综合",
+  "publish_time": "",
+  "cursor": ""
+ },
+ "response": {
+  "code": 0,
+  "msg": null,
+  "data": {
+   "has_more": false,
+   "next_cursor": null,
+   "data": [
+    {
+     "id": "696b90ce000000002102be77",
+     "model_type": "note",
+     "note_card": {
+      "type": "video",
+      "image_list": [
+       {
+        "image_url": "https://ci.xiaohongshu.com/1040g00831remfdem006g5oveh54jq0nj784l530?imageView2/2/w/1080/format/webp"
+       }
+      ],
+      "user": {
+       "nick_name": "一方盛景",
+       "avatar": "https://sns-avatar-qc.xhscdn.com/avatar/1040g2jo30pcirbdo3q6g5oveh54jq0nj415r800?imageView2/2/w/80/format/jpg",
+       "user_id": "63ee8949000000000f0102f3",
+       "nickname": "一方盛景"
+      },
+      "display_title": null,
+      "desc": "夏日雨后彩虹草原 1. 核心主体:广袤的绿色草原上开满五彩野花,一道七色彩虹横跨天际,雨后的草叶挂着晶莹水珠,几匹骏马低",
+      "interact_info": {
+       "collected_count": 1,
+       "comment_count": 1,
+       "shared_count": 0,
+       "liked_count": 7
+      },
+      "publish_timestamp": 1768657102
+     }
+    },
+    {
+     "id": "69b3a899000000002800a5eb",
+     "model_type": "note",
+     "note_card": {
+      "type": "video",
+      "image_list": [
+       {
+        "image_url": "https://ci.xiaohongshu.com/1040g2sg31tl4iab572e05p9jpr8h1cro1st6hn0?imageView2/2/w/1080/format/webp"
+       }
+      ],
+      "user": {
+       "nick_name": "时间(世间)旅行家",
+       "avatar": "https://sns-avatar-qc.xhscdn.com/avatar/1040g2jo31t9hb3rdm8005p9jpr8h1cro2pkq3eo?imageView2/2/w/80/format/jpg",
+       "user_id": "6533ced1000000000400b378",
+       "nickname": "时间(世间)旅行家"
+      },
+      "display_title": "彩虹🌈",
+      "desc": "见者好运❤️🧡💛💚🩵💙💜太美啦!遇到喀纳斯雨后的双彩虹🌈#好运彩虹  #雨后彩虹🌈  #风雨过后见彩虹",
+      "interact_info": {
+       "collected_count": 14,
+       "comment_count": 2,
+       "shared_count": 43,
+       "liked_count": 43
+      },
+      "publish_timestamp": 1773381785
+     }
+    },
+    {
+     "id": "6a23efa6000000002100adc6",
+     "model_type": "note",
+     "note_card": {
+      "type": "video",
+      "image_list": [
+       {
+        "image_url": "https://ci.xiaohongshu.com/1040g0083212p7jt9nk6g5pqduokndra1lmjbvgg?imageView2/2/w/1080/format/webp"
+       }
+      ],
+      "user": {
+       "nick_name": "难-原创素材分享",
+       "avatar": "https://sns-avatar-qc.xhscdn.com/avatar/1040g2jo3212nieb37e6g5pqduokndra1fsja7fo?imageView2/2/w/80/format/jpg",
+       "user_id": "674df629000000001d02ed41",
+       "nickname": "难-原创素材分享"
+      },
+      "display_title": null,
+      "desc": "赛里木湖双彩虹视频素材",
+      "interact_info": {
+       "collected_count": 3,
+       "comment_count": 2,
+       "shared_count": 0,
+       "liked_count": 43
+      },
+      "publish_timestamp": 1780740006
+     }
+    },
+    {
+     "id": "699ebbf600000000220394b4",
+     "model_type": "note",
+     "note_card": {
+      "type": "video",
+      "image_list": [
+       {
+        "image_url": "https://ci.xiaohongshu.com/1040g2sg31t0mco4n5ee05oju7548cu4ei76k0s0?imageView2/2/w/1080/format/webp"
+       }
+      ],
+      "user": {
+       "nick_name": "多杰",
+       "avatar": "https://sns-avatar-qc.xhscdn.com/avatar/1040g2jo31raodq14n0005oju7548cu4e2f3g330?imageView2/2/w/80/format/jpg",
+       "user_id": "627e3948000000002102788e",
+       "nickname": "多杰"
+      },
+      "display_title": "#川西 #色达 #彩虹 #风雨过后见彩虹",
+      "desc": "#川西  #色达  #彩虹  #风雨过后见彩虹",
+      "interact_info": {
+       "collected_count": 6,
+       "comment_count": 1,
+       "shared_count": 2,
+       "liked_count": 28
+      },
+      "publish_timestamp": 1772010486
+     }
+    },
+    {
+     "id": "68590334000000002203301b",
+     "model_type": "note",
+     "note_card": {
+      "type": "video",
+      "image_list": [
+       {
+        "image_url": "https://ci.xiaohongshu.com/1040g2sg31j2jldsk1a205o2v6geg8njdc0p97cg?imageView2/2/w/1080/format/webp"
+       }
+      ],
+      "user": {
+       "nick_name": "拾光",
+       "avatar": "https://sns-avatar-qc.xhscdn.com/avatar/1040g2jo31gmjnqgh3q605o2v6geg8njdu3ba8v0?imageView2/2/w/80/format/jpg",
+       "user_id": "605f341d0000000001005e6d",
+       "nickname": "拾光"
+      },
+      "display_title": "彩虹🌈的约定",
+      "desc": "#剪映  雨后初霁,天空展开了一幅绚丽的绘卷。橙红的云朵如燃烧的火焰,在天际肆意蔓延,似是大自然积蓄的热情,在此刻迸发",
+      "interact_info": {
+       "collected_count": 14,
+       "comment_count": 3,
+       "shared_count": 17,
+       "liked_count": 50
+      },
+      "publish_timestamp": 1750663988
+     }
+    },
+    {
+     "id": "687e0b9f00000000100278ff",
+     "model_type": "note",
+     "note_card": {
+      "type": "video",
+      "image_list": [
+       {
+        "image_url": "https://ci.xiaohongshu.com/1040g2sg31k6ob0q5igeg5q3ed2unipdm6o5lu3g?imageView2/2/w/1080/format/webp"
+       }
+      ],
+      "user": {
+       "nick_name": "曜灵阁",
+       "avatar": "https://sns-avatar-qc.xhscdn.com/avatar/1040g2jo31kdb9k323q6g5q3ed2unipdmcf98er0?imageView2/2/w/80/format/jpg",
+       "user_id": "686e68bd000000001e0165b6",
+       "nickname": "曜灵阁"
+      },
+      "display_title": "大海上的闪电与彩虹",
+      "desc": "虹电共现#雨后见彩虹  #遇见彩虹  #七彩祥云  #打雷闪电暴雨  #奇幻的云彩  #电闪雷鸣狂风又暴雨  #彩虹",
+      "interact_info": {
+       "collected_count": 27,
+       "comment_count": 1,
+       "shared_count": 9,
+       "liked_count": 75
+      },
+      "publish_timestamp": 1753090975
+     }
+    },
+    {
+     "id": "68678624000000001202e4a5",
+     "model_type": "note",
+     "note_card": {
+      "type": "video",
+      "image_list": [
+       {
+        "image_url": "https://ci.xiaohongshu.com/1040g00831jgpa1egj06g5p558pnamoakuc658fg?imageView2/2/w/1080/format/webp"
+       }
+      ],
+      "user": {
+       "nick_name": "折耳根杨",
+       "avatar": "https://sns-avatar-qc.xhscdn.com/avatar/1040g2jo31n1q7op06g6g5p558pnamoak7uh9fb8?imageView2/2/w/80/format/jpg",
+       "user_id": "64a5466e000000002a036154",
+       "nickname": "折耳根杨"
+      },
+      "display_title": null,
+      "desc": "暴雨倾盆而下,狠狠冲刷过抚仙湖 。待雨幕褪去,一道绚烂彩虹如梦幻桥架,稳稳横跨澄澈湖面 #抚仙湖  #风雨过后见彩虹",
+      "interact_info": {
+       "collected_count": 41,
+       "comment_count": 9,
+       "shared_count": 94,
+       "liked_count": 138
+      },
+      "publish_timestamp": 1751615012
+     }
+    },
+    {
+     "id": "688d816d0000000023026958",
+     "model_type": "note",
+     "note_card": {
+      "type": "video",
+      "image_list": [
+       {
+        "image_url": "https://ci.xiaohongshu.com/1040g00831kls8qqe346g5nujf86gbs62eaj7888?imageView2/2/w/1080/format/webp"
+       }
+      ],
+      "user": {
+       "nick_name": "展翅飞翔(约拍)",
+       "avatar": "https://sns-avatar-qc.xhscdn.com/avatar/1040g2jo31o1ounlr6m6g5nujf86gbs622kmsvt0?imageView2/2/w/80/format/jpg",
+       "user_id": "5fd37a0d000000000101f0c2",
+       "nickname": "展翅飞翔(约拍)"
+      },
+      "display_title": "🌈 雨后天晴,彩虹如诗",
+      "desc": "“东边日出西边雨,道是无晴却有晴。”正如刘禹锡所描绘的这般美景,一场夏雨过后,天地间忽然架起了一道七彩虹桥。彩虹横跨天际",
+      "interact_info": {
+       "collected_count": 22,
+       "comment_count": 3,
+       "shared_count": 77,
+       "liked_count": 60
+      },
+      "publish_timestamp": 1754104174
+     }
+    },
+    {
+     "id": "69378e9d000000001e00b175",
+     "model_type": "note",
+     "note_card": {
+      "type": "video",
+      "image_list": [
+       {
+        "image_url": "https://ci.xiaohongshu.com/1040g2sg31prpbvac3qhg5oduuogk1530p0nbmp8?imageView2/2/w/1080/format/webp"
+       }
+      ],
+      "user": {
+       "nick_name": "幸运7",
+       "avatar": "https://sns-avatar-qc.xhscdn.com/avatar/61bef65042a714f551490c2f.jpg?imageView2/2/w/80/format/jpg",
+       "user_id": "61bef6210000000010009460",
+       "nickname": "幸运7"
+      },
+      "display_title": "🌈 雨后彩虹,海天一色的奇观",
+      "desc": "风雨过后,天空架起彩虹桥,大海也温柔起来。🌊🌈 #自然风光 #彩虹奇观#彩虹  #怎么去拥有一道彩虹  #彩虹的约定",
+      "interact_info": {
+       "collected_count": 9,
+       "comment_count": 0,
+       "shared_count": 3,
+       "liked_count": 51
+      },
+      "publish_timestamp": 1765248669
+     }
+    },
+    {
+     "id": "69f5ea2f0000000036019e69",
+     "model_type": "note",
+     "note_card": {
+      "type": "video",
+      "image_list": [
+       {
+        "image_url": "https://ci.xiaohongshu.com/1040g2sg31vlqrvhh3qe05n825k05k4gnec04cv0?imageView2/2/w/1080/format/webp"
+       }
+      ],
+      "user": {
+       "nick_name": "木子希同学",
+       "avatar": "https://sns-avatar-qc.xhscdn.com/avatar/1040g2jo320dmkiebm8005n825k05k4gnq8cbbpo?imageView2/2/w/80/format/jpg",
+       "user_id": "5d022d000000000016021217",
+       "nickname": "木子希同学"
+      },
+      "display_title": "5月2日北京❗️拍到了飞机穿过彩虹",
+      "desc": "天时地利人和的一条视频 我刚好看向窗外 看到浅浅的彩虹🌈 上楼顶2分钟后 看到了很清晰的彩虹🌈 放大拍到了飞机飞过彩",
+      "interact_info": {
+       "collected_count": 138,
+       "comment_count": 96,
+       "shared_count": 155,
+       "liked_count": 1099
+      },
+      "publish_timestamp": 1777723951
+     }
+    },
+    {
+     "id": "686b335a000000002400b03e",
+     "model_type": "note",
+     "note_card": {
+      "type": "video",
+      "image_list": [
+       {
+        "image_url": "https://ci.xiaohongshu.com/1040g2sg31jkc4ilj2uc04a6pt2s6smeqncjep28?imageView2/2/w/1080/format/webp"
+       }
+      ],
+      "user": {
+       "nick_name": "私鱼空间",
+       "avatar": "https://sns-avatar-qc.xhscdn.com/avatar/1040g2jo31r1u344j7o004a6pt2s6smeq8437l90?imageView2/2/w/80/format/jpg",
+       "user_id": "5b3b386e4eacab4773ca59da",
+       "nickname": "私鱼空间"
+      },
+      "display_title": "彩虹瀑布太美啦",
+      "desc": "#站在高处看景  万马奔腾从天落 银河倒挂震山河 站在亚洲第一大瀑布前 水雾扑面,轰鸣贯耳 瞬间被大自然的磅礴之力征服",
+      "interact_info": {
+       "collected_count": 21,
+       "comment_count": 4,
+       "shared_count": 35,
+       "liked_count": 26
+      },
+      "publish_timestamp": 1751855962
+     }
+    },
+    {
+     "id": "6883327c0000000012014429",
+     "model_type": "note",
+     "note_card": {
+      "type": "video",
+      "image_list": [
+       {
+        "image_url": "https://ci.xiaohongshu.com/1040g2sg31kbpdsjb36sg4a52de2t469m93akqog?imageView2/2/w/1080/format/webp"
+       }
+      ],
+      "user": {
+       "nick_name": "肖尧Numen",
+       "avatar": "https://sns-avatar-qc.xhscdn.com/avatar/647947937f644b3ecc2577bb.jpg?imageView2/2/w/80/format/jpg",
+       "user_id": "5aecc5d2e8ac2b7410651936",
+       "nickname": "肖尧Numen"
+      },
+      "display_title": "川西的含金量,同一天同一地点看到三道彩虹!",
+      "desc": "#彩虹  #斯人若彩虹遇上方知有  #川西  #与高原同频呼吸  #雨过天晴时见彩虹",
+      "interact_info": {
+       "collected_count": 33,
+       "comment_count": 17,
+       "shared_count": 52,
+       "liked_count": 321
+      },
+      "publish_timestamp": 1753428604
+     }
+    },
+    {
+     "id": "69bfb51c000000001b00337c",
+     "model_type": "note",
+     "note_card": {
+      "type": "video",
+      "image_list": [
+       {
+        "image_url": "https://ci.xiaohongshu.com/1040g00831u0t0bnoha005n99gmukgbuvpsufnko?imageView2/2/w/1080/format/webp"
+       }
+      ],
+      "user": {
+       "nick_name": "深白的影像诗",
+       "avatar": "https://sns-avatar-qc.xhscdn.com/avatar/613bdae2cf905f6ad0f381af.jpg?imageView2/2/w/80/format/jpg",
+       "user_id": "5d2985bd0000000012002fdf",
+       "nickname": "深白的影像诗"
+      },
+      "display_title": "3.22大理天空出现超极好看的彩虹",
+      "desc": "雨后天晴,真的太壮观了,小伙伴你们拍到了吗? #大理  #大理旅行  #彩虹🌈  #旅游编辑部  #雨过天晴时见彩虹",
+      "interact_info": {
+       "collected_count": 43,
+       "comment_count": 48,
+       "shared_count": 146,
+       "liked_count": 242
+      },
+      "publish_timestamp": 1774171420
+     }
+    },
+    {
+     "id": "687b8c8000000000120145a1",
+     "model_type": "note",
+     "note_card": {
+      "type": "video",
+      "image_list": [
+       {
+        "image_url": "https://ci.xiaohongshu.com/1040g2sg31k4b36ec3q005opl00fmbpjlfi5ddlo?imageView2/2/w/1080/format/webp"
+       }
+      ],
+      "user": {
+       "nick_name": "📸瀑布拍照不积极🌊",
+       "avatar": "https://sns-avatar-qc.xhscdn.com/avatar/1040g2jo320i14rlhli005opl00fmbpjlun314f8?imageView2/2/w/80/format/jpg",
+       "user_id": "6335001f000000001901e675",
+       "nickname": "📸瀑布拍照不积极🌊"
+      },
+      "display_title": "第一次拍到圆形彩虹🌈!亲眼所见真的是圆的",
+      "desc": "好运爆棚#整点儿摄影节奏  #小红书影像激励计划  #彩虹  #遇见彩虹  #雨后见彩虹  #七彩祥云  #不经历风雨怎",
+      "interact_info": {
+       "collected_count": 29,
+       "comment_count": 17,
+       "shared_count": 18,
+       "liked_count": 182
+      },
+      "publish_timestamp": 1752927360
+     }
+    },
+    {
+     "id": "6867d451000000001203cec1",
+     "model_type": "note",
+     "note_card": {
+      "type": "video",
+      "image_list": [
+       {
+        "image_url": "https://ci.xiaohongshu.com/spectrum/1040g0k031jh2mr64ii005nqqqajgbke6rv1joa0?imageView2/2/w/1080/format/webp"
+       }
+      ],
+      "user": {
+       "nick_name": "Wzkdream",
+       "avatar": "https://sns-avatar-qc.xhscdn.com/avatar/623a994d69241c7f533c07dd.jpg?imageView2/2/w/80/format/jpg",
+       "user_id": "5f5ad2a7000000000101d1c6",
+       "nickname": "Wzkdream"
+      },
+      "display_title": "夏天真是拍彩虹的大好季节!!!",
+      "desc": "很幸运,一场大雨过后,在大理的夏天拍到了圆形彩虹!! #天空之城签约摄影师  #旅游万粉扶持计划  #小红书",
+      "interact_info": {
+       "collected_count": 57,
+       "comment_count": 13,
+       "shared_count": 38,
+       "liked_count": 179
+      },
+      "publish_timestamp": 1751635025
+     }
+    },
+    {
+     "id": "68b2f933000000001c03dfbd",
+     "model_type": "note",
+     "note_card": {
+      "type": "video",
+      "image_list": [
+       {
+        "image_url": "https://ci.xiaohongshu.com/1040g2sg31lqf3hbc50005nl876k093uv90v1u50?imageView2/2/w/1080/format/webp"
+       }
+      ],
+      "user": {
+       "nick_name": "飒美丽",
+       "avatar": "https://sns-avatar-qc.xhscdn.com/avatar/1040g2jo3217p73f7n20g5nl876k093uvakcpjro?imageView2/2/w/80/format/jpg",
+       "user_id": "5ea839a80000000001008fdf",
+       "nickname": "飒美丽"
+      },
+      "display_title": "大理 这彩虹和鸟儿也太治愈了吧",
+      "desc": "#怎么去拥有一道彩虹  #七彩祥云  #向云端许愿  #遇上彩虹吃定彩虹  #五彩斑斓的世界  #雨后见彩虹",
+      "interact_info": {
+       "collected_count": 380,
+       "comment_count": 137,
+       "shared_count": 826,
+       "liked_count": 2363
+      },
+      "publish_timestamp": 1756559667
+     }
+    },
+    {
+     "id": "69f87e7f0000000035028e46",
+     "model_type": "note",
+     "note_card": {
+      "type": "video",
+      "image_list": [
+       {
+        "image_url": "https://ci.xiaohongshu.com/1040g00831vobgqn0kc005ppv6vs7dn1d5ea28v0?imageView2/2/w/1080/format/webp"
+       }
+      ],
+      "user": {
+       "nick_name": "汤姆的移动城堡",
+       "avatar": "https://sns-avatar-qc.xhscdn.com/avatar/1040g2jo31cr1k90u16005ppv6vs7dn1dq3jna30?imageView2/2/w/80/format/jpg",
+       "user_id": "673f37f8000000001d02dc2d",
+       "nickname": "汤姆的移动城堡"
+      },
+      "display_title": "天空出现的罕见“七彩祥云”现象,太美了!!",
+      "desc": "当太阳光线与云彩中的冰晶结构产生折射和反射以后出现的罕见景象! #七彩祥云  #雨后见彩虹  #七彩云  #好运  #彩",
+      "interact_info": {
+       "collected_count": 58,
+       "comment_count": 10,
+       "shared_count": 19,
+       "liked_count": 330
+      },
+      "publish_timestamp": 1777892991
+     }
+    },
+    {
+     "id": "67b6d18d000000000302a9c2",
+     "model_type": "note",
+     "note_card": {
+      "type": "video",
+      "image_list": [
+       {
+        "image_url": "https://ci.xiaohongshu.com/1040g00831e460d0j163g5plg80lnc87ca18eu60?imageView2/2/w/1080/format/webp"
+       }
+      ],
+      "user": {
+       "nick_name": "萌态小可爱",
+       "avatar": "https://sns-avatar-qc.xhscdn.com/avatar/1040g2jo31aqv4oek7g605n8i4d34du3e6cv1v1o?imageView2/2/w/80/format/jpg",
+       "user_id": "5d122346000000001102f86e",
+       "nickname": "萌态小可爱"
+      },
+      "display_title": "风景 雨后彩虹🌈森林湖泊",
+      "desc": "#一起欣赏美丽的景色  #绚丽多彩的世界  #治愈心灵美景  #美景分享给大家  #好美的景色  #好心情从欣赏美景开始",
+      "interact_info": {
+       "collected_count": 10,
+       "comment_count": 1,
+       "shared_count": 5,
+       "liked_count": 24
+      },
+      "publish_timestamp": 1740034445
+     }
+    },
+    {
+     "id": "686e606f00000000170322ad",
+     "model_type": "note",
+     "note_card": {
+      "type": "video",
+      "image_list": [
+       {
+        "image_url": "https://ci.xiaohongshu.com/1040g2sg31jnffbnf34hg5nrno0s0bqg33an7b18?imageView2/2/w/1080/format/webp"
+       }
+      ],
+      "user": {
+       "nick_name": "亦雷Yilei",
+       "avatar": "https://sns-avatar-qc.xhscdn.com/avatar/1040g2jo31pf9s5703c6g5nrno0s0bqg31h25kkg?imageView2/2/w/80/format/jpg",
+       "user_id": "5f77c038000000000101ea03",
+       "nickname": "亦雷Yilei"
+      },
+      "display_title": "风把彩虹揉进甘南的绿野,此刻美到失语",
+      "desc": "#甘南  #彩虹  #风雨过后总会遇见彩虹  #草原",
+      "interact_info": {
+       "collected_count": 17,
+       "comment_count": 2,
+       "shared_count": 16,
+       "liked_count": 37
+      },
+      "publish_timestamp": 1752064111
+     }
+    },
+    {
+     "id": "6908c747000000000301c300",
+     "model_type": "note",
+     "note_card": {
+      "type": "video",
+      "image_list": [
+       {
+        "image_url": "https://ci.xiaohongshu.com/1040g00831oe8elcq5m6g4004sidfoea1tj5bbc8?imageView2/2/w/1080/format/webp"
+       }
+      ],
+      "user": {
+       "nick_name": "阿诺碎碎念",
+       "avatar": "https://sns-avatar-qc.xhscdn.com/avatar/1040g2jo31jjobbjq34dg4004sidfoea1brc94po?imageView2/2/w/80/format/jpg",
+       "user_id": "53eb5afcb4c4d668d4ba3941",
+       "nickname": "阿诺碎碎念"
+      },
+      "display_title": "天安门的彩虹🌈 是祖国给的浪漫暴击!",
+      "desc": "天安门广场直接美到失语!☀️ 湛蓝的天空像被洗过一样,阳光洒在宏伟的天安门城楼上,金光闪闪超有气势~ 音乐喷泉随着旋律舞",
+      "interact_info": {
+       "collected_count": 109,
+       "comment_count": 15,
+       "shared_count": 66,
+       "liked_count": 243
+      },
+      "publish_timestamp": 1762182983
+     }
+    }
+   ]
+  }
+ }
+}

File diff ditekan karena terlalu besar
+ 21 - 0
数据接口与来源/captures/youtube_detail.json


+ 472 - 0
数据接口与来源/captures/youtube_search.json

@@ -0,0 +1,472 @@
+{
+ "label": "youtube_search",
+ "url": "http://crawler.aiddit.com/crawler/youtube/keyword",
+ "request_body": {
+  "keyword": "彩虹"
+ },
+ "response": {
+  "code": 0,
+  "msg": null,
+  "data": {
+   "has_more": true,
+   "next_cursor": "EqMDEgblvanombkamANDQUFTQmdnRkVBRVlBMGdVZ2dFTE1VdEVURlZRWVRBeFdqaUNBUXRRUTNnd1oyeG5URjlVT0lJQkMyeG1aemREYWpkelkzZDNnZ0VMYkRsRmRrcE1MWFI2UVhlQ0FRdHBTRzB4TUVaRVpGcHBaNElCQzNKR05GVXdaRWcyYlhKSmdnRUxaakpSU21nNGF6WnVXbEdDQVF0eGRFOUpabU5YZFd4QmI0SUJDMGhpTjJaVmVHWnNiRGt3Z2dFTE5FZHZObEp0UWsxaVYydUNBUXRuWjJGTFpWTnpNMEpCYjRJQkMxcFdVWGwwWld4cU1FSXdnZ0VMYTJ4cWFERTNWRkZKVlhlQ0FRdDJaVEphVGt0MGRWOWxXWUlCQzJwWFMwbzRUVVI2VGtFMGdnRUxiRzg0YkVoWlZIbDBibU9DQVF0V2JWUllNR1I1Y21oNE9JSUJDMHBIY1cxVlowOU1SV2h6Z2dFTFlURndlR2hhYUU0MGNqQ0NBUXQ0YlZJMmNXRjRaR042UWJJQkJnb0VDQlFRQWclM0QlM0QYgeDoGCILc2VhcmNoLWZlZWQ%3D",
+   "data": [
+    {
+     "video_id": "1KDLUPa01Z8",
+     "title": "宇宙人 Cosmos People【彩虹 Rainbow】歌詞版MV Lyrics Video @CosmosPeople",
+     "duration": "4:22",
+     "view_count": "137,357 views",
+     "published_time": "7 months ago",
+     "author": "滾石唱片 ROCK RECORDS",
+     "channel_id": "UCPcF3KTqhD67ADkukx_OeDg",
+     "thumbnails": [
+      {
+       "url": "https://i.ytimg.com/vi/1KDLUPa01Z8/hq720.jpg?sqp=-oaymwEjCOgCEMoBSFryq4qpAxUIARUAAAAAGAElAADIQj0AgKJDeAE=&rs=AOn4CLDnHwvJ4xGH8vMS237NRl0vOlk9uA",
+       "width": 360,
+       "height": 202
+      },
+      {
+       "url": "https://i.ytimg.com/vi/1KDLUPa01Z8/hq720.jpg?sqp=-oaymwEXCNAFEJQDSFryq4qpAwkIARUAAIhCGAE=&rs=AOn4CLCUQLw6Nn4BHly21YeT-7saOKMNQQ",
+       "width": 720,
+       "height": 404
+      }
+     ],
+     "description_snippet": "【ROCK 歌詞版MV】 歡迎訂閱滾石唱片YouTube官方頻道→ http://bit.ly/RockRecords 宇宙人@CosmosPeople 《彩虹》歌詞 ...",
+     "url": "https://www.youtube.com/watch?v=1KDLUPa01Z8"
+    },
+    {
+     "video_id": "PCx0glgL_T8",
+     "title": "周杰倫《彩虹》吉他彈唱 教學 吉他譜 完整版 全曲演奏 伴奏 動態歌詞 (acoustic) Guitar TAB Jay Chou Rainbow",
+     "duration": "4:25",
+     "view_count": "2,695 views",
+     "published_time": "4 months ago",
+     "author": "大老师乐谱",
+     "channel_id": "UCQQIHhcreczwKK6VUPN6zOA",
+     "thumbnails": [
+      {
+       "url": "https://i.ytimg.com/vi/PCx0glgL_T8/hq720.jpg?sqp=-oaymwEjCOgCEMoBSFryq4qpAxUIARUAAAAAGAElAADIQj0AgKJDeAE=&rs=AOn4CLDm1iY2NlKT1oFb5vroONNLftAXcg",
+       "width": 360,
+       "height": 202
+      },
+      {
+       "url": "https://i.ytimg.com/vi/PCx0glgL_T8/hq720.jpg?sqp=-oaymwEXCNAFEJQDSFryq4qpAwkIARUAAIhCGAE=&rs=AOn4CLBmf9WpAJynJGRgvai_aNlGSerQ0w",
+       "width": 720,
+       "height": 404
+      }
+     ],
+     "description_snippet": "完整吉他谱、各种伴奏for练习表演教学需要的话可以支持一下  :https://item.taobao.com/item.htm?ft=t&id=1015891188712 ps.",
+     "url": "https://www.youtube.com/watch?v=PCx0glgL_T8"
+    },
+    {
+     "video_id": "lfg7Cj7scww",
+     "title": "Cosmos People 宇宙人 [ 彩虹 ] 回到未來1986版 Official Live Video",
+     "duration": "4:27",
+     "view_count": "33,529 views",
+     "published_time": "3 months ago",
+     "author": "宇宙人Cosmos People and 相信音樂BinMusic",
+     "channel_id": "",
+     "thumbnails": [
+      {
+       "url": "https://i.ytimg.com/vi/lfg7Cj7scww/hq720.jpg?sqp=-oaymwEjCOgCEMoBSFryq4qpAxUIARUAAAAAGAElAADIQj0AgKJDeAE=&rs=AOn4CLAwMOa67OmImzy_1zwXolgUZnFpgg",
+       "width": 360,
+       "height": 202
+      },
+      {
+       "url": "https://i.ytimg.com/vi/lfg7Cj7scww/hq720.jpg?sqp=-oaymwEXCNAFEJQDSFryq4qpAwkIARUAAIhCGAE=&rs=AOn4CLDT31SqPYOQuYsR6iQpxsMS8CZVyg",
+       "width": 720,
+       "height": 404
+      }
+     ],
+     "description_snippet": "抱不住的彩虹要怎麼折射故事才能繼續瞳孔那道顏色是不是我愛過的模樣. 在愛與物理的定律之間我們用自己的方式為憂傷加一點 ...",
+     "url": "https://www.youtube.com/watch?v=lfg7Cj7scww"
+    },
+    {
+     "video_id": "l9EvJL-tzAw",
+     "title": "把周杰倫的《彩虹》改編成R&B版是什麼感覺【看不見你的笑我怎麼睡得著】【動態歌詞/Pinyin Lyrics】♫超好聽的流行歌曲(Cover by K.D)",
+     "duration": "4:25",
+     "view_count": "11,323 views",
+     "published_time": "5 months ago",
+     "author": "K.D",
+     "channel_id": "UCjf54RHhVqpq2Ed1egdIYhg",
+     "thumbnails": [
+      {
+       "url": "https://i.ytimg.com/vi/l9EvJL-tzAw/hq720.jpg?sqp=-oaymwEjCOgCEMoBSFryq4qpAxUIARUAAAAAGAElAADIQj0AgKJDeAE=&rs=AOn4CLBmBpULmg0vawuDpNAzsSLmUpjVjQ",
+       "width": 360,
+       "height": 202
+      },
+      {
+       "url": "https://i.ytimg.com/vi/l9EvJL-tzAw/hq720.jpg?sqp=-oaymwEXCNAFEJQDSFryq4qpAwkIARUAAIhCGAE=&rs=AOn4CLBAzEd7tR9KbhoqXrMeWVWWTw0qKQ",
+       "width": 720,
+       "height": 404
+      }
+     ],
+     "description_snippet": "好聽中文流行歌關注K.D就夠了^_^點擊訂閱打開鈴鐺開啟清單循環播放(Playlist): ...",
+     "url": "https://www.youtube.com/watch?v=l9EvJL-tzAw"
+    },
+    {
+     "video_id": "iHm10FDdZig",
+     "title": "[🪷] 彩虹 Neo Soul Reimagined (原唱:周杰伦)",
+     "duration": "4:15",
+     "view_count": "14,830 views",
+     "published_time": "3 weeks ago",
+     "author": "飞行莲花",
+     "channel_id": "UC0bQGGDYqtlIHE7wegEbS-g",
+     "thumbnails": [
+      {
+       "url": "https://i.ytimg.com/vi/iHm10FDdZig/hq720.jpg?sqp=-oaymwEjCOgCEMoBSFryq4qpAxUIARUAAAAAGAElAADIQj0AgKJDeAE=&rs=AOn4CLB0PptFNtX7AFrEv08duYl-BDgYcQ",
+       "width": 360,
+       "height": 202
+      },
+      {
+       "url": "https://i.ytimg.com/vi/iHm10FDdZig/hq720.jpg?sqp=-oaymwEXCNAFEJQDSFryq4qpAwkIARUAAIhCGAE=&rs=AOn4CLDstb59tI19UytlC057EhVITGECqw",
+       "width": 720,
+       "height": 404
+      }
+     ],
+     "description_snippet": "终于排到黑旋风的彩虹了在等这首的留言区见.",
+     "url": "https://www.youtube.com/watch?v=iHm10FDdZig"
+    },
+    {
+     "video_id": "rF4U0dH6mrI",
+     "title": "彩虹",
+     "duration": "4:24",
+     "view_count": "1,125,187 views",
+     "published_time": "",
+     "author": "aMEI - Topic",
+     "channel_id": "UC5M7vIbPTCOMVF3lTtbeO6g",
+     "thumbnails": [
+      {
+       "url": "https://i.ytimg.com/vi/rF4U0dH6mrI/hq720.jpg?sqp=-oaymwEjCOgCEMoBSFryq4qpAxUIARUAAAAAGAElAADIQj0AgKJDeAE=&rs=AOn4CLADv-WrOnYRrk9hZvMwaTTnoefDVA",
+       "width": 360,
+       "height": 202
+      },
+      {
+       "url": "https://i.ytimg.com/vi/rF4U0dH6mrI/hq720.jpg?sqp=-oaymwEXCNAFEJQDSFryq4qpAwkIARUAAIhCGAE=&rs=AOn4CLAloomSEn6nsUZvErNQJ0o5PTCFAg",
+       "width": 720,
+       "height": 404
+      }
+     ],
+     "description_snippet": "Provided to YouTube by Mei Entertainment Ltd 彩虹· 張惠妹阿密特意識專輯℗ Mei Entertainment Ltd Released on: 2009-06-26 ...",
+     "url": "https://www.youtube.com/watch?v=rF4U0dH6mrI"
+    },
+    {
+     "video_id": "f2QJh8k6nZQ",
+     "title": "彩虹(摇滚版) | 艾尔 (EL) Cover| 建议🎧听",
+     "duration": "4:14",
+     "view_count": "25,384 views",
+     "published_time": "4 months ago",
+     "author": "艾尔-EL",
+     "channel_id": "UCytEhKaOgqL9zs8dShxGS9w",
+     "thumbnails": [
+      {
+       "url": "https://i.ytimg.com/vi/f2QJh8k6nZQ/hq720.jpg?sqp=-oaymwEjCOgCEMoBSFryq4qpAxUIARUAAAAAGAElAADIQj0AgKJDeAE=&rs=AOn4CLCnQ-K0gMFg4Vd0g35guQsky4aVDQ",
+       "width": 360,
+       "height": 202
+      },
+      {
+       "url": "https://i.ytimg.com/vi/f2QJh8k6nZQ/hq720.jpg?sqp=-oaymwEXCNAFEJQDSFryq4qpAwkIARUAAIhCGAE=&rs=AOn4CLCx2LP8BkMRihLf-p3IDesie1MCpA",
+       "width": 720,
+       "height": 404
+      }
+     ],
+     "description_snippet": "《彩虹》摇滚版|Original Artist:周杰倫Jay Chou|by:艾尔哪里有彩虹告诉我能不能把我的愿望还给我为什么天这么安静所有的云 ...",
+     "url": "https://www.youtube.com/watch?v=f2QJh8k6nZQ"
+    },
+    {
+     "video_id": "qtOIfcWulAo",
+     "title": "彩虹",
+     "duration": "4:39",
+     "view_count": "2,766 views",
+     "published_time": "",
+     "author": "張心傑 - Topic",
+     "channel_id": "UCVS4gYptsKbH_c1ThDAP4cQ",
+     "thumbnails": [
+      {
+       "url": "https://i.ytimg.com/vi/qtOIfcWulAo/hq720.jpg?sqp=-oaymwEjCOgCEMoBSFryq4qpAxUIARUAAAAAGAElAADIQj0AgKJDeAE=&rs=AOn4CLDQ-bd2ZS5ROz4kJodRb3ANWoJHDg",
+       "width": 360,
+       "height": 202
+      },
+      {
+       "url": "https://i.ytimg.com/vi/qtOIfcWulAo/hq720.jpg?sqp=-oaymwEXCNAFEJQDSFryq4qpAwkIARUAAIhCGAE=&rs=AOn4CLDe9syvQ3mYr4l-Co5nciIZ_esEmQ",
+       "width": 720,
+       "height": 404
+      }
+     ],
+     "description_snippet": "Provided to YouTube by Symphonic Distribution 彩虹· 張心傑《名揚四海》電視原聲帶℗ 2003 友善的狗文化活動股份有限 ...",
+     "url": "https://www.youtube.com/watch?v=qtOIfcWulAo"
+    },
+    {
+     "video_id": "Hb7fUxfll90",
+     "title": "韩国冷门佳作《跨越彩虹》:即使丢失了记忆,我的眼里依然只有你 #影视解说  #电影解说  #一剪到底",
+     "duration": "10:10",
+     "view_count": "482 views",
+     "published_time": "10 months ago",
+     "author": "心房电影",
+     "channel_id": "UCRztmX1dGFAzHQAAi5W6PVA",
+     "thumbnails": [
+      {
+       "url": "https://i.ytimg.com/vi/Hb7fUxfll90/hq720.jpg?sqp=-oaymwEjCOgCEMoBSFryq4qpAxUIARUAAAAAGAElAADIQj0AgKJDeAE=&rs=AOn4CLDPt96SVbGQsXzClCn_gzb8l-iE2g",
+       "width": 360,
+       "height": 202
+      },
+      {
+       "url": "https://i.ytimg.com/vi/Hb7fUxfll90/hq720.jpg?sqp=-oaymwEXCNAFEJQDSFryq4qpAwkIARUAAIhCGAE=&rs=AOn4CLA4NQiT9aZvp3DXKMQI6bQUjH-mHQ",
+       "width": 720,
+       "height": 404
+      }
+     ],
+     "description_snippet": "韩国冷门佳作《跨越彩虹》:即使丢失了记忆,我的眼里依然只有你#影视解说#电影解说#一剪到底.",
+     "url": "https://www.youtube.com/watch?v=Hb7fUxfll90"
+    },
+    {
+     "video_id": "4Go6RmBMbWk",
+     "title": "彩虹 - 周杰倫 | City Pop Remix(女聲版)| 【哪裡有彩虹告訴我 能不能把我的願望還給我】",
+     "duration": "4:44",
+     "view_count": "4,090 views",
+     "published_time": "1 month ago",
+     "author": "音樂迷航地圖",
+     "channel_id": "UCl_wFJ0nFr7KV0OFkrE-xbg",
+     "thumbnails": [
+      {
+       "url": "https://i.ytimg.com/vi/4Go6RmBMbWk/hq720.jpg?sqp=-oaymwEjCOgCEMoBSFryq4qpAxUIARUAAAAAGAElAADIQj0AgKJDeAE=&rs=AOn4CLBwC12XRxO-I9RQIJWMysNPa_F9Ig",
+       "width": 360,
+       "height": 202
+      },
+      {
+       "url": "https://i.ytimg.com/vi/4Go6RmBMbWk/hq720.jpg?sqp=-oaymwEXCNAFEJQDSFryq4qpAwkIARUAAIhCGAE=&rs=AOn4CLCvujDCca6rVwlSapD0NXZOzfmZ1w",
+       "width": 720,
+       "height": 404
+      }
+     ],
+     "description_snippet": "周杰倫2007《我很忙》專輯經典《彩虹》— 這次以女聲詮釋,融入冰球樂團(icyball)retro-cool 的都會復古質感,讓那份「沒有 ...",
+     "url": "https://www.youtube.com/watch?v=4Go6RmBMbWk"
+    },
+    {
+     "video_id": "ggaKeSs3BAo",
+     "title": "彩虹實驗|兒童科學|Learning from Rainbow Science experiments with Kala EE |兒童實驗|親子活動|顏色|廣東話教學|兒童中文學習|kids",
+     "duration": "16:35",
+     "view_count": "143,962 views",
+     "published_time": "10 months ago",
+     "author": "Kala EE 香港兒童教學頻道 Kids learning videos",
+     "channel_id": "UCg2FVjR0oMNEu5_Ja40WPJw",
+     "thumbnails": [
+      {
+       "url": "https://i.ytimg.com/vi/ggaKeSs3BAo/hq720.jpg?sqp=-oaymwEjCOgCEMoBSFryq4qpAxUIARUAAAAAGAElAADIQj0AgKJDeAE=&rs=AOn4CLAxsEPWj9EWSTQddMT1hzYqkWoMcQ",
+       "width": 360,
+       "height": 202
+      },
+      {
+       "url": "https://i.ytimg.com/vi/ggaKeSs3BAo/hq720.jpg?sqp=-oaymwEXCNAFEJQDSFryq4qpAwkIARUAAIhCGAE=&rs=AOn4CLBSAqoOw2RQQE0-nkgtucPDKDTV5Q",
+       "width": 720,
+       "height": 404
+      }
+     ],
+     "description_snippet": "「雨過後有#彩虹  」但唔一定見到喎!暑假大雨/太熱留喺室內親子齊齊玩「#彩虹實驗」啦!有好快好簡單、有培養耐性慢慢觀察嘅 ...",
+     "url": "https://www.youtube.com/watch?v=ggaKeSs3BAo"
+    },
+    {
+     "video_id": "ZVQytelj0B0",
+     "title": "彩虹(動力火車/陳鋕榮編曲)——第8屆南馬獨中合唱觀摩會",
+     "duration": "5:12",
+     "view_count": "2,562 views",
+     "published_time": "11 months ago",
+     "author": "麻坡中化中学合唱团",
+     "channel_id": "UCLggRo6Kux6BtWAUxyZJ1FA",
+     "thumbnails": [
+      {
+       "url": "https://i.ytimg.com/vi/ZVQytelj0B0/hq720.jpg?sqp=-oaymwEjCOgCEMoBSFryq4qpAxUIARUAAAAAGAElAADIQj0AgKJDeAE=&rs=AOn4CLByScTpaC3wNWamv1G7gFGTyglNPQ",
+       "width": 360,
+       "height": 202
+      },
+      {
+       "url": "https://i.ytimg.com/vi/ZVQytelj0B0/hq720.jpg?sqp=-oaymwEXCNAFEJQDSFryq4qpAwkIARUAAIhCGAE=&rs=AOn4CLACro-xeZK4fjEj2mPxB4cBLIuB8Q",
+       "width": 720,
+       "height": 404
+      }
+     ],
+     "description_snippet": "《彩虹》 作词:颜璽轩作曲:陈峰/ 不浪尤干编曲:陈鋕荣原唱:动力火车录音:不走寻常路Skate Strange Studio 指挥:蔡佑君 ...",
+     "url": "https://www.youtube.com/watch?v=ZVQytelj0B0"
+    },
+    {
+     "video_id": "kljh17TQIUw",
+     "title": "一定要试试!免揉面!免擀面!简直软到没朋友!比面包好吃!",
+     "duration": "4:30",
+     "view_count": "4,543 views",
+     "published_time": "2 days ago",
+     "author": "彩虹小厨",
+     "channel_id": "UC_ReTh__D4ZZeaftHZ0GJhA",
+     "thumbnails": [
+      {
+       "url": "https://i.ytimg.com/vi/kljh17TQIUw/hq720.jpg?sqp=-oaymwEjCOgCEMoBSFryq4qpAxUIARUAAAAAGAElAADIQj0AgKJDeAE=&rs=AOn4CLDV_Jw8X-1aE-2VzRmcFuIDLADoqQ",
+       "width": 360,
+       "height": 202
+      },
+      {
+       "url": "https://i.ytimg.com/vi/kljh17TQIUw/hq720.jpg?sqp=-oaymwEXCNAFEJQDSFryq4qpAwkIARUAAIhCGAE=&rs=AOn4CLD59Yl9cZSryVlWE1Zc3mgKuuIYOw",
+       "width": 720,
+       "height": 404
+      }
+     ],
+     "description_snippet": "欢迎来到【彩虹小厨】!这是一个专为你打造的“碳水研究所”。 你是否也经历过:馒头塌陷、面包硬得像石头、面团发酵总是不成功 ...",
+     "url": "https://www.youtube.com/watch?v=kljh17TQIUw"
+    },
+    {
+     "video_id": "ve2ZNKtu_eY",
+     "title": "A New Way to Eat Potatoes! Simple Ingredients! Easy to Make! You'll Want to Make It Every Day!",
+     "duration": "6:04",
+     "view_count": "402 views",
+     "published_time": "3 hours ago",
+     "author": "彩虹小厨",
+     "channel_id": "UC_ReTh__D4ZZeaftHZ0GJhA",
+     "thumbnails": [
+      {
+       "url": "https://i.ytimg.com/vi/ve2ZNKtu_eY/hq720_custom_1.jpg?sqp=CLypqdEG-oaymwEjCOgCEMoBSFryq4qpAxUIARUAAAAAGAElAADIQj0AgKJDeAE=&rs=AOn4CLCt05-DtfM0dZGadwGZXXCmmHcn7g",
+       "width": 360,
+       "height": 202
+      },
+      {
+       "url": "https://i.ytimg.com/vi/ve2ZNKtu_eY/hq720_custom_1.jpg?sqp=CLypqdEG-oaymwEXCNAFEJQDSFryq4qpAwkIARUAAIhCGAE=&rs=AOn4CLCLcKIbzxlbyq3GmJuw2UBdaZqBMQ",
+       "width": 720,
+       "height": 404
+      }
+     ],
+     "description_snippet": "Welcome to [Rainbow Kitchen]! This is a \"Carb Research Institute\" created just for you.\n\nHave you ever experienced: steamed ...",
+     "url": "https://www.youtube.com/watch?v=ve2ZNKtu_eY"
+    },
+    {
+     "video_id": "jWKJ8MDzNA4",
+     "title": "The Demonic Meaning Behind The Rainbow Flag",
+     "duration": "8:20",
+     "view_count": "97,205 views",
+     "published_time": "7 days ago",
+     "author": "Pastor Mark Driscoll",
+     "channel_id": "UCyzD6QsOut9S3e854Ffj41g",
+     "thumbnails": [
+      {
+       "url": "https://i.ytimg.com/vi/jWKJ8MDzNA4/hq720.jpg?sqp=-oaymwEjCOgCEMoBSFryq4qpAxUIARUAAAAAGAElAADIQj0AgKJDeAE=&rs=AOn4CLBX1pPmhkD8-RLOTY7ySDF0pZXW5w",
+       "width": 360,
+       "height": 202
+      },
+      {
+       "url": "https://i.ytimg.com/vi/jWKJ8MDzNA4/hq720.jpg?sqp=-oaymwEXCNAFEJQDSFryq4qpAwkIARUAAIhCGAE=&rs=AOn4CLA7IIPmFFKRI1lF0apR5iPgoVVYkQ",
+       "width": 720,
+       "height": 404
+      }
+     ],
+     "description_snippet": "The rainbow flag is now being flow everywhere, especially in June, and used as symbol of pride. Do you know where that flag ...",
+     "url": "https://www.youtube.com/watch?v=jWKJ8MDzNA4"
+    },
+    {
+     "video_id": "lo8lHYTytnc",
+     "title": "260610 彩虹道體育館 17:07",
+     "duration": "19:29",
+     "view_count": "7 views",
+     "published_time": "15 hours ago",
+     "author": "FLYHIGH PREMIER",
+     "channel_id": "UCaTWed5-Wd7L9Qy6E8XLrKw",
+     "thumbnails": [
+      {
+       "url": "https://i.ytimg.com/vi/lo8lHYTytnc/hq720.jpg?sqp=-oaymwE9COgCEMoBSFryq4qpAy8IARUAAAAAGAElAADIQj0AgKJDeAHwAQH4Af4JgALQBYoCDAgAEAEYciBNKCkwDw==&rs=AOn4CLDFO0K3pugS2uMuipA5UsqFnFnlVQ",
+       "width": 360,
+       "height": 202
+      },
+      {
+       "url": "https://i.ytimg.com/vi/lo8lHYTytnc/hq720.jpg?sqp=-oaymwExCNAFEJQDSFryq4qpAyMIARUAAIhCGAHwAQH4Af4JgALQBYoCDAgAEAEYciBNKCkwDw==&rs=AOn4CLD1I_HpSCdhTG6LNAn5A84SQy7QNA",
+       "width": 720,
+       "height": 404
+      }
+     ],
+     "description_snippet": "",
+     "url": "https://www.youtube.com/watch?v=lo8lHYTytnc"
+    },
+    {
+     "video_id": "VmTX0dyrhx8",
+     "title": "A graduation speech by National Tsing Hua University (NTU) has gone viral on mainland Chinese pla...",
+     "duration": "19:45",
+     "view_count": "22,046 views",
+     "published_time": "5 days ago",
+     "author": "彩虹媽咪",
+     "channel_id": "UCcvD5i0eGBaBBK9FW47WTpw",
+     "thumbnails": [
+      {
+       "url": "https://i.ytimg.com/vi/VmTX0dyrhx8/hqdefault.jpg?sqp=-oaymwEjCOADEI4CSFryq4qpAxUIARUAAAAAGAElAADIQj0AgKJDeAE=&rs=AOn4CLBJ2WJ6LoasR8JI6SnOMJvRB6nNCA",
+       "width": 480,
+       "height": 270
+      }
+     ],
+     "description_snippet": "A graduation speech by National Tsing Hua University (NTU) has gone viral on mainland Chinese platforms, garnering over ten ...",
+     "url": "https://www.youtube.com/watch?v=VmTX0dyrhx8"
+    },
+    {
+     "video_id": "JGqmUgOLEhs",
+     "title": "260610 彩虹道體育館 18:35",
+     "duration": "17:28",
+     "view_count": "8 views",
+     "published_time": "15 hours ago",
+     "author": "FLYHIGH PREMIER",
+     "channel_id": "UCaTWed5-Wd7L9Qy6E8XLrKw",
+     "thumbnails": [
+      {
+       "url": "https://i.ytimg.com/vi/JGqmUgOLEhs/hq720.jpg?sqp=-oaymwE9COgCEMoBSFryq4qpAy8IARUAAAAAGAElAADIQj0AgKJDeAHwAQH4Af4JgALQBYoCDAgAEAEYciBNKCkwDw==&rs=AOn4CLDCZqLFuHZUMJv5rd45IWBW-bRrQA",
+       "width": 360,
+       "height": 202
+      },
+      {
+       "url": "https://i.ytimg.com/vi/JGqmUgOLEhs/hq720.jpg?sqp=-oaymwExCNAFEJQDSFryq4qpAyMIARUAAIhCGAHwAQH4Af4JgALQBYoCDAgAEAEYciBNKCkwDw==&rs=AOn4CLDcycC5dWwizWGXO6uC2RheRCNNPw",
+       "width": 720,
+       "height": 404
+      }
+     ],
+     "description_snippet": "",
+     "url": "https://www.youtube.com/watch?v=JGqmUgOLEhs"
+    },
+    {
+     "video_id": "a1pxhZhN4r0",
+     "title": "Adel is Painting Rainbow on Wood | Best Learning Video for Toddlers",
+     "duration": "13:57",
+     "view_count": "2,698,007 views",
+     "published_time": "7 months ago",
+     "author": "Let's Play",
+     "channel_id": "UC6iyrmtXY7E3QwI-J3PlX-A",
+     "thumbnails": [
+      {
+       "url": "https://i.ytimg.com/vi/a1pxhZhN4r0/hq720.jpg?sqp=-oaymwEjCOgCEMoBSFryq4qpAxUIARUAAAAAGAElAADIQj0AgKJDeAE=&rs=AOn4CLA9qz4_QGHo5FHXT4ADauipgm-rAg",
+       "width": 360,
+       "height": 202
+      },
+      {
+       "url": "https://i.ytimg.com/vi/a1pxhZhN4r0/hq720.jpg?sqp=-oaymwEXCNAFEJQDSFryq4qpAwkIARUAAIhCGAE=&rs=AOn4CLCLN-fzg6wESvopjMUkNfHJcmf1SA",
+       "width": 720,
+       "height": 404
+      }
+     ],
+     "description_snippet": "Join Adel in this fun and creative art adventure where she paints a beautiful rainbow on a wooden board while learning all the ...",
+     "url": "https://www.youtube.com/watch?v=a1pxhZhN4r0"
+    },
+    {
+     "video_id": "xmR6qaxdczA",
+     "title": "Six-Color Rainbow Snack Challenge 🌈 Buy one item and you have to eat them all! SunnyYummy!",
+     "duration": "5:02",
+     "view_count": "54,093 views",
+     "published_time": "3 months ago",
+     "author": "SunnyYummy",
+     "channel_id": "UC3hi3cz42bDrqozo8UkyU1A",
+     "thumbnails": [
+      {
+       "url": "https://i.ytimg.com/vi/xmR6qaxdczA/hq720.jpg?sqp=-oaymwEjCOgCEMoBSFryq4qpAxUIARUAAAAAGAElAADIQj0AgKJDeAE=&rs=AOn4CLD0bCCfONQYLxfsKs4ABRkgQY-cEg",
+       "width": 360,
+       "height": 202
+      },
+      {
+       "url": "https://i.ytimg.com/vi/xmR6qaxdczA/hq720.jpg?sqp=-oaymwEXCNAFEJQDSFryq4qpAwkIARUAAIhCGAE=&rs=AOn4CLDyjOJjFKr69oDqEuhfr0RUh9uF0g",
+       "width": 720,
+       "height": 404
+      }
+     ],
+     "description_snippet": "#RainbowChallenge #SnackChallenge #RainbowSnacks #GoodBaby #GypsyStars #ChildhoodSnacks #TaiwaneseSnacks #FoodieDailyLife ...",
+     "url": "https://www.youtube.com/watch?v=xmR6qaxdczA"
+    }
+   ]
+  }
+ }
+}

+ 12 - 0
数据接口与来源/captures/zhihu_search.json

@@ -0,0 +1,12 @@
+{
+ "label": "zhihu_search",
+ "url": "http://crawler.aiddit.com/crawler/zhi_hu/keyword",
+ "request_body": {
+  "keyword": "彩虹"
+ },
+ "response": {
+  "code": 10000,
+  "msg": "未知错误",
+  "data": null
+ }
+}

+ 14 - 0
数据接口与来源/captures/zhihu_search_retry.json

@@ -0,0 +1,14 @@
+{
+ "label": "zhihu_search_retry",
+ "url": "http://crawler.aiddit.com/crawler/zhi_hu/keyword",
+ "request_body": {
+  "keyword": "彩虹",
+  "cursor": "",
+  "content_type": "综合"
+ },
+ "response": {
+  "code": 10000,
+  "msg": "未知错误",
+  "data": null
+ }
+}

+ 994 - 0
数据接口与来源/crawler_endpoints.registry.json

@@ -0,0 +1,994 @@
+{
+  "registry_version": "crawler_endpoints.v1",
+  "updated_at": "2026-06-11",
+  "purpose": "crawler.aiddit.com 多平台接口的机读台账,接口级。汇总 10 个平台的关键词搜索、内容详情、作者作品、账号画像与视频下载接口的实测状态、输入输出字段和边界,供程序、脚本和审查流程按 source_id / platform 查询。",
+  "authority_note": "本文件是 crawler.aiddit.com 接口级机读索引;人读解释见 00_数据接口总览.md 多平台 crawler 接口一节;外部数据源主索引仍以 external_data_sources_registry.json 为准。每条目逐字段保留各平台 registry 片段原文,仅补 platform 字段。",
+  "status_legend": {
+    "verified": "本批真实抓包 code=0,结构、字段与边界已实测确认。",
+    "verified_unstable": "抓包可成功,但服务端抖动,需重试+退避才稳定(视频号搜索)。",
+    "blocked": "因接口报错、超时、参数限制或平台/接口侧不可用,本批未取得可用样本。",
+    "source_only": "有配置或源码线索,但当前未作为主链路实连。",
+    "missing": "缺真实接口、真实 key、稳定字段或可用配置。"
+  },
+  "source_type_legend": {
+    "http_api": "HTTP API。"
+  },
+  "access_mode_legend": {
+    "read": "只读。",
+    "not_connected": "当前不可连接或不应接入。"
+  },
+  "source_id_prefixes": {
+    "PLT": "平台接入接口。"
+  },
+  "endpoints": [
+    {
+      "platform": "douyin",
+      "source_id": "PLT_DOUYIN_KEYWORD",
+      "display_name": "抖音关键词搜索",
+      "source_type": "http_api",
+      "status": [
+        "verified"
+      ],
+      "system": "crawler.aiddit.com",
+      "table_or_endpoint": "/crawler/dou_yin/keyword",
+      "access_mode": "read",
+      "usage_stages": [],
+      "owner_module": "平台接入模块",
+      "required_env_vars": [
+        "CONTENTFIND_API_CRAWAPI_BASE_URL"
+      ],
+      "input_fields": [
+        "keyword",
+        "content_type",
+        "cursor",
+        "sort_type"
+      ],
+      "output_fields": [
+        "aweme_id",
+        "desc",
+        "caption",
+        "text_extra",
+        "cha_list",
+        "video.play_addr.url_list",
+        "video.download_addr.url_list",
+        "video.duration",
+        "author.uid",
+        "author.sec_uid",
+        "author.unique_id",
+        "author.nickname",
+        "author.signature",
+        "author.follower_count",
+        "statistics.digg_count",
+        "statistics.comment_count",
+        "statistics.share_count",
+        "statistics.collect_count",
+        "create_time",
+        "share_url",
+        "has_more",
+        "next_cursor"
+      ],
+      "v1_boundary": "verified code=0;搜索阶段 author 即含完整档案(sec_uid/粉丝数/签名/抖音号);单条卡片为抖音原生 raw 结构,字段名与 detail 归一化结构不同;视频下载需带 iOS UA + Referer=https://www.douyin.com/;限流间隔>=15s。"
+    },
+    {
+      "platform": "douyin",
+      "source_id": "PLT_DOUYIN_DETAIL",
+      "display_name": "抖音内容详情",
+      "source_type": "http_api",
+      "status": [
+        "verified"
+      ],
+      "system": "crawler.aiddit.com",
+      "table_or_endpoint": "/crawler/dou_yin/detail",
+      "access_mode": "read",
+      "usage_stages": [],
+      "owner_module": "平台接入模块",
+      "required_env_vars": [
+        "CONTENTFIND_API_CRAWAPI_BASE_URL"
+      ],
+      "input_fields": [
+        "content_id"
+      ],
+      "output_fields": [
+        "channel_content_id",
+        "content_link",
+        "title",
+        "body_text",
+        "topic_list",
+        "content_type",
+        "video_url_list",
+        "multi_bitrate",
+        "image_url_list",
+        "channel_account_id",
+        "channel_account_name",
+        "like_count",
+        "comment_count",
+        "share_count",
+        "collect_count",
+        "bgm_data",
+        "publish_timestamp",
+        "is_original",
+        "has_more",
+        "next_cursor"
+      ],
+      "v1_boundary": "verified code=0;归一化结构(channel_content_id/channel_account_id),字段名与搜索 raw 结构不同;无翻页(has_more=false);view_count/play_count 实测为 null;视频下载需 iOS UA + Referer;限流>=15s。"
+    },
+    {
+      "platform": "douyin",
+      "source_id": "PLT_DOUYIN_BLOGGER",
+      "display_name": "抖音博主主页作品列表",
+      "source_type": "http_api",
+      "status": [
+        "verified"
+      ],
+      "system": "crawler.aiddit.com",
+      "table_or_endpoint": "/crawler/dou_yin/blogger",
+      "access_mode": "read",
+      "usage_stages": [],
+      "owner_module": "平台接入模块",
+      "required_env_vars": [
+        "CONTENTFIND_API_CRAWAPI_BASE_URL"
+      ],
+      "input_fields": [
+        "account_id",
+        "cursor"
+      ],
+      "output_fields": [
+        "aweme_id",
+        "desc",
+        "text_extra",
+        "video.play_addr.url_list",
+        "author.sec_uid",
+        "author.nickname",
+        "statistics.digg_count",
+        "statistics.comment_count",
+        "statistics.share_count",
+        "statistics.collect_count",
+        "has_more",
+        "next_cursor"
+      ],
+      "v1_boundary": "verified code=0;account_id 必须传 sec_uid(MS4...);单条作品为 raw aweme 结构(同搜索);next_cursor 为毫秒时间戳游标原样回填 cursor;作者作品需按 aweme_id 与已发现内容去重;限流>=15s。"
+    },
+    {
+      "platform": "douyin",
+      "source_id": "PLT_DOUYIN_AUTHOR_PROFILE",
+      "display_name": "抖音账号粉丝画像",
+      "source_type": "http_api",
+      "status": [
+        "verified"
+      ],
+      "system": "crawler.aiddit.com",
+      "table_or_endpoint": "/crawler/dou_yin/re_dian_bao/account_fans_portrait",
+      "access_mode": "read",
+      "usage_stages": [],
+      "owner_module": "平台接入模块",
+      "required_env_vars": [
+        "CONTENTFIND_API_CRAWAPI_BASE_URL"
+      ],
+      "input_fields": [
+        "account_id",
+        "need_age",
+        "need_gender",
+        "need_province"
+      ],
+      "output_fields": [
+        "account.user_id",
+        "account.nickname",
+        "account.uniqueId",
+        "account.follower_count",
+        "account.aweme_count",
+        "account.total_favorited",
+        "account.first_tag_name",
+        "account.second_tag_name",
+        "account.fans_milestone",
+        "fans.gender",
+        "fans.age",
+        "fans.province",
+        "fans.city",
+        "fans.city_level",
+        "fans.phone_brand",
+        "posts.avg_like_count",
+        "posts.avg_comment_count",
+        "posts.percentile_like_count",
+        "posts.percentile_follower_count",
+        "has_more",
+        "next_cursor"
+      ],
+      "v1_boundary": "verified code=0;account_id 必须 sec_uid;fans 含 6 维人群分布(gender/age/province/city/city_level/phone_brand),展开 50+ 信号,percentage 带 % 需 strip,preference 为 TGI;无翻页;限流>=15s。"
+    },
+    {
+      "platform": "douyin",
+      "source_id": "PLT_DOUYIN_CONTENT_PORTRAIT",
+      "display_name": "抖音内容人群画像(内容画像)",
+      "source_type": "http_api",
+      "status": [
+        "blocked"
+      ],
+      "system": "crawler.aiddit.com",
+      "table_or_endpoint": "/crawler/dou_yin/re_dian_bao/video_like_portrait",
+      "access_mode": "read",
+      "usage_stages": [],
+      "owner_module": "平台接入模块",
+      "required_env_vars": [
+        "CONTENTFIND_API_CRAWAPI_BASE_URL"
+      ],
+      "input_fields": [
+        "content_id",
+        "need_age",
+        "need_gender",
+        "need_province"
+      ],
+      "output_fields": [],
+      "v1_boundary": "blocked;实测 HTTP 404 Not Found(error_body=<html><title>404: Not Found</title>);该 path 当前在 crawler.aiddit.com 不存在,内容级人群画像不可用,需上游确认正确 path 或下线;游走层不要挂该边。"
+    },
+    {
+      "platform": "kuaishou",
+      "source_id": "PLT_KUAISHOU_KEYWORD",
+      "display_name": "快手关键词搜索",
+      "source_type": "http_api",
+      "status": [
+        "verified"
+      ],
+      "system": "crawler.aiddit.com",
+      "table_or_endpoint": "/crawler/kuai_shou/keyword_v2",
+      "access_mode": "read",
+      "usage_stages": [],
+      "owner_module": "平台接入模块",
+      "required_env_vars": [
+        "CONTENTFIND_API_CRAWAPI_BASE_URL"
+      ],
+      "input_fields": [
+        "keyword"
+      ],
+      "output_fields": [
+        "channel_content_id",
+        "content_link",
+        "title",
+        "body_text",
+        "topic_list",
+        "content_type",
+        "video_url_list",
+        "image_url_list",
+        "channel_account_id",
+        "channel_account_name",
+        "view_count",
+        "like_count",
+        "collect_count",
+        "comment_count",
+        "share_count",
+        "publish_timestamp",
+        "has_more",
+        "next_cursor"
+      ],
+      "v1_boundary": "verified code=0;请求体仅 keyword;返回归一化结构;本次实测 has_more=false/next_cursor=null 单页返回;搜索结果只带 channel_account_id/name,无作者粉丝数/签名(需二次 account_info);title/body_text/topic_list 常为 null;视频可下载(206/mp4),下载带 Range + Referer=https://www.kuaishou.com/;限流>=15s。"
+    },
+    {
+      "platform": "kuaishou",
+      "source_id": "PLT_KUAISHOU_DETAIL",
+      "display_name": "快手内容详情",
+      "source_type": "http_api",
+      "status": [
+        "verified"
+      ],
+      "system": "crawler.aiddit.com",
+      "table_or_endpoint": "/crawler/kuai_shou/detail",
+      "access_mode": "read",
+      "usage_stages": [],
+      "owner_module": "平台接入模块",
+      "required_env_vars": [
+        "CONTENTFIND_API_CRAWAPI_BASE_URL"
+      ],
+      "input_fields": [
+        "content_id"
+      ],
+      "output_fields": [
+        "channel_content_id",
+        "content_link",
+        "content_type",
+        "title",
+        "body_text",
+        "topic_list",
+        "video_url_list",
+        "image_url_list",
+        "channel_account_id",
+        "channel_account_name",
+        "avatar",
+        "view_count",
+        "like_count",
+        "collect_count",
+        "comment_count",
+        "share_count",
+        "bgm_data",
+        "publish_timestamp",
+        "has_more",
+        "next_cursor"
+      ],
+      "v1_boundary": "verified code=0;归一化结构;无翻页;title/body_text/topic_list 常 null;同一内容 share_count detail(7)>search(0),以 detail 为准;视频可下载(206/mp4),下载带 Range + Referer;限流>=15s。"
+    },
+    {
+      "platform": "kuaishou",
+      "source_id": "PLT_KUAISHOU_ACCOUNT_INFO",
+      "display_name": "快手账号信息",
+      "source_type": "http_api",
+      "status": [
+        "verified"
+      ],
+      "system": "crawler.aiddit.com",
+      "table_or_endpoint": "/crawler/kuai_shou/account_info",
+      "access_mode": "read",
+      "usage_stages": [],
+      "owner_module": "平台接入模块",
+      "required_env_vars": [
+        "CONTENTFIND_API_CRAWAPI_BASE_URL"
+      ],
+      "input_fields": [
+        "account_id",
+        "is_cache"
+      ],
+      "output_fields": [
+        "channel_account_id",
+        "ks_id",
+        "digit_id",
+        "account_link",
+        "account_name",
+        "avatar_url",
+        "gender",
+        "description",
+        "tags",
+        "follower_count",
+        "publish_count",
+        "like_count",
+        "update_timestamp",
+        "has_more",
+        "next_cursor"
+      ],
+      "v1_boundary": "verified code=0;account_id 用 channel_account_id(如 3xfkwajatdh7p7i)非数字快手号;tags 已结构化(星座+地区);ip_location/collect_count/create_timestamp 实测 null;快手本批未抓到独立作者作品列表接口,author_to_works 在快手侧暂依赖搜索聚合;限流>=15s。"
+    },
+    {
+      "platform": "shipinhao",
+      "source_id": "PLT_SHIPINHAO_KEYWORD",
+      "display_name": "视频号关键词搜索",
+      "source_type": "http_api",
+      "status": "verified_unstable",
+      "system": "crawler.aiddit.com",
+      "table_or_endpoint": "/crawler/shi_pin_hao/keyword",
+      "access_mode": "read",
+      "usage_stages": [],
+      "owner_module": "平台接入模块",
+      "required_env_vars": [
+        "CONTENTFIND_API_CRAWAPI_BASE_URL"
+      ],
+      "input_fields": [
+        "keyword",
+        "cursor"
+      ],
+      "output_fields": [
+        "code",
+        "msg",
+        "data.has_more",
+        "data.next_cursor",
+        "data.data[].channel_content_id",
+        "data.data[].title",
+        "data.data[].content_type",
+        "data.data[].content_link",
+        "data.data[].video_url_list[].video_url",
+        "data.data[].video_url_list[].video_duration",
+        "data.data[].image_url_list[].image_url",
+        "data.data[].channel_account_id",
+        "data.data[].channel_account_name",
+        "data.data[].channel_account_avatar",
+        "data.data[].like_count",
+        "data.data[].collect_count",
+        "data.data[].comment_count",
+        "data.data[].share_count",
+        "data.data[].topic_list",
+        "data.data[].publish_timestamp"
+      ],
+      "v1_boundary": "搜索服务端抖动不稳定:首次 code=25011(视频号接口异常:获取搜索结果失败,见 sph_search.json),重试 code=0 成功有数据(sph_search_retry.json,has_more=true/next_cursor=12)。实现必须带重试+退避;限流≥15s。topic_list 常为 null,tag 需从 title 正则抽;publish_timestamp 为毫秒。"
+    },
+    {
+      "platform": "shipinhao",
+      "source_id": "PLT_SHIPINHAO_VIDEO_DL",
+      "display_name": "视频号视频直链下载",
+      "source_type": "http_api",
+      "status": "verified",
+      "system": "crawler.aiddit.com",
+      "table_or_endpoint": "https://findermp.video.qq.com/.../stodownload (来自 keyword 返回的 video_url)",
+      "access_mode": "read",
+      "usage_stages": [],
+      "owner_module": "平台接入模块",
+      "required_env_vars": [
+        "CONTENTFIND_API_CRAWAPI_BASE_URL"
+      ],
+      "input_fields": [
+        "video_url(encfilekey,token)"
+      ],
+      "output_fields": [
+        "http_status",
+        "content_type",
+        "content_range",
+        "bytes_received",
+        "looks_like_video"
+      ],
+      "v1_boundary": "可下载:http_status=200/content_type=video/mp4/content_range=bytes 0-784921/784922/约784KB(sph_video_dl.json)。下载需带 Referer https://channels.weixin.qq.com/;encfilekey/token 有时效,需搜索后尽快下载。"
+    },
+    {
+      "platform": "shipinhao",
+      "source_id": "PLT_SHIPINHAO_BLOGGER",
+      "display_name": "视频号博主作品列表",
+      "source_type": "http_api",
+      "status": "blocked",
+      "system": "crawler.aiddit.com",
+      "table_or_endpoint": "/crawler/shi_pin_hao/blogger",
+      "access_mode": "read",
+      "usage_stages": [],
+      "owner_module": "平台接入模块",
+      "required_env_vars": [
+        "CONTENTFIND_API_CRAWAPI_BASE_URL"
+      ],
+      "input_fields": [
+        "account_id",
+        "is_cache"
+      ],
+      "output_fields": [],
+      "v1_boundary": "blocked:code=25011(视频号接口异常),data=null(sph_blogger.json)。与搜索同源抖动,作者作品展开当前不可用,author_to_works 边无法落地。"
+    },
+    {
+      "platform": "shipinhao",
+      "source_id": "PLT_SHIPINHAO_ACCOUNT_INFO",
+      "display_name": "视频号账号信息",
+      "source_type": "http_api",
+      "status": "blocked",
+      "system": "crawler.aiddit.com",
+      "table_or_endpoint": "/crawler/shi_pin_hao/account_info",
+      "access_mode": "read",
+      "usage_stages": [],
+      "owner_module": "平台接入模块",
+      "required_env_vars": [
+        "CONTENTFIND_API_CRAWAPI_BASE_URL"
+      ],
+      "input_fields": [
+        "account_id",
+        "is_cache",
+        "app_id|account_name(至少一个)"
+      ],
+      "output_fields": [],
+      "v1_boundary": "blocked:code=10001(参数异常:app_id或account_name至少需要一个),data=null(sph_account_info.json)。本次仅传 account_id 被拒;后续可补 channel_account_name 再试。"
+    },
+    {
+      "platform": "xiaohongshu",
+      "source_id": "PLT_XIAOHONGSHU_KEYWORD",
+      "display_name": "小红书关键词搜索",
+      "source_type": "http_api",
+      "status": "verified",
+      "system": "crawler.aiddit.com",
+      "table_or_endpoint": "/crawler/xiao_hong_shu/keyword",
+      "access_mode": "read",
+      "usage_stages": [],
+      "owner_module": "平台接入模块",
+      "required_env_vars": [
+        "CONTENTFIND_API_CRAWAPI_BASE_URL"
+      ],
+      "input_fields": [
+        "keyword",
+        "content_type",
+        "sort_type",
+        "publish_time",
+        "cursor"
+      ],
+      "output_fields": [
+        "code",
+        "msg",
+        "data.has_more",
+        "data.next_cursor",
+        "data.data[].id",
+        "data.data[].model_type",
+        "data.data[].note_card.type",
+        "data.data[].note_card.display_title",
+        "data.data[].note_card.desc",
+        "data.data[].note_card.image_list[].image_url",
+        "data.data[].note_card.user.user_id",
+        "data.data[].note_card.user.nick_name",
+        "data.data[].note_card.user.nickname",
+        "data.data[].note_card.user.avatar",
+        "data.data[].note_card.interact_info.liked_count",
+        "data.data[].note_card.interact_info.collected_count",
+        "data.data[].note_card.interact_info.comment_count",
+        "data.data[].note_card.interact_info.shared_count",
+        "data.data[].note_card.publish_timestamp"
+      ],
+      "v1_boundary": "verified:code=0 有数据(xhs_search.json,has_more=false/next_cursor=null)。关键提取规则:内容字段全部嵌在 note_card 下——内容ID取 item.id,其余取 item.note_card.*(type/desc/display_title/image_list/user.user_id/user.nick_name/interact_info.*/publish_timestamp),不在顶层找。以图文为主(image_list);视频直链不在搜索结果,需走 detail 二次请求。publish_timestamp 为秒级(注意与 detail 毫秒级不一致)。限流≥15s。"
+    },
+    {
+      "platform": "xiaohongshu",
+      "source_id": "PLT_XIAOHONGSHU_DETAIL",
+      "display_name": "小红书笔记详情",
+      "source_type": "http_api",
+      "status": "verified",
+      "system": "crawler.aiddit.com",
+      "table_or_endpoint": "/crawler/xiao_hong_shu/detail",
+      "access_mode": "read",
+      "usage_stages": [],
+      "owner_module": "平台接入模块",
+      "required_env_vars": [
+        "CONTENTFIND_API_CRAWAPI_BASE_URL"
+      ],
+      "input_fields": [
+        "content_id"
+      ],
+      "output_fields": [
+        "code",
+        "msg",
+        "data.has_more",
+        "data.next_cursor",
+        "data.data.channel_content_id",
+        "data.data.content_link",
+        "data.data.title",
+        "data.data.content_type",
+        "data.data.body_text",
+        "data.data.location",
+        "data.data.topic_list",
+        "data.data.image_url_list[].image_url",
+        "data.data.image_url_list[].image_type",
+        "data.data.video_url_list",
+        "data.data.channel_account_id",
+        "data.data.channel_account_name",
+        "data.data.like_count",
+        "data.data.collect_count",
+        "data.data.comment_count",
+        "data.data.share_count",
+        "data.data.publish_timestamp",
+        "data.data.is_original",
+        "data.data.is_cache"
+      ],
+      "v1_boundary": "verified:code=0 有数据(xhs_detail.json)。详情为扁平结构(非 note_card),字段在 data.data.* 直接取。body_text 比搜索 desc 完整,topic_list 结构化给 tag。video_url_list 本样本为 null(图文笔记)。publish_timestamp 为毫秒(1768657102000),与搜索接口秒级不一致,落库须按接口区分换算。is_cache=true 表缓存命中。"
+    },
+    {
+      "platform": "xiaohongshu",
+      "source_id": "PLT_XIAOHONGSHU_BLOGGER",
+      "display_name": "小红书博主作品列表",
+      "source_type": "http_api",
+      "status": "blocked",
+      "system": "crawler.aiddit.com",
+      "table_or_endpoint": "/crawler/xiao_hong_shu/blogger",
+      "access_mode": "read",
+      "usage_stages": [],
+      "owner_module": "平台接入模块",
+      "required_env_vars": [
+        "CONTENTFIND_API_CRAWAPI_BASE_URL"
+      ],
+      "input_fields": [
+        "account_id",
+        "cursor"
+      ],
+      "output_fields": [],
+      "v1_boundary": "blocked:请求超时 error=timed out(xhs_blogger.json),无响应。需加超时重试+退避;account_id 可由搜索 note_card.user.user_id 提供。author_to_works 边当前不可落地。"
+    },
+    {
+      "platform": "bilibili",
+      "source_id": "PLT_BILIBILI_KEYWORD",
+      "display_name": "Crawapi B站关键词搜索",
+      "source_type": "http_api",
+      "status": "verified",
+      "system": "crawler.aiddit.com",
+      "table_or_endpoint": "/crawler/bilibili/keyword",
+      "access_mode": "read",
+      "usage_stages": [
+        "platform_access",
+        "content_discovery"
+      ],
+      "owner_module": "平台接入模块",
+      "required_env_vars": [
+        "CONTENTFIND_API_CRAWAPI_BASE_URL"
+      ],
+      "input_fields": [
+        "keyword",
+        "cursor"
+      ],
+      "output_fields": [
+        "bvid",
+        "aid",
+        "title",
+        "arcurl",
+        "pic",
+        "description",
+        "author",
+        "mid",
+        "upic",
+        "tag",
+        "play",
+        "like",
+        "favorites",
+        "review",
+        "danmaku",
+        "duration",
+        "pubdate",
+        "typename",
+        "has_more",
+        "next_cursor"
+      ],
+      "v1_boundary": "verified code=0,单次返回 42 条;uid 恒为 0 需弃用以 mid 为准;title 含 <em class=keyword> 需剥;无作者作品接口,author_to_works 不可走。"
+    },
+    {
+      "platform": "bilibili",
+      "source_id": "PLT_BILIBILI_CONTENT_DETAIL",
+      "display_name": "Crawapi B站内容详情",
+      "source_type": "http_api",
+      "status": "verified",
+      "system": "crawler.aiddit.com",
+      "table_or_endpoint": "/crawler/bilibili/detail",
+      "access_mode": "read",
+      "usage_stages": [
+        "platform_access",
+        "content_enrichment"
+      ],
+      "owner_module": "平台接入模块",
+      "required_env_vars": [
+        "CONTENTFIND_API_CRAWAPI_BASE_URL"
+      ],
+      "input_fields": [
+        "content_id"
+      ],
+      "output_fields": [
+        "channel_content_id",
+        "content_link",
+        "title",
+        "body_text",
+        "content_type",
+        "topic_list",
+        "video_url_list",
+        "voice_data",
+        "image_url_list",
+        "channel_account_id",
+        "channel_account_name",
+        "play_count",
+        "like_count",
+        "collect_count",
+        "comment_count",
+        "share_count",
+        "publish_timestamp",
+        "has_more",
+        "next_cursor"
+      ],
+      "v1_boundary": "verified code=0,归一化单对象;video_url_list 视频轨 + voice_data.play_url 音频轨分轨需合并;channel_account_id == search.mid;无作者作品接口。"
+    },
+    {
+      "platform": "bilibili",
+      "source_id": "PLT_BILIBILI_VIDEO_DL",
+      "display_name": "B站视频下载(m4s 直链)",
+      "source_type": "http_api",
+      "status": "verified",
+      "system": "crawler.aiddit.com",
+      "table_or_endpoint": "video_url_list[].video_url (bilivideo.cn m4s 直连 CDN)",
+      "access_mode": "read",
+      "usage_stages": [
+        "material_download"
+      ],
+      "owner_module": "平台接入模块",
+      "required_env_vars": [
+        "CONTENTFIND_API_CRAWAPI_BASE_URL"
+      ],
+      "input_fields": [
+        "video_url",
+        "referer"
+      ],
+      "output_fields": [
+        "http_status",
+        "content_type",
+        "content_range",
+        "bytes_received",
+        "looks_like_video"
+      ],
+      "v1_boundary": "verified 实测 206/octet-stream/1MB 真实视频字节,可下载;必须带 Referer https://www.bilibili.com/;URL 含 deadline 时效签名,过期回详情重取;DASH 分轨需合并。"
+    },
+    {
+      "platform": "weixin",
+      "source_id": "PLT_WEIXIN_KEYWORD",
+      "display_name": "Crawapi 公众号关键词搜索",
+      "source_type": "http_api",
+      "status": "verified",
+      "system": "crawler.aiddit.com",
+      "table_or_endpoint": "/crawler/wei_xin/keyword",
+      "access_mode": "read",
+      "usage_stages": [
+        "platform_access",
+        "content_discovery"
+      ],
+      "owner_module": "平台接入模块",
+      "required_env_vars": [
+        "CONTENTFIND_API_CRAWAPI_BASE_URL"
+      ],
+      "input_fields": [
+        "keyword",
+        "cursor"
+      ],
+      "output_fields": [
+        "url",
+        "title",
+        "cover_url",
+        "time",
+        "nick_name",
+        "biz",
+        "has_more",
+        "next_cursor"
+      ],
+      "v1_boundary": "verified code=0,单次 20 条;nick_name 与 biz 恒为空串,作者 biz 须从 url 正则抽 __biz;title 含 <em class=highlight> 需剥;无 blogger 接口 author_to_works 不可走。"
+    },
+    {
+      "platform": "weixin",
+      "source_id": "PLT_WEIXIN_CONTENT_DETAIL",
+      "display_name": "Crawapi 公众号文章详情",
+      "source_type": "http_api",
+      "status": "verified",
+      "system": "crawler.aiddit.com",
+      "table_or_endpoint": "/crawler/wei_xin/detail",
+      "access_mode": "read",
+      "usage_stages": [
+        "platform_access",
+        "content_enrichment"
+      ],
+      "owner_module": "平台接入模块",
+      "required_env_vars": [
+        "CONTENTFIND_API_CRAWAPI_BASE_URL"
+      ],
+      "input_fields": [
+        "content_link"
+      ],
+      "output_fields": [
+        "channel_content_id",
+        "content_link",
+        "title",
+        "body_text",
+        "content_type",
+        "topic_list",
+        "image_url_list",
+        "video_url_list",
+        "channel_account_id",
+        "channel_account_name",
+        "location",
+        "view_count",
+        "like_count",
+        "publish_timestamp",
+        "has_more",
+        "next_cursor"
+      ],
+      "v1_boundary": "verified code=0,归一化单对象;topic_list 恒 null(无 tag);channel_account_name 恒 null 昵称须 account_info 补;channel_account_id 是网关 hash 非 biz,两者均需沉淀。"
+    },
+    {
+      "platform": "weixin",
+      "source_id": "PLT_WEIXIN_ACCOUNT_INFO",
+      "display_name": "Crawapi 公众号号主信息",
+      "source_type": "http_api",
+      "status": "verified",
+      "system": "crawler.aiddit.com",
+      "table_or_endpoint": "/crawler/wei_xin/account_info",
+      "access_mode": "read",
+      "usage_stages": [
+        "platform_access",
+        "author_enrichment"
+      ],
+      "owner_module": "平台接入模块",
+      "required_env_vars": [
+        "CONTENTFIND_API_CRAWAPI_BASE_URL"
+      ],
+      "input_fields": [
+        "content_link"
+      ],
+      "output_fields": [
+        "channel_account_id",
+        "account_name",
+        "account_link",
+        "biz_info",
+        "wx_gh",
+        "gender",
+        "follower_count",
+        "publish_count"
+      ],
+      "v1_boundary": "verified code=0,公众号作者血缘唯一可达补全(用任一文章 content_link 反查);返回 account_name+biz_info+wx_gh;publish_count=null 无作品列表,author_to_works 仍走不通;粉丝/互动指标多为 null。"
+    },
+    {
+      "platform": "zhihu",
+      "source_id": "PLT_ZHIHU_KEYWORD",
+      "display_name": "Crawapi 知乎关键词搜索",
+      "source_type": "http_api",
+      "status": "blocked",
+      "system": "crawler.aiddit.com",
+      "table_or_endpoint": "/crawler/zhi_hu/keyword",
+      "access_mode": "read",
+      "usage_stages": [
+        "platform_access",
+        "content_discovery"
+      ],
+      "owner_module": "平台接入模块",
+      "required_env_vars": [
+        "CONTENTFIND_API_CRAWAPI_BASE_URL"
+      ],
+      "input_fields": [
+        "keyword",
+        "cursor",
+        "content_type"
+      ],
+      "output_fields": [],
+      "v1_boundary": "blocked:zhihu_search.json 与 zhihu_search_retry.json 两次均 code=10000 未知错误 data=null;整平台不可用,下游内容/作者/tag/下载全部阻断,需上游修复后重新抓包验证。"
+    },
+    {
+      "platform": "youtube",
+      "source_id": "PLT_YOUTUBE_KEYWORD",
+      "display_name": "Crawapi YouTube 关键词搜索",
+      "source_type": "http_api",
+      "status": [
+        "verified"
+      ],
+      "system": "crawler.aiddit.com",
+      "table_or_endpoint": "/crawler/youtube/keyword",
+      "access_mode": "read",
+      "usage_stages": [
+        "platform_access",
+        "content_discovery"
+      ],
+      "owner_module": "平台接入模块",
+      "required_env_vars": [
+        "CONTENTFIND_API_CRAWAPI_BASE_URL"
+      ],
+      "input_fields": [
+        "keyword",
+        "next_cursor"
+      ],
+      "output_fields": [
+        "video_id",
+        "title",
+        "author",
+        "channel_id",
+        "url",
+        "description_snippet",
+        "duration",
+        "view_count",
+        "published_time",
+        "thumbnails",
+        "has_more",
+        "next_cursor"
+      ],
+      "canonical_mapping": {
+        "video_id": "platform_content_id",
+        "channel_id": "platform_author_id",
+        "tags": null
+      },
+      "walk_edges": [
+        "search_page_to_content",
+        "video_to_author"
+      ],
+      "v1_boundary": "verified ✅,capture youtube_search.json code=0,单页约 20 条;has_more=true 时透传 next_cursor(URL-encoded 长 token)翻页。搜索结果无 hashtag 字段;channel_id 可能为空串。"
+    },
+    {
+      "platform": "youtube",
+      "source_id": "PLT_YOUTUBE_DETAIL",
+      "display_name": "Crawapi YouTube 内容详情",
+      "source_type": "http_api",
+      "status": [
+        "verified"
+      ],
+      "system": "crawler.aiddit.com",
+      "table_or_endpoint": "/crawler/youtube/detail",
+      "access_mode": "read",
+      "usage_stages": [
+        "platform_access",
+        "content_discovery"
+      ],
+      "owner_module": "平台接入模块",
+      "required_env_vars": [
+        "CONTENTFIND_API_CRAWAPI_BASE_URL"
+      ],
+      "input_fields": [
+        "content_id"
+      ],
+      "output_fields": [
+        "channel_content_id",
+        "title",
+        "content_link",
+        "body_text",
+        "content_type",
+        "channel_account_id",
+        "channel_account_name",
+        "video_url_list",
+        "image_url_list",
+        "topic_list",
+        "like_count",
+        "comment_count",
+        "publish_timestamp",
+        "is_original",
+        "has_more",
+        "next_cursor"
+      ],
+      "canonical_mapping": {
+        "channel_content_id": "platform_content_id",
+        "channel_account_id": "platform_author_id",
+        "tags": "body_text 正则抽 #xxx"
+      },
+      "walk_edges": [
+        "video_to_author",
+        "video_to_hashtag"
+      ],
+      "v1_boundary": "verified ✅但带重大限制:capture youtube_detail.json code=0,结构完整,但 video_url_list=[] 且 image_url_list=[] → 视频/图片文件不可直取;hashtag 须从 body_text 正则抽(topic_list=null);detail 无翻页(has_more=false)。"
+    },
+    {
+      "platform": "github",
+      "source_id": "PLT_GITHUB_KEYWORD",
+      "display_name": "Crawapi GitHub 关键词搜索(代码仓库)",
+      "source_type": "http_api",
+      "status": [
+        "verified"
+      ],
+      "system": "crawler.aiddit.com",
+      "table_or_endpoint": "/crawler/github/keyword",
+      "access_mode": "read",
+      "usage_stages": [
+        "platform_access",
+        "content_discovery"
+      ],
+      "owner_module": "平台接入模块",
+      "required_env_vars": [
+        "CONTENTFIND_API_CRAWAPI_BASE_URL"
+      ],
+      "input_fields": [
+        "keyword",
+        "token"
+      ],
+      "output_fields": [
+        "id",
+        "hl_name",
+        "hl_trunc_description",
+        "topics",
+        "language",
+        "followers",
+        "archived",
+        "type",
+        "repo.repository.name",
+        "repo.repository.owner_login",
+        "repo.repository.owner_id",
+        "repo.repository.updated_at",
+        "repo.repository.has_issues",
+        "has_more",
+        "next_cursor"
+      ],
+      "canonical_mapping": {
+        "id": "platform_content_id",
+        "repo.repository.owner_id": "platform_author_id",
+        "topics": "tags"
+      },
+      "walk_edges": [
+        "search_page_to_content",
+        "video_to_author",
+        "video_to_hashtag"
+      ],
+      "v1_boundary": "verified ✅,capture github_search.json code=0,单页约 10 条;非视频内容(代码仓库),无 video 字段;has_more=true 时透传 next_cursor(短页码如 '1')回传到请求 token 参数翻页;topics 即 tag(多数为空);content url 须由 hl_name 去 <em> 后拼 https://github.com/{owner/repo};多数 topics=[]、language=null。"
+    },
+    {
+      "platform": "toutiao",
+      "source_id": "PLT_TOUTIAO_KEYWORD",
+      "display_name": "Crawapi 头条号关键词搜索",
+      "source_type": "http_api",
+      "status": [
+        "blocked"
+      ],
+      "system": "crawler.aiddit.com",
+      "table_or_endpoint": "/crawler/tou_tiao_hao/keyword",
+      "access_mode": "read",
+      "usage_stages": [
+        "platform_access",
+        "content_discovery"
+      ],
+      "owner_module": "平台接入模块",
+      "required_env_vars": [
+        "CONTENTFIND_API_CRAWAPI_BASE_URL"
+      ],
+      "input_fields": [
+        "keyword",
+        "content_type",
+        "page"
+      ],
+      "output_fields": [],
+      "canonical_mapping": {},
+      "walk_edges": [],
+      "v1_boundary": "blocked ⛔:toutiao_search.json(keyword=彩虹, content_type=video, page=0)与 toutiao_search_retry.json(去掉 content_type)两次请求均返回 code=10000 / msg=未知错误 / data=null;无成功结构,无字段无翻页;下游链路跳过本平台,待 crawler 侧修复复抓到 code=0 后再解锁登记。"
+    }
+  ]
+}

+ 630 - 0
数据接口与来源/external_data_sources_registry.json

@@ -0,0 +1,630 @@
+{
+  "registry_version": "external_data_sources.v1",
+  "updated_at": "2026-06-07",
+  "purpose": "机器可读的外部数据源总表,供程序、脚本和审查流程查询 ContentFindAgent 可以读取、待接入或明确不能当作已接入的数据来源。",
+  "authority_note": "外部数据源以本文件为机器可读索引;详细中文说明见 00_数据接口总览.md;CFA 自有 DB 表和 runtime 字段见 ../数据库字段总览/content_agent_schema_registry.json。",
+  "status_legend": {
+    "verified": "已有 DB / API 只读验证或旧版实测结果。",
+    "v1_active": "V1 主链路使用或必须接入的来源。",
+    "source_only": "已有配置或源码线索,但当前未作为主链路实连。",
+    "fixture_only": "只用于本地回归、fixture 或兼容导出,不作为生产事实来源。",
+    "blocked": "因 key、token、权限或副作用限制未实连。",
+    "missing": "缺真实接口、真实 key、稳定字段或可用配置。",
+    "deprecated_reference_only": "历史迁移对照,不能作为新版证据来源。"
+  },
+  "source_type_legend": {
+    "mysql_table": "MySQL 表。",
+    "postgres_table": "PostgreSQL 表。",
+    "odps_table": "ODPS / MaxCompute 表。",
+    "http_api": "HTTP API。",
+    "local_json": "本地 JSON 文件,只能作为 fixture、兼容导出或回放材料。",
+    "capability": "能力或外部系统入口,不一定是单一表或单一 API。",
+    "gap": "产品方向存在,但当前没有可用真实来源。"
+  },
+  "access_mode_legend": {
+    "read": "只读。",
+    "read_write": "可读写。",
+    "planned_read": "计划读取,当前未接入代码主链路。",
+    "not_connected": "当前不可连接或不应接入。"
+  },
+  "source_id_prefixes": {
+    "SRC": "数据源与种子。",
+    "QRY": "搜索意图。",
+    "PLT": "平台接入。",
+    "JDG": "判断与回扣。",
+    "WALK": "游走扩展。",
+    "ASSET": "结果沉淀。",
+    "LEARN": "策略学习。",
+    "GAP": "明确缺口。"
+  },
+  "sources": [
+    {
+      "source_id": "SRC_DEMAND_CONTENT_MYSQL",
+      "display_name": "DemandAgent 需求池 MySQL 单表",
+      "source_type": "mysql_table",
+      "status": ["verified", "v1_active"],
+      "system": "content-deconstruction-supply",
+      "table_or_endpoint": "demand_content",
+      "access_mode": "read",
+      "usage_stages": ["source_seed", "search_intent", "learning_review"],
+      "owner_module": "数据源与种子模块",
+      "current_code_refs": [
+        "content_agent/business_modules/source_seed/source_context.py",
+        "content_agent/integrations/demand_source.py",
+        "content_agent/run_service.py",
+        "content_agent/schemas.py"
+      ],
+      "required_env_vars": [
+        "CONTENT_SUPPLY_DB_HOST",
+        "CONTENT_SUPPLY_DB_PORT",
+        "CONTENT_SUPPLY_DB_NAME",
+        "CONTENT_SUPPLY_DB_USER",
+        "CONTENT_SUPPLY_DB_PASSWORD"
+      ],
+      "input_fields": ["id", "merge_leve2", "name", "reason", "suggestion", "ext_data", "score", "dt", "create_time", "update_time"],
+      "required_payload_paths": ["ext_data.evidence_pack"],
+      "output_fields": ["demand_content_id", "evidence_pack", "seed_terms", "source_post_id", "itemset_ids"],
+      "v1_boundary": "真实需求领取读取 demand_content.ext_data.evidence_pack;显式 demand_content_id、run_label、无 selector 默认 pg_pattern_v2 + passed 首条记录均由 CFA 自己的 DB env 接入。本地 JSON 只作 fixture / 回放。",
+      "secret_policy": "只登记 env key,不记录密码。"
+    },
+    {
+      "source_id": "SRC_DEMAND_CONTENT_LOCAL_JSON",
+      "display_name": "DemandAgent 本地 demand_content.json",
+      "source_type": "local_json",
+      "status": ["verified", "fixture_only"],
+      "system": "DemandAgentNew local_json",
+      "table_or_endpoint": "examples/demand/test_output_data/{run_id}/demand_content.json",
+      "access_mode": "read",
+      "usage_stages": ["source_seed", "search_intent"],
+      "owner_module": "数据源与种子模块",
+      "current_code_refs": [
+        "content_agent/business_modules/source_seed/source_context.py",
+        "tests/fixtures/real_case_source/source_context.json"
+      ],
+      "required_env_vars": [],
+      "input_fields": ["merge_leve2", "name", "reason", "suggestion", "score", "ext_data"],
+      "required_payload_paths": ["ext_data.evidence_pack"],
+      "output_fields": ["source_context.json", "pattern_seed_pack.json"],
+      "v1_boundary": "本地回归可用;生产读取和 P0F 应直接使用 MySQL demand_content,本地 JSON 不作为生产事实来源。"
+    },
+    {
+      "source_id": "SRC_WORKFLOW_DECODE_TASK_RESULT",
+      "display_name": "历史 Case 解构结果表",
+      "source_type": "mysql_table",
+      "status": ["verified"],
+      "system": "content-deconstruction-supply",
+      "table_or_endpoint": "workflow_decode_task_result",
+      "access_mode": "planned_read",
+      "usage_stages": ["source_seed", "search_intent", "pattern_recall"],
+      "owner_module": "数据源与种子模块",
+      "current_code_refs": [],
+      "required_env_vars": ["CONTENT_SUPPLY_DB_*"],
+      "input_fields": ["channel_content_id"],
+      "output_fields": ["title", "body_text", "images", "video_url", "channel", "purpose_points", "key_points", "inspiration_points", "topic_fusion_result"],
+      "v1_boundary": "可解释历史 Case,不替代 PG Pattern V2 evidence_pack。"
+    },
+    {
+      "source_id": "SRC_PG_PATTERN_ITEMSET",
+      "display_name": "PG Pattern V2 itemset 与支撑素材",
+      "source_type": "postgres_table",
+      "status": ["verified", "v1_active"],
+      "system": "open_aigc.public",
+      "table_or_endpoint": "pattern_itemset, pattern_itemset_post, pattern_itemset_item",
+      "access_mode": "planned_read",
+      "usage_stages": ["source_seed", "search_intent", "pattern_recall", "learning_review"],
+      "owner_module": "数据源与种子模块",
+      "current_code_refs": [],
+      "required_env_vars": ["OPEN_AIGC_PG_*", "PGVECTOR_DSN", "DATA_ENGINEERING_OPEN_AIGC_PG_DSN"],
+      "input_fields": ["execution_id", "itemset_id", "mining_config_id", "scope"],
+      "output_fields": ["support", "absolute_support", "matched_post_ids", "itemset_items", "category_id", "category_path", "element_name"],
+      "v1_boundary": "新版 evidence_pack 的正式 Pattern 主事实来源。CFA 可通过 DemandAgent evidence_pack 间接消费,不应临时回旧 MySQL 兜底。"
+    },
+    {
+      "source_id": "SRC_PG_PATTERN_CATEGORY",
+      "display_name": "PG Pattern V2 分类快照",
+      "source_type": "postgres_table",
+      "status": ["verified", "v1_active"],
+      "system": "open_aigc.public",
+      "table_or_endpoint": "pattern_mining_category",
+      "access_mode": "planned_read",
+      "usage_stages": ["source_seed", "pattern_recall", "learning_review"],
+      "owner_module": "数据源与种子模块",
+      "current_code_refs": [],
+      "required_env_vars": ["OPEN_AIGC_PG_*", "PGVECTOR_DSN", "DATA_ENGINEERING_OPEN_AIGC_PG_DSN"],
+      "input_fields": ["execution_id", "id", "path", "source_type"],
+      "output_fields": ["name", "description", "category_nature", "level", "parent_id", "element_count"],
+      "v1_boundary": "解释 PG Pattern V2 分类路径,不直接召回平台内容。"
+    },
+    {
+      "source_id": "SRC_PG_PATTERN_ELEMENT",
+      "display_name": "PG Pattern V2 元素快照",
+      "source_type": "postgres_table",
+      "status": ["verified", "v1_active"],
+      "system": "open_aigc.public",
+      "table_or_endpoint": "pattern_mining_element",
+      "access_mode": "planned_read",
+      "usage_stages": ["source_seed", "pattern_recall", "learning_review"],
+      "owner_module": "数据源与种子模块",
+      "current_code_refs": [],
+      "required_env_vars": ["OPEN_AIGC_PG_*", "PGVECTOR_DSN", "DATA_ENGINEERING_OPEN_AIGC_PG_DSN"],
+      "input_fields": ["execution_id", "post_id", "source_table", "source_element_id", "element_type", "element_sub_type", "name"],
+      "output_fields": ["category_path", "point_type", "point_text", "element_name"],
+      "v1_boundary": "用于 PG Pattern V2 解释和新发现内容回扣判断。"
+    },
+    {
+      "source_id": "SRC_OPEN_AIGC_POST",
+      "display_name": "上游历史内容素材表",
+      "source_type": "mysql_table",
+      "status": ["verified"],
+      "system": "open_aigc",
+      "table_or_endpoint": "post",
+      "access_mode": "planned_read",
+      "usage_stages": ["source_seed", "learning_review"],
+      "owner_module": "数据源与种子模块",
+      "current_code_refs": [],
+      "required_env_vars": ["OPEN_AIGC_MYSQL_*"],
+      "input_fields": ["post_id", "platform", "merge_leve1", "merge_leve2", "import_date"],
+      "output_fields": ["title", "body_text", "platform_account_id", "platform_account_name", "publish_timestamp", "like_count", "comment_count", "collect_count", "images"],
+      "v1_boundary": "上游素材理解来源,不是当前 CFA 主链路平台召回。"
+    },
+    {
+      "source_id": "SRC_OPEN_AIGC_TOPIC_POINT_ELEMENT",
+      "display_name": "上游选题点元素表",
+      "source_type": "mysql_table",
+      "status": ["verified"],
+      "system": "open_aigc",
+      "table_or_endpoint": "post_decode_topic_point_element",
+      "access_mode": "planned_read",
+      "usage_stages": ["source_seed", "pattern_recall", "learning_review"],
+      "owner_module": "数据源与种子模块",
+      "current_code_refs": [],
+      "required_env_vars": ["OPEN_AIGC_MYSQL_*"],
+      "input_fields": ["post_id", "topic_point_id", "element_type", "element_sub_type"],
+      "output_fields": ["element_name", "element_description", "element_source", "element_reason"],
+      "v1_boundary": "用于理解上游元素,不替代 workflow_decode_task_result。"
+    },
+    {
+      "source_id": "SRC_OPEN_AIGC_SCRIPT_ELEMENT",
+      "display_name": "上游脚本段落元素表",
+      "source_type": "mysql_table",
+      "status": ["verified"],
+      "system": "open_aigc",
+      "table_or_endpoint": "post_script_paragraph_field_element",
+      "access_mode": "planned_read",
+      "usage_stages": ["source_seed", "learning_review"],
+      "owner_module": "数据源与种子模块",
+      "current_code_refs": [],
+      "required_env_vars": ["OPEN_AIGC_MYSQL_*"],
+      "input_fields": ["post_id", "paragraph_id", "field_type", "element_type", "element_sub_type"],
+      "output_fields": ["element_name", "element_description"],
+      "v1_boundary": "策略学习和素材理解来源。"
+    },
+    {
+      "source_id": "SRC_OLD_MYSQL_TOPIC_PATTERN",
+      "display_name": "旧 MySQL topic_pattern 兼容层",
+      "source_type": "mysql_table",
+      "status": ["verified", "deprecated_reference_only"],
+      "system": "open_aigc_pattern",
+      "table_or_endpoint": "topic_pattern_element, topic_pattern_itemset, topic_pattern_category",
+      "access_mode": "not_connected",
+      "usage_stages": ["migration_reference"],
+      "owner_module": "数据源与种子模块",
+      "current_code_refs": [],
+      "required_env_vars": ["OPEN_AIGC_PATTERN_DB_*", "PATTERN_GLOBAL_DB_*", "CONTENTFIND_PATTERN_DB_*"],
+      "input_fields": ["execution_id", "itemset_id", "category_id"],
+      "output_fields": ["historical_pattern_fields"],
+      "v1_boundary": "只作历史迁移对照,不能进入新版 evidence_pack,不能作为 PG Pattern V2 兜底。"
+    },
+    {
+      "source_id": "PLT_DOUYIN_KEYWORD",
+      "display_name": "Crawapi 抖音关键词搜索",
+      "source_type": "http_api",
+      "status": ["verified", "v1_active"],
+      "system": "Crawapi Douyin",
+      "table_or_endpoint": "/crawler/dou_yin/keyword",
+      "access_mode": "read",
+      "usage_stages": ["platform_access", "content_discovery"],
+      "owner_module": "平台接入模块",
+      "current_code_refs": ["content_agent/integrations/douyin.py", "content_agent/business_modules/platform_access.py"],
+      "required_env_vars": ["CONTENTFIND_API_CRAWAPI_BASE_URL", "CONTENTFIND_DOUYIN_*"],
+      "input_fields": ["keyword", "content_type", "sort_type", "publish_time", "cursor", "account_id"],
+      "output_fields": ["platform_content_id", "desc", "author", "platform_author_id", "statistics", "has_more", "next_cursor"],
+      "v1_boundary": "V1 real 模式已接关键词搜索一页结果;默认每个 search_query 小预算处理。"
+    },
+    {
+      "source_id": "PLT_DOUYIN_DETAIL",
+      "display_name": "Crawapi 抖音内容详情",
+      "source_type": "http_api",
+      "status": ["verified"],
+      "system": "Crawapi Douyin",
+      "table_or_endpoint": "/crawler/dou_yin/detail",
+      "access_mode": "read",
+      "usage_stages": ["platform_access", "content_discovery"],
+      "owner_module": "平台接入模块",
+      "current_code_refs": ["content_agent/integrations/douyin.py", "content_agent/business_modules/platform_access.py"],
+      "required_env_vars": ["CONTENTFIND_API_CRAWAPI_BASE_URL", "CONTENTFIND_DOUYIN_*"],
+      "input_fields": ["content_id"],
+      "output_fields": ["channel_content_id", "content_link", "title", "body_text", "topic_list", "content_type", "video_url_list", "multi_bitrate", "image_url_list", "channel_account_id", "channel_account_name", "like_count", "comment_count", "share_count", "collect_count", "publish_timestamp", "is_original", "has_more", "next_cursor"],
+      "v1_boundary": "2026-06-11 真实 smoke 已确认 code=0,归一化结构(channel_content_id/channel_account_id)与搜索 raw 结构字段名不同;无翻页(has_more=false);view_count/play_count 实测 null;视频下载需 iOS UA + Referer=https://www.douyin.com/。历史漏登,本次补齐。"
+    },
+    {
+      "source_id": "PLT_DOUYIN_AUTHOR_WORKS",
+      "display_name": "Crawapi 抖音账号作品",
+      "source_type": "http_api",
+      "status": ["verified"],
+      "system": "Crawapi Douyin",
+      "table_or_endpoint": "/crawler/dou_yin/blogger",
+      "access_mode": "read",
+      "usage_stages": ["walk_strategy", "content_discovery"],
+      "owner_module": "平台接入模块",
+      "current_code_refs": [
+        "content_agent/integrations/douyin.py::CrawapiDouyinClient.fetch_author_works"
+      ],
+      "required_env_vars": ["CONTENTFIND_API_CRAWAPI_BASE_URL", "CONTENTFIND_DOUYIN_*"],
+      "input_fields": ["account_id", "sort_type", "cursor"],
+      "output_fields": ["platform_content_id", "desc", "author", "statistics", "has_more", "next_cursor"],
+      "v1_boundary": "P6 作者边使用;作品仍需逐条 Pattern 回扣和规则判断。"
+    },
+    {
+      "source_id": "PLT_DOUYIN_CONTENT_PROFILE",
+      "display_name": "热点宝内容点赞画像",
+      "source_type": "http_api",
+      "status": ["verified", "v1_active"],
+      "system": "Crawapi Douyin",
+      "table_or_endpoint": "/crawler/dou_yin/re_dian_bao/video_like_portrait",
+      "access_mode": "read",
+      "usage_stages": ["platform_access", "content_discovery", "rule_judgment"],
+      "owner_module": "平台接入模块",
+      "current_code_refs": ["content_agent/integrations/douyin.py"],
+      "required_env_vars": ["CONTENTFIND_API_CRAWAPI_BASE_URL", "CONTENTFIND_DOUYIN_*"],
+      "input_fields": ["content_id", "need_age", "need_gender", "need_province"],
+      "output_fields": ["age_profile", "gender_profile", "province_profile", "percentage", "preference"],
+      "v1_boundary": "作为内容 50+ 画像信号,不直接代表内容质量。"
+    },
+    {
+      "source_id": "PLT_DOUYIN_AUTHOR_PROFILE",
+      "display_name": "热点宝账号画像",
+      "source_type": "http_api",
+      "status": ["verified"],
+      "system": "Crawapi Douyin",
+      "table_or_endpoint": "/crawler/dou_yin/re_dian_bao/account_fans_portrait",
+      "access_mode": "planned_read",
+      "usage_stages": ["walk_strategy", "rule_judgment"],
+      "owner_module": "平台接入模块",
+      "current_code_refs": [],
+      "required_env_vars": ["CONTENTFIND_API_CRAWAPI_BASE_URL", "CONTENTFIND_DOUYIN_*"],
+      "input_fields": ["account_id", "need_age", "need_gender", "need_province"],
+      "output_fields": ["age_profile", "gender_profile", "province_profile", "percentage", "preference"],
+      "v1_boundary": "作者强不代表作品必然强;V1 不做账号画像兜底。"
+    },
+    {
+      "source_id": "PLT_DOUYIN_HOT_RANK",
+      "display_name": "今日热榜",
+      "source_type": "http_api",
+      "status": ["verified"],
+      "system": "Crawapi Hot Rank",
+      "table_or_endpoint": "/crawler/jin_ri_re_bang/content_rank",
+      "access_mode": "planned_read",
+      "usage_stages": ["source_seed", "search_intent"],
+      "owner_module": "平台接入模块",
+      "current_code_refs": [],
+      "required_env_vars": ["CONTENTFIND_API_CRAWAPI_BASE_URL", "CONTENTFIND_HOT_TOPIC_PATH"],
+      "input_fields": ["sort_type", "cursor"],
+      "output_fields": ["source", "jump_url", "type", "rankList.title", "rankList.heat", "has_more", "next_cursor"],
+      "v1_boundary": "热点只做探索入口,不等于最终内容源。"
+    },
+    {
+      "source_id": "PLT_TIKHUB_SEARCH_FALLBACK",
+      "display_name": "TikHub 抖音搜索备用通道",
+      "source_type": "http_api",
+      "status": ["blocked", "missing"],
+      "system": "TikHub",
+      "table_or_endpoint": "TIKHUB_DOUYIN_SEARCH_PATH",
+      "access_mode": "not_connected",
+      "usage_stages": ["platform_access"],
+      "owner_module": "平台接入模块",
+      "current_code_refs": [],
+      "required_env_vars": ["TIKHUB_API_KEY", "TIKHUB_BASE_URL", "TIKHUB_DOUYIN_SEARCH_PATH"],
+      "input_fields": ["keyword", "cursor", "sort_type", "publish_time", "filter_duration", "content_type", "search_id", "backtrace"],
+      "output_fields": ["business_data", "next_page", "backtrace"],
+      "v1_boundary": "缺 key,不能写成已接入。"
+    },
+    {
+      "source_id": "JDG_DECODE_API",
+      "display_name": "内容解构接口",
+      "source_type": "http_api",
+      "status": ["source_only"],
+      "system": "Aiddit AIGC Decode",
+      "table_or_endpoint": "https://aigc-api.aiddit.com/aigc/api/task/decode, https://aigc-api.aiddit.com/aigc/api/task/decode/result",
+      "access_mode": "read",
+      "usage_stages": ["pattern_recall", "rule_judgment"],
+      "owner_module": "发现内容与证据模块",
+      "current_code_refs": [
+        "content_agent/integrations/decode_api.py::AigcDecodeClient",
+        "content_agent/business_modules/content_discovery/pattern_recall/decode.py::decode_content"
+      ],
+      "required_env_vars": [],
+      "input_fields": ["platform_content_id", "platform_content_url", "configId"],
+      "output_fields": ["decode_status", "purpose_points", "key_points", "inspiration_points", "topic_fusion_result"],
+      "v1_boundary": "当前 CFA 主链路尚未接入;Pattern 回扣必须依赖解构强证据词。"
+    },
+    {
+      "source_id": "JDG_CATEGORY_MATCH_PATHS",
+      "display_name": "分类树 match-paths",
+      "source_type": "http_api",
+      "status": ["verified", "source_only"],
+      "system": "Aiddit Library",
+      "table_or_endpoint": "https://library.aiddit.com/api/search/categories/match-paths/v2",
+      "access_mode": "read",
+      "usage_stages": ["pattern_recall", "rule_judgment"],
+      "owner_module": "发现内容与证据模块",
+      "current_code_refs": [
+        "content_agent/integrations/category_match.py::CategoryMatchClient.match_paths",
+        "content_agent/business_modules/content_discovery/pattern_recall/category_match.py::match_decode_terms"
+      ],
+      "required_env_vars": [],
+      "input_fields": ["source_type", "top_k", "min_score", "items.term", "items.description"],
+      "output_fields": ["matched_category_paths", "score", "matched_terms"],
+      "v1_boundary": "在线向量匹配结果会漂移;2026-06-08 已确认当前 endpoint 为 v2,不能把某次分数写成稳定业务合同。"
+    },
+    {
+      "source_id": "QRY_OPENROUTER",
+      "display_name": "OpenRouter LLM 能力",
+      "source_type": "capability",
+      "status": ["source_only"],
+      "system": "OpenRouter",
+      "table_or_endpoint": "chat completion / tool use",
+      "access_mode": "not_connected",
+      "usage_stages": ["search_intent", "rule_judgment"],
+      "owner_module": "搜索意图模块",
+      "current_code_refs": [],
+      "required_env_vars": ["OPEN_ROUTER_API_KEY", "OPENROUTER_API_KEY", "OPENROUTER_BASE_URL"],
+      "input_fields": ["model", "messages", "tools", "system", "max_tokens", "temperature"],
+      "output_fields": ["content", "tool_calls", "usage", "finish_reason"],
+      "v1_boundary": "本轮只做 key metadata 探测;真实生成必须另开预算和策略开关。"
+    },
+    {
+      "source_id": "ASSET_DEMAND_FIND_CONTENT_RESULT",
+      "display_name": "旧版内容结果沉淀表",
+      "source_type": "mysql_table",
+      "status": ["verified"],
+      "system": "content-deconstruction-supply",
+      "table_or_endpoint": "demand_find_content_result",
+      "access_mode": "planned_read",
+      "usage_stages": ["asset_commit", "learning_review"],
+      "owner_module": "结果沉淀与来源反查模块",
+      "current_code_refs": [],
+      "required_env_vars": ["CONTENT_SUPPLY_DB_*"],
+      "input_fields": ["run_id", "query", "rank_no", "channel", "platform_content_id", "demand_content_id"],
+      "output_fields": ["video_url", "title", "author_name", "author_id", "process_trace", "crawler_plan_id", "produce_plan_id", "publish_plan_id", "web_html_url"],
+      "v1_boundary": "旧版只沉淀最终内容,不保存全量发现内容和结构化淘汰原因。"
+    },
+    {
+      "source_id": "ASSET_DEMAND_FIND_AUTHOR",
+      "display_name": "旧版作者资产表",
+      "source_type": "mysql_table",
+      "status": ["verified"],
+      "system": "content-deconstruction-supply",
+      "table_or_endpoint": "demand_find_author",
+      "access_mode": "planned_read",
+      "usage_stages": ["walk_strategy", "asset_commit", "learning_review"],
+      "owner_module": "结果沉淀与来源反查模块",
+      "current_code_refs": [],
+      "required_env_vars": ["CONTENT_SUPPLY_DB_*"],
+      "input_fields": ["author_id", "author_name", "author_link", "content_tags", "channel"],
+      "output_fields": ["elderly_ratio", "elderly_tgi", "is_good", "remark"],
+      "v1_boundary": "历史作者参考不进入 P6 V1 默认边;作者资产启用等 P6 作者边实现后再处理。"
+    },
+    {
+      "source_id": "LEARN_DEMAND_FIND_TASK",
+      "display_name": "旧版任务级 run_context 表",
+      "source_type": "mysql_table",
+      "status": ["verified"],
+      "system": "content-deconstruction-supply",
+      "table_or_endpoint": "demand_find_task",
+      "access_mode": "planned_read",
+      "usage_stages": ["learning_review"],
+      "owner_module": "策略学习模块",
+      "current_code_refs": [],
+      "required_env_vars": ["CONTENT_SUPPLY_DB_*"],
+      "input_fields": ["run_id", "demand_content_id", "status", "created_at", "token_coast"],
+      "output_fields": ["task_status", "cost", "demand_relation"],
+      "v1_boundary": "只能看任务级结果,不能还原全量发现内容过程。"
+    },
+    {
+      "source_id": "LEARN_DEMAND_TASK_OPRATE",
+      "display_name": "旧版调度和预算开关表",
+      "source_type": "mysql_table",
+      "status": ["source_only"],
+      "system": "content-deconstruction-supply",
+      "table_or_endpoint": "demand_task_oprate",
+      "access_mode": "planned_read",
+      "usage_stages": ["learning_review", "policy_version"],
+      "owner_module": "策略学习模块",
+      "current_code_refs": [],
+      "required_env_vars": ["CONTENT_SUPPLY_DB_*"],
+      "input_fields": ["is_open", "day_limit_coast", "update_time"],
+      "output_fields": ["enabled", "daily_budget"],
+      "v1_boundary": "策略控制数据,不是学习结论。"
+    },
+    {
+      "source_id": "ASSET_AIGC_PLAN_DETAIL",
+      "display_name": "AIGC 后处理计划详情",
+      "source_type": "http_api",
+      "status": ["source_only", "blocked"],
+      "system": "AIGC plan",
+      "table_or_endpoint": "produce plan detail / crawler plan / publish plan",
+      "access_mode": "not_connected",
+      "usage_stages": ["asset_commit", "publish_job"],
+      "owner_module": "结果沉淀与来源反查模块",
+      "current_code_refs": [],
+      "required_env_vars": ["AIGC_TOKEN", "CONTENTFIND_API_AIGC_TOKEN", "CONTENTFIND_API_READONLY_TOKEN", "CONTENTFIND_AIGC_READONLY_PRODUCE_PLAN_ID"],
+      "input_fields": ["platform_content_id", "merge_leve2", "produce_plan_id", "account_id", "sort_type"],
+      "output_fields": ["crawler_plan_id", "produce_plan_id", "produce_plan_name", "publish_plan_id"],
+      "v1_boundary": "写侧有副作用;V1 已拍板不自动触发发布接口。"
+    },
+    {
+      "source_id": "ASSET_OSS_LOG_HTML",
+      "display_name": "OSS 过程可视化链接",
+      "source_type": "capability",
+      "status": ["source_only", "blocked", "missing"],
+      "system": "Aliyun OSS",
+      "table_or_endpoint": "OSS object storage",
+      "access_mode": "not_connected",
+      "usage_stages": ["asset_commit", "run_record"],
+      "owner_module": "运行记录模块",
+      "current_code_refs": [],
+      "required_env_vars": ["ALIYUN_OSS_ACCESS_KEY_ID", "ALIYUN_OSS_ACCESS_KEY_SECRET", "ALIYUN_OSS_BUCKET", "ALIYUN_OSS_REGION", "ALIYUN_OSS_PREFIX", "ALIYUN_OSS_PUBLIC_BASE_URL"],
+      "input_fields": ["html_path", "object_key", "task_id"],
+      "output_fields": ["web_html_url"],
+      "v1_boundary": "缺真实 OSS 配置;不能写成已接入。"
+    },
+    {
+      "source_id": "LEARN_ODPS_DEMAND_POOL",
+      "display_name": "ODPS 需求池表现参考",
+      "source_type": "odps_table",
+      "status": ["verified"],
+      "system": "ODPS",
+      "table_or_endpoint": "dwd_multi_demand_pool_di",
+      "access_mode": "planned_read",
+      "usage_stages": ["learning_review"],
+      "owner_module": "策略学习模块",
+      "current_code_refs": [],
+      "required_env_vars": ["ODPS_ACCESS_ID", "ODPS_ACCESS_KEY", "ODPS_ENDPOINT", "ODPS_PROJECT"],
+      "input_fields": ["strategy", "demand_id", "demand_name", "weight", "type", "video_count", "video_list", "extend", "dt"],
+      "output_fields": ["demand_performance", "video_list"],
+      "v1_boundary": "表现参考,不是实时判断输入。"
+    },
+    {
+      "source_id": "LEARN_ODPS_FEATURE_POINT",
+      "display_name": "ODPS 特征点表现参考",
+      "source_type": "odps_table",
+      "status": ["verified"],
+      "system": "ODPS",
+      "table_or_endpoint": "feature_point_data",
+      "access_mode": "planned_read",
+      "usage_stages": ["learning_review"],
+      "owner_module": "策略学习模块",
+      "current_code_refs": [],
+      "required_env_vars": ["ODPS_ACCESS_ID", "ODPS_ACCESS_KEY", "ODPS_ENDPOINT", "ODPS_PROJECT"],
+      "input_fields": ["特征点", "分发视频量", "vid_list", "dt"],
+      "output_fields": ["曝光", "回流", "播放", "视频列表"],
+      "v1_boundary": "用于后续策略学习,不是 V1 实时评分表。"
+    },
+    {
+      "source_id": "LEARN_LOGHUB_VIDEO_DIMENSION",
+      "display_name": "视频表现宽表",
+      "source_type": "odps_table",
+      "status": ["verified"],
+      "system": "loghubods",
+      "table_or_endpoint": "video_dimension_detail_add_column",
+      "access_mode": "planned_read",
+      "usage_stages": ["learning_review"],
+      "owner_module": "策略学习模块",
+      "current_code_refs": [],
+      "required_env_vars": ["ODPS_ACCESS_ID", "ODPS_ACCESS_KEY", "ODPS_ENDPOINT", "ODPS_PROJECT"],
+      "input_fields": ["视频id", "视频地址", "标题", "一级品类", "二级品类", "上传渠道", "dt"],
+      "output_fields": ["曝光", "播放", "回流", "标签"],
+      "v1_boundary": "宽表只列策略学习关键字段。"
+    },
+    {
+      "source_id": "LEARN_GLOBAL_TAXONOMY",
+      "display_name": "open_aigc 全局分类与元素",
+      "source_type": "mysql_table",
+      "status": ["verified"],
+      "system": "open_aigc",
+      "table_or_endpoint": "global_category, global_element, element_classification_mapping",
+      "access_mode": "planned_read",
+      "usage_stages": ["pattern_recall", "learning_review"],
+      "owner_module": "策略学习模块",
+      "current_code_refs": [],
+      "required_env_vars": ["OPEN_AIGC_MYSQL_*"],
+      "input_fields": ["stable_id", "name", "source_type", "path", "source_element_id", "post_id", "classification_path"],
+      "output_fields": ["category_tree", "global_element", "classification_mapping"],
+      "v1_boundary": "长期概念分类来源;不替代在线 match-paths。"
+    },
+    {
+      "source_id": "GAP_XIAOHONGSHU_PLATFORM",
+      "display_name": "小红书笔记、作者、话题接口",
+      "source_type": "gap",
+      "status": ["missing"],
+      "system": "xiaohongshu",
+      "table_or_endpoint": "not_available",
+      "access_mode": "not_connected",
+      "usage_stages": ["platform_access", "walk_strategy"],
+      "owner_module": "平台接入模块",
+      "current_code_refs": [],
+      "required_env_vars": [],
+      "input_fields": [],
+      "output_fields": [],
+      "v1_boundary": "产品可以设计,但技术文档不能写成已接入。"
+    },
+    {
+      "source_id": "GAP_OTHER_PLATFORMS",
+      "display_name": "快手、B站、视频号、票圈等平台",
+      "source_type": "gap",
+      "status": ["missing"],
+      "system": "multi_platform",
+      "table_or_endpoint": "not_available",
+      "access_mode": "not_connected",
+      "usage_stages": ["platform_access"],
+      "owner_module": "平台接入模块",
+      "current_code_refs": [],
+      "required_env_vars": [],
+      "input_fields": [],
+      "output_fields": [],
+      "v1_boundary": "暂时不能复用抖音字段口径。"
+    },
+    {
+      "source_id": "GAP_RELATED_DISCOVERY",
+      "display_name": "相关搜索、视频 tag、共创作者、相似作者、相似内容",
+      "source_type": "gap",
+      "status": ["missing"],
+      "system": "platform_related_discovery",
+      "table_or_endpoint": "not_available",
+      "access_mode": "not_connected",
+      "usage_stages": ["walk_strategy"],
+      "owner_module": "游走策略模块",
+      "current_code_refs": [],
+      "required_env_vars": [],
+      "input_fields": [],
+      "output_fields": [],
+      "v1_boundary": "可作为游走方向,但必须标为待验证。"
+    }
+  ],
+  "stage_index": {
+    "source_seed": ["SRC_DEMAND_CONTENT_MYSQL", "SRC_DEMAND_CONTENT_LOCAL_JSON", "SRC_WORKFLOW_DECODE_TASK_RESULT", "SRC_PG_PATTERN_ITEMSET", "SRC_PG_PATTERN_CATEGORY", "SRC_PG_PATTERN_ELEMENT", "SRC_OPEN_AIGC_POST", "SRC_OPEN_AIGC_TOPIC_POINT_ELEMENT", "SRC_OPEN_AIGC_SCRIPT_ELEMENT", "PLT_DOUYIN_HOT_RANK"],
+    "search_intent": ["SRC_DEMAND_CONTENT_MYSQL", "SRC_DEMAND_CONTENT_LOCAL_JSON", "SRC_PG_PATTERN_ITEMSET", "QRY_OPENROUTER"],
+    "platform_access": ["PLT_DOUYIN_KEYWORD", "PLT_DOUYIN_DETAIL", "PLT_DOUYIN_AUTHOR_WORKS", "PLT_DOUYIN_CONTENT_PROFILE", "PLT_DOUYIN_AUTHOR_PROFILE", "PLT_TIKHUB_SEARCH_FALLBACK", "GAP_XIAOHONGSHU_PLATFORM", "GAP_OTHER_PLATFORMS"],
+    "content_discovery": ["PLT_DOUYIN_KEYWORD", "PLT_DOUYIN_DETAIL", "PLT_DOUYIN_CONTENT_PROFILE"],
+    "pattern_recall": ["JDG_DECODE_API", "JDG_CATEGORY_MATCH_PATHS", "SRC_WORKFLOW_DECODE_TASK_RESULT", "SRC_PG_PATTERN_ITEMSET", "SRC_PG_PATTERN_CATEGORY", "SRC_PG_PATTERN_ELEMENT", "LEARN_GLOBAL_TAXONOMY"],
+    "rule_judgment": ["PLT_DOUYIN_CONTENT_PROFILE", "PLT_DOUYIN_AUTHOR_PROFILE", "JDG_DECODE_API", "JDG_CATEGORY_MATCH_PATHS"],
+    "walk_strategy": ["PLT_DOUYIN_AUTHOR_WORKS", "ASSET_DEMAND_FIND_AUTHOR", "GAP_RELATED_DISCOVERY", "GAP_XIAOHONGSHU_PLATFORM"],
+    "asset_commit": ["ASSET_DEMAND_FIND_CONTENT_RESULT", "ASSET_DEMAND_FIND_AUTHOR", "ASSET_AIGC_PLAN_DETAIL", "ASSET_OSS_LOG_HTML"],
+    "learning_review": ["LEARN_DEMAND_FIND_TASK", "LEARN_DEMAND_TASK_OPRATE", "ASSET_DEMAND_FIND_CONTENT_RESULT", "ASSET_DEMAND_FIND_AUTHOR", "LEARN_ODPS_DEMAND_POOL", "LEARN_ODPS_FEATURE_POINT", "LEARN_LOGHUB_VIDEO_DIMENSION", "LEARN_GLOBAL_TAXONOMY", "SRC_PG_PATTERN_ITEMSET"]
+  },
+  "status_index": {
+    "v1_active": ["SRC_DEMAND_CONTENT_MYSQL", "SRC_DEMAND_CONTENT_LOCAL_JSON", "SRC_PG_PATTERN_ITEMSET", "SRC_PG_PATTERN_CATEGORY", "SRC_PG_PATTERN_ELEMENT", "PLT_DOUYIN_KEYWORD", "PLT_DOUYIN_CONTENT_PROFILE"],
+    "verified": ["SRC_DEMAND_CONTENT_MYSQL", "SRC_DEMAND_CONTENT_LOCAL_JSON", "SRC_WORKFLOW_DECODE_TASK_RESULT", "SRC_PG_PATTERN_ITEMSET", "SRC_PG_PATTERN_CATEGORY", "SRC_PG_PATTERN_ELEMENT", "SRC_OPEN_AIGC_POST", "SRC_OPEN_AIGC_TOPIC_POINT_ELEMENT", "SRC_OPEN_AIGC_SCRIPT_ELEMENT", "SRC_OLD_MYSQL_TOPIC_PATTERN", "PLT_DOUYIN_KEYWORD", "PLT_DOUYIN_DETAIL", "PLT_DOUYIN_AUTHOR_WORKS", "PLT_DOUYIN_CONTENT_PROFILE", "PLT_DOUYIN_AUTHOR_PROFILE", "PLT_DOUYIN_HOT_RANK", "JDG_CATEGORY_MATCH_PATHS", "ASSET_DEMAND_FIND_CONTENT_RESULT", "ASSET_DEMAND_FIND_AUTHOR", "LEARN_DEMAND_FIND_TASK", "LEARN_ODPS_DEMAND_POOL", "LEARN_ODPS_FEATURE_POINT", "LEARN_LOGHUB_VIDEO_DIMENSION", "LEARN_GLOBAL_TAXONOMY"],
+    "missing_or_blocked": ["PLT_TIKHUB_SEARCH_FALLBACK", "ASSET_AIGC_PLAN_DETAIL", "ASSET_OSS_LOG_HTML", "GAP_XIAOHONGSHU_PLATFORM", "GAP_OTHER_PLATFORMS", "GAP_RELATED_DISCOVERY"]
+  },
+  "env_var_index": {
+    "CONTENT_SUPPLY_DB_*": ["SRC_DEMAND_CONTENT_MYSQL", "SRC_WORKFLOW_DECODE_TASK_RESULT", "ASSET_DEMAND_FIND_CONTENT_RESULT", "ASSET_DEMAND_FIND_AUTHOR", "LEARN_DEMAND_FIND_TASK", "LEARN_DEMAND_TASK_OPRATE"],
+    "OPEN_AIGC_PG_*": ["SRC_PG_PATTERN_ITEMSET", "SRC_PG_PATTERN_CATEGORY", "SRC_PG_PATTERN_ELEMENT"],
+    "OPEN_AIGC_MYSQL_*": ["SRC_OPEN_AIGC_POST", "SRC_OPEN_AIGC_TOPIC_POINT_ELEMENT", "SRC_OPEN_AIGC_SCRIPT_ELEMENT", "LEARN_GLOBAL_TAXONOMY"],
+    "CONTENTFIND_API_CRAWAPI_BASE_URL": ["PLT_DOUYIN_KEYWORD", "PLT_DOUYIN_DETAIL", "PLT_DOUYIN_AUTHOR_WORKS", "PLT_DOUYIN_CONTENT_PROFILE", "PLT_DOUYIN_AUTHOR_PROFILE", "PLT_DOUYIN_HOT_RANK"],
+    "TIKHUB_API_KEY": ["PLT_TIKHUB_SEARCH_FALLBACK"],
+    "OPENROUTER_API_KEY": ["QRY_OPENROUTER"],
+    "AIGC_TOKEN": ["ASSET_AIGC_PLAN_DETAIL"],
+    "ALIYUN_OSS_*": ["ASSET_OSS_LOG_HTML"],
+    "ODPS_*": ["LEARN_ODPS_DEMAND_POOL", "LEARN_ODPS_FEATURE_POINT", "LEARN_LOGHUB_VIDEO_DIMENSION"]
+  },
+  "validation_rules": [
+    "每个 source_id 必须唯一。",
+    "status 只能使用 status_legend 中登记的值。",
+    "source_type 只能使用 source_type_legend 中登记的值。",
+    "required_env_vars 只登记变量名或通配符,不登记 secret 值。",
+    "deprecated_reference_only 的来源不能作为 v1_active 来源。",
+    "missing 或 blocked 的来源不能写成已接入。"
+  ]
+}

+ 113 - 0
数据接口与来源/platform_profiles/bilibili.json

@@ -0,0 +1,113 @@
+{
+  "schema_version": "platform_profile.v1",
+  "platform": "bilibili",
+  "platform_label": "B站",
+  "status": "partial",
+  "evidence": "2026-06-11 实测(接口台账/B站.md)",
+  "runtime": {
+    "rate_limit_seconds": 15,
+    "retry": null,
+    "video_download": {
+      "downloadable": true,
+      "headers": {
+        "User-Agent": "PC UA",
+        "Referer": "https://www.bilibili.com/"
+      },
+      "note": "实测 206 真实字节;.m4s DASH 分轨(视频轨+音频轨 voice_data.play_url 需合并)"
+    }
+  },
+  "heat": {
+    "note": "R3 第二步(2026-06-12):B站有播放量,量级大以播放为主;字段据抓包,权重/锚点起步值待该平台接入真跑标定",
+    "signals": [
+      {
+        "field": "play_count",
+        "weight": 0.4,
+        "floor": 5000,
+        "ceil": 10000000
+      },
+      {
+        "field": "digg_count",
+        "weight": 0.3,
+        "floor": 500,
+        "ceil": 500000
+      },
+      {
+        "field": "comment_count",
+        "weight": 0.1,
+        "floor": 50,
+        "ceil": 50000
+      },
+      {
+        "field": "share_count",
+        "weight": 0.1,
+        "floor": 20,
+        "ceil": 50000
+      },
+      {
+        "field": "collect_count",
+        "weight": 0.1,
+        "floor": 50,
+        "ceil": 200000
+      }
+    ]
+  },
+  "endpoints": {
+    "search": {
+      "path": "/crawler/bilibili/keyword",
+      "params": {
+        "keyword": "str"
+      },
+      "response_shape": "raw(B站原生,一次 42 条)"
+    },
+    "detail": {
+      "path": "/crawler/bilibili/detail",
+      "params": {
+        "content_id": "bvid"
+      },
+      "response_shape": "normalized(channel_*)"
+    }
+  },
+  "jump_key_raw": {
+    "platform_content_id": {
+      "search": "bvid",
+      "detail": "channel_content_id"
+    },
+    "platform_author_id": {
+      "search": "mid",
+      "trap": "uid 字段恒为 0,必须取 mid"
+    },
+    "tags": {
+      "search": "tag(逗号串需 split)",
+      "detail": "topic_list"
+    },
+    "video_url": {
+      "detail": "video_url_list[0].video_url(.m4s)"
+    }
+  },
+  "edges": {
+    "query_next_page": {
+      "status": "supported"
+    },
+    "search_page_to_content": {
+      "status": "supported"
+    },
+    "video_to_author": {
+      "status": "supported",
+      "note": "仅落 mid 标识"
+    },
+    "author_to_works": {
+      "status": "unsupported",
+      "note": "集合中无作者作品接口"
+    },
+    "author_work_to_content": {
+      "status": "unsupported"
+    },
+    "video_to_hashtag": {
+      "status": "supported",
+      "note": "tag split / topic_list"
+    },
+    "hashtag_to_query": {
+      "status": "supported"
+    }
+  }
+}

+ 52 - 0
数据接口与来源/platform_profiles/douyin.json

@@ -0,0 +1,52 @@
+{
+  "schema_version": "platform_profile.v1",
+  "platform": "douyin",
+  "platform_label": "抖音",
+  "status": "active",
+  "evidence": "2026-06-11 实测(接口台账/抖音.md)",
+  "runtime": {
+    "rate_limit_seconds": 15,
+    "retry": null,
+    "video_download": { "downloadable": true, "headers": { "User-Agent": "iOS UA", "Referer": "https://www.douyin.com/" }, "note": "实测 206/video/mp4;play_addr 地址有时效" }
+  },
+  "heat": {
+    "note": "R3 第二步(2026-06-12):抖音无播放量,用 赞+评+转+藏 四字段复合;权重/锚点为起步值,凭真跑主观调",
+    "signals": [
+      { "field": "digg_count",    "weight": 0.4, "floor": 10000, "ceil": 1000000 },
+      { "field": "comment_count", "weight": 0.2, "floor": 100,   "ceil": 50000 },
+      { "field": "share_count",   "weight": 0.2, "floor": 50,    "ceil": 20000 },
+      { "field": "collect_count", "weight": 0.2, "floor": 100,   "ceil": 100000 }
+    ]
+  },
+  "observable_fields": [
+    { "field": "statistics.digg_count", "availability": "supported", "source": "search.statistics.digg_count / detail.like_count" },
+    { "field": "statistics.comment_count", "availability": "supported", "source": "search.statistics.comment_count / detail.comment_count" },
+    { "field": "statistics.share_count", "availability": "supported", "source": "search.statistics.share_count / detail.share_count" },
+    { "field": "statistics.collect_count", "availability": "supported", "source": "search.statistics.collect_count / detail.collect_count" }
+  ],
+  "missing_observable_fields": [
+    { "field": "statistics.play_count", "missing_type": "natural_platform_missing", "platform": "douyin", "evidence": "跨平台字段映射.json" }
+  ],
+  "endpoints": {
+    "search":         { "path": "/crawler/dou_yin/keyword", "params": { "keyword": "str", "content_type": "视频|图文", "sort_type": "最多点赞|最多分享", "cursor": "str" }, "response_shape": "raw(aweme 原生结构)" },
+    "detail":         { "path": "/crawler/dou_yin/detail", "params": { "content_id": "str" }, "response_shape": "normalized(channel_* 归一化)" },
+    "blogger":        { "path": "/crawler/dou_yin/blogger", "params": { "account_id": "sec_uid", "cursor": "str" }, "response_shape": "raw" },
+    "author_profile": { "path": "/crawler/dou_yin/re_dian_bao/account_fans_portrait", "params": { "account_id": "sec_uid", "need_age": true, "need_gender": true, "need_province": true } },
+    "content_profile": { "path": "/crawler/dou_yin/re_dian_bao/video_like_portrait", "status": "blocked", "note": "实测 HTTP 404" }
+  },
+  "jump_key_raw": {
+    "platform_content_id": { "search": "aweme_id", "detail": "channel_content_id" },
+    "platform_author_id":  { "search": "author.sec_uid", "detail": "channel_account_id" },
+    "tags":                { "search": "text_extra[].hashtag_name + video_tag[].tag_name", "detail": "topic_list" },
+    "video_url":           { "search": "video.play_addr.url_list[0]", "detail": "video_url_list[0].video_url" }
+  },
+  "edges": {
+    "query_next_page":        { "status": "supported" },
+    "search_page_to_content": { "status": "supported" },
+    "video_to_author":        { "status": "supported", "note": "搜索阶段即得完整作者档案(sec_uid/粉丝/签名)" },
+    "author_to_works":        { "status": "supported", "note": "blogger 可翻页,实测一次 22 条" },
+    "author_work_to_content": { "status": "supported" },
+    "video_to_hashtag":       { "status": "supported", "note": "结构化 tag 直接可用" },
+    "hashtag_to_query":       { "status": "supported" }
+  }
+}

+ 30 - 0
数据接口与来源/platform_profiles/github.json

@@ -0,0 +1,30 @@
+{
+  "schema_version": "platform_profile.v1",
+  "platform": "github",
+  "platform_label": "github",
+  "status": "partial",
+  "evidence": "2026-06-11 实测(接口台账/github.md)",
+  "runtime": {
+    "rate_limit_seconds": 15,
+    "retry": null,
+    "video_download": { "downloadable": false, "note": "代码仓库,非视频内容" }
+  },
+  "endpoints": {
+    "search": { "path": "/crawler/github/keyword", "params": { "keyword": "str", "token": "" }, "pagination_note": "请求传 token、响应给 next_cursor(短页码),参数名不对称" }
+  },
+  "jump_key_raw": {
+    "platform_content_id": { "search": "id" },
+    "platform_author_id":  { "search": "owner_login" },
+    "tags":                { "search": "topics(多数为空)" },
+    "url_trap":            "无现成仓库 url 字段,须 hl_name 去 <em> 后拼 https://github.com/{owner/repo}"
+  },
+  "edges": {
+    "query_next_page":        { "status": "supported" },
+    "search_page_to_content": { "status": "supported", "note": "repo,非视频" },
+    "video_to_author":        { "status": "supported", "note": "content→owner" },
+    "author_to_works":        { "status": "unsupported" },
+    "author_work_to_content": { "status": "unsupported" },
+    "video_to_hashtag":       { "status": "weak", "note": "topics 常空" },
+    "hashtag_to_query":       { "status": "supported" }
+  }
+}

+ 127 - 0
数据接口与来源/platform_profiles/kuaishou.json

@@ -0,0 +1,127 @@
+{
+  "schema_version": "platform_profile.v1",
+  "platform": "kuaishou",
+  "platform_label": "快手",
+  "status": "partial",
+  "evidence": "2026-06-11 实测(接口台账/快手.md)",
+  "runtime": {
+    "rate_limit_seconds": 15,
+    "retry": null,
+    "video_download": {
+      "downloadable": true,
+      "headers": {
+        "User-Agent": "PC UA",
+        "Referer": "https://www.kuaishou.com/"
+      },
+      "note": "实测 206/video/mp4;kwaicdn 直链带 pkey 签名"
+    }
+  },
+  "heat": {
+    "note": "R3 第二步(2026-06-12):快手有播放量(唯一全字段),以播放为主;字段据抓包,权重/锚点起步值待该平台接入真跑标定",
+    "signals": [
+      {
+        "field": "play_count",
+        "weight": 0.4,
+        "floor": 1000,
+        "ceil": 5000000
+      },
+      {
+        "field": "digg_count",
+        "weight": 0.3,
+        "floor": 1000,
+        "ceil": 500000
+      },
+      {
+        "field": "comment_count",
+        "weight": 0.1,
+        "floor": 50,
+        "ceil": 50000
+      },
+      {
+        "field": "share_count",
+        "weight": 0.1,
+        "floor": 20,
+        "ceil": 20000
+      },
+      {
+        "field": "collect_count",
+        "weight": 0.1,
+        "floor": 50,
+        "ceil": 100000
+      }
+    ]
+  },
+  "observable_fields": [
+    { "field": "statistics.play_count", "availability": "supported", "source": "view_count" },
+    { "field": "statistics.digg_count", "availability": "supported", "source": "like_count" },
+    { "field": "statistics.comment_count", "availability": "supported", "source": "comment_count" },
+    { "field": "statistics.share_count", "availability": "supported", "source": "share_count" },
+    { "field": "statistics.collect_count", "availability": "supported", "source": "collect_count" }
+  ],
+  "missing_observable_fields": [],
+  "endpoints": {
+    "search": {
+      "path": "/crawler/kuai_shou/keyword_v2",
+      "params": {
+        "keyword": "str"
+      },
+      "response_shape": "normalized(channel_*)"
+    },
+    "detail": {
+      "path": "/crawler/kuai_shou/detail",
+      "params": {
+        "content_id": "str"
+      },
+      "response_shape": "normalized"
+    },
+    "account_info": {
+      "path": "/crawler/kuai_shou/account_info",
+      "params": {
+        "account_id": "str",
+        "is_cache": true
+      }
+    }
+  },
+  "jump_key_raw": {
+    "platform_content_id": {
+      "search": "channel_content_id"
+    },
+    "platform_author_id": {
+      "search": "channel_account_id"
+    },
+    "tags": {
+      "search": "topic_list(常 null,兜底标题/正文正则)"
+    },
+    "video_url": {
+      "search": "video_url_list[0].video_url"
+    }
+  },
+  "edges": {
+    "query_next_page": {
+      "status": "blocked",
+      "note": "实测单页 has_more=false,不猜测翻页"
+    },
+    "search_page_to_content": {
+      "status": "supported"
+    },
+    "video_to_author": {
+      "status": "supported",
+      "note": "作者档案需 account_info 二次补齐"
+    },
+    "author_to_works": {
+      "status": "blocked",
+      "note": "无独立作者作品接口"
+    },
+    "author_work_to_content": {
+      "status": "blocked"
+    },
+    "video_to_hashtag": {
+      "status": "supported",
+      "confidence": "weak",
+      "note": "topic_list 常 null,靠正则兜底"
+    },
+    "hashtag_to_query": {
+      "status": "supported"
+    }
+  }
+}

+ 47 - 0
数据接口与来源/platform_profiles/shipinhao.json

@@ -0,0 +1,47 @@
+{
+  "schema_version": "platform_profile.v1",
+  "platform": "shipinhao",
+  "platform_label": "视频号",
+  "status": "partial",
+  "evidence": "2026-06-11 实测(接口台账/视频号.md)",
+  "runtime": {
+    "rate_limit_seconds": 15,
+    "retry": { "search": { "trigger": "仅暂时性故障重试:code=25011 接口异常 / 超时 / 网络错误(code=0 空结果、参数/鉴权错 不重试)", "max_attempts": 3, "backoff_seconds": [1, 2, 4], "on_exhausted": "标 blocked·失败待查,游走绕行不卡流水线", "note": "实测首次 25011、重试 code=0;退避与 rate_limit_seconds=15 取较大值,故退避多被 15s 吸收(2026-06-11 拍板)" } },
+    "video_download": { "downloadable": true, "headers": { "User-Agent": "PC UA", "Referer": "https://channels.weixin.qq.com/" }, "note": "实测 200/video/mp4;findermp 带 encfilekey" }
+  },
+  "heat": {
+    "note": "R3 第一步(2026-06-12):点赞单信号=R3 前行为;视频号 comment/share/collect 实测常空,数据所限只能用点赞",
+    "signals": [
+      { "field": "digg_count", "weight": 1.0, "floor": 50, "ceil": 50000 }
+    ]
+  },
+  "observable_fields": [
+    { "field": "statistics.digg_count", "availability": "supported", "source": "like_count" }
+  ],
+  "missing_observable_fields": [
+    { "field": "statistics.comment_count", "missing_type": "natural_platform_missing", "platform": "shipinhao", "evidence": "跨平台字段映射.json" },
+    { "field": "statistics.share_count", "missing_type": "natural_platform_missing", "platform": "shipinhao", "evidence": "跨平台字段映射.json" },
+    { "field": "statistics.collect_count", "missing_type": "natural_platform_missing", "platform": "shipinhao", "evidence": "跨平台字段映射.json" },
+    { "field": "statistics.play_count", "missing_type": "natural_platform_missing", "platform": "shipinhao", "evidence": "跨平台字段映射.json" }
+  ],
+  "endpoints": {
+    "search":       { "path": "/crawler/shi_pin_hao/keyword", "params": { "keyword": "str", "cursor": "str" }, "response_shape": "normalized(channel_*)", "stability": "unstable" },
+    "blogger":      { "path": "/crawler/shi_pin_hao/blogger", "status": "blocked", "note": "实测 code=25011" },
+    "account_info": { "path": "/crawler/shi_pin_hao/account_info", "params": { "account_name": "str" }, "status": "blocked", "note": "以 registry/capture blocked 为准;2026-06-14 profile partial 不作为可靠运行能力" }
+  },
+  "jump_key_raw": {
+    "platform_content_id": { "search": "channel_content_id" },
+    "platform_author_id":  { "search": "channel_account_id" },
+    "tags":                { "search": "topic_list(实测 null,兜底标题正则 #xxx)" },
+    "video_url":           { "search": "video_url_list[0].video_url" }
+  },
+  "edges": {
+    "query_next_page":        { "status": "supported", "note": "抖动需重试" },
+    "search_page_to_content": { "status": "supported", "note": "抖动需重试" },
+    "video_to_author":        { "status": "supported", "note": "仅落 channel_account_id 标识" },
+    "author_to_works":        { "status": "blocked", "note": "blogger code=25011" },
+    "author_work_to_content": { "status": "blocked" },
+    "video_to_hashtag":       { "status": "supported", "note": "标题正则抽" },
+    "hashtag_to_query":       { "status": "supported" }
+  }
+}

+ 12 - 0
数据接口与来源/platform_profiles/toutiao.json

@@ -0,0 +1,12 @@
+{
+  "schema_version": "platform_profile.v1",
+  "platform": "toutiao",
+  "platform_label": "头条",
+  "status": "blocked",
+  "evidence": "2026-06-11 实测(接口台账/头条.md):/crawler/tou_tiao_hao/keyword 两次(含变参)均 code=10000 未知错误",
+  "runtime": { "rate_limit_seconds": 15 },
+  "endpoints": {
+    "search": { "path": "/crawler/tou_tiao_hao/keyword", "status": "blocked", "note": "code=10000,与参数无关,平台侧不可用;修复后复抓再登记" }
+  },
+  "edges": { "_all": "blocked(整平台所有边阻断)" }
+}

+ 93 - 0
数据接口与来源/platform_profiles/weixin.json

@@ -0,0 +1,93 @@
+{
+  "schema_version": "platform_profile.v1",
+  "platform": "weixin",
+  "platform_label": "公众号",
+  "status": "partial",
+  "evidence": "2026-06-11 实测(接口台账/公众号.md)",
+  "runtime": {
+    "rate_limit_seconds": 15,
+    "retry": null,
+    "video_download": {
+      "downloadable": false,
+      "note": "图文平台,无视频"
+    }
+  },
+  "heat": {
+    "note": "R3 第二步(2026-06-12):公众号只有阅读数+赞(赞常0),以阅读为主;字段据抓包,权重/锚点起步值待该平台接入真跑标定",
+    "signals": [
+      {
+        "field": "play_count",
+        "weight": 0.6,
+        "floor": 100,
+        "ceil": 500000
+      },
+      {
+        "field": "digg_count",
+        "weight": 0.4,
+        "floor": 10,
+        "ceil": 50000
+      }
+    ]
+  },
+  "endpoints": {
+    "search": {
+      "path": "/crawler/wei_xin/keyword",
+      "params": {
+        "keyword": "str",
+        "cursor": "0"
+      },
+      "response_shape": "item={biz,cover_url,nick_name,time,title,url};nick_name/biz 实测常为空"
+    },
+    "detail": {
+      "path": "/crawler/wei_xin/detail",
+      "params": {
+        "content_link": "文章url"
+      }
+    },
+    "account_info": {
+      "path": "/crawler/wei_xin/account_info",
+      "params": {
+        "content_link": "文章url"
+      },
+      "note": "唯一可达的作者补全(account_name/biz_info/wx_gh)"
+    }
+  },
+  "jump_key_raw": {
+    "platform_content_id": {
+      "search": "url(文章链接即标识)"
+    },
+    "platform_author_id": {
+      "search": "url 正则抽 __biz=([^&]+)",
+      "trap": "三套标识互不相同:biz / 网关hash channel_account_id / wx_gh;昵称只能 account_info 补"
+    },
+    "tags": {
+      "trap": "整平台无 hashtag/topic_list"
+    }
+  },
+  "edges": {
+    "query_next_page": {
+      "status": "supported"
+    },
+    "search_page_to_content": {
+      "status": "supported"
+    },
+    "video_to_author": {
+      "status": "supported",
+      "note": "仅落 biz(正则);昵称需 account_info 二次请求"
+    },
+    "author_to_works": {
+      "status": "unsupported",
+      "note": "blogger 不可达,无作品列表"
+    },
+    "author_work_to_content": {
+      "status": "unsupported"
+    },
+    "video_to_hashtag": {
+      "status": "unsupported",
+      "note": "整平台无 tag"
+    },
+    "hashtag_to_query": {
+      "status": "unsupported"
+    }
+  }
+}

+ 113 - 0
数据接口与来源/platform_profiles/xiaohongshu.json

@@ -0,0 +1,113 @@
+{
+  "schema_version": "platform_profile.v1",
+  "platform": "xiaohongshu",
+  "platform_label": "小红书",
+  "status": "partial",
+  "evidence": "2026-06-11 实测(接口台账/小红书.md)",
+  "runtime": {
+    "rate_limit_seconds": 15,
+    "retry": null,
+    "video_download": {
+      "downloadable": null,
+      "note": "图文为主(image_list);视频可下载性未实测"
+    }
+  },
+  "heat": {
+    "note": "R3 第二步(2026-06-12):小红书无播放量,收藏文化重,收藏权重抬高;字段据抓包,权重/锚点起步值待该平台接入真跑标定",
+    "signals": [
+      {
+        "field": "collect_count",
+        "weight": 0.35,
+        "floor": 100,
+        "ceil": 200000
+      },
+      {
+        "field": "digg_count",
+        "weight": 0.35,
+        "floor": 100,
+        "ceil": 500000
+      },
+      {
+        "field": "comment_count",
+        "weight": 0.15,
+        "floor": 20,
+        "ceil": 50000
+      },
+      {
+        "field": "share_count",
+        "weight": 0.15,
+        "floor": 10,
+        "ceil": 20000
+      }
+    ]
+  },
+  "endpoints": {
+    "search": {
+      "path": "/crawler/xiao_hong_shu/keyword",
+      "params": {
+        "keyword": "str",
+        "content_type": "图文|视频",
+        "sort_type": "综合",
+        "publish_time": "",
+        "cursor": ""
+      },
+      "response_shape": "嵌套:item={id,model_type,note_card},内容字段全在 note_card.* 下"
+    },
+    "detail": {
+      "path": "/crawler/xiao_hong_shu/detail",
+      "params": {
+        "content_id": "str"
+      },
+      "response_shape": "扁平(与 search 嵌套结构不同!)"
+    },
+    "blogger": {
+      "path": "/crawler/xiao_hong_shu/blogger",
+      "status": "blocked",
+      "note": "实测请求超时"
+    }
+  },
+  "jump_key_raw": {
+    "platform_content_id": {
+      "search": "item.id",
+      "detail": "channel_content_id"
+    },
+    "platform_author_id": {
+      "search": "note_card.user.user_id"
+    },
+    "tags": {
+      "search": "note_card.desc 正则 #xxx",
+      "detail": "topic_list"
+    },
+    "interactions": {
+      "search": "note_card.interact_info.{liked,collected,comment,shared}_count"
+    },
+    "timestamp_trap": "search 秒级 vs detail 毫秒级,同一笔记两接口不一致"
+  },
+  "edges": {
+    "query_next_page": {
+      "status": "supported"
+    },
+    "search_page_to_content": {
+      "status": "supported",
+      "note": "必须深入 note_card 嵌套抽取"
+    },
+    "video_to_author": {
+      "status": "supported",
+      "note": "note_card.user.user_id"
+    },
+    "author_to_works": {
+      "status": "blocked",
+      "note": "blogger 超时"
+    },
+    "author_work_to_content": {
+      "status": "blocked"
+    },
+    "video_to_hashtag": {
+      "status": "supported",
+      "note": "desc 正则 / detail topic_list"
+    },
+    "hashtag_to_query": {
+      "status": "supported"
+    }
+  }
+}

+ 94 - 0
数据接口与来源/platform_profiles/youtube.json

@@ -0,0 +1,94 @@
+{
+  "schema_version": "platform_profile.v1",
+  "platform": "youtube",
+  "platform_label": "youtube",
+  "status": "partial",
+  "evidence": "2026-06-11 实测(接口台账/youtube.md)",
+  "runtime": {
+    "rate_limit_seconds": 15,
+    "retry": null,
+    "video_download": {
+      "downloadable": false,
+      "note": "detail 的 video_url_list 实测为空,视频不可经 crawler 直取"
+    }
+  },
+  "heat": {
+    "note": "R3 第二步(2026-06-12):油管有播放量,share/collect 常空,用 播放+赞+评;字段据抓包,权重/锚点起步值待该平台接入真跑标定",
+    "signals": [
+      {
+        "field": "play_count",
+        "weight": 0.5,
+        "floor": 1000,
+        "ceil": 10000000
+      },
+      {
+        "field": "digg_count",
+        "weight": 0.3,
+        "floor": 100,
+        "ceil": 1000000
+      },
+      {
+        "field": "comment_count",
+        "weight": 0.2,
+        "floor": 20,
+        "ceil": 100000
+      }
+    ]
+  },
+  "endpoints": {
+    "search": {
+      "path": "/crawler/youtube/keyword",
+      "params": {
+        "keyword": "str"
+      },
+      "pagination_note": "next_cursor 是 400+ 字符 URL-encoded 长 token,须整体透传"
+    },
+    "detail": {
+      "path": "/crawler/youtube/detail",
+      "params": {
+        "content_id": "video_id"
+      },
+      "note": "无视频地址,仅正文/统计"
+    }
+  },
+  "jump_key_raw": {
+    "platform_content_id": {
+      "search": "video_id"
+    },
+    "platform_author_id": {
+      "search": "channel_id(UC...)",
+      "detail": "channel_account_id(32位hash)",
+      "trap": "双体系互不相同"
+    },
+    "tags": {
+      "search": "无",
+      "detail": "topic_list=null,须 body_text 正则 #xxx"
+    }
+  },
+  "edges": {
+    "query_next_page": {
+      "status": "supported",
+      "note": "长 token 游标"
+    },
+    "search_page_to_content": {
+      "status": "supported"
+    },
+    "video_to_author": {
+      "status": "supported"
+    },
+    "author_to_works": {
+      "status": "unsupported",
+      "note": "无作者作品接口"
+    },
+    "author_work_to_content": {
+      "status": "unsupported"
+    },
+    "video_to_hashtag": {
+      "status": "weak",
+      "note": "仅 detail.body_text 正则,搜索无 tag"
+    },
+    "hashtag_to_query": {
+      "status": "supported"
+    }
+  }
+}

+ 12 - 0
数据接口与来源/platform_profiles/zhihu.json

@@ -0,0 +1,12 @@
+{
+  "schema_version": "platform_profile.v1",
+  "platform": "zhihu",
+  "platform_label": "知乎",
+  "status": "blocked",
+  "evidence": "2026-06-11 实测(接口台账/知乎.md):/crawler/zhi_hu/keyword 两次(含变参)均 code=10000 未知错误",
+  "runtime": { "rate_limit_seconds": 15 },
+  "endpoints": {
+    "search": { "path": "/crawler/zhi_hu/keyword", "status": "blocked", "note": "code=10000,与参数无关,平台侧不可用;修复后复抓再登记" }
+  },
+  "edges": { "_all": "blocked(整平台所有边阻断)" }
+}

+ 150 - 0
数据接口与来源/walk_graph.json

@@ -0,0 +1,150 @@
+{
+  "schema_version": "walk_graph.v2",
+  "title": "游走图谱(全局边目录,平台无关;8 节点 + 10 边,复用 douyin_walk_strategy.v1.json 命名)",
+  "generated_at": "2026-06-11",
+  "source_of_truth": "product_documents/抖音游走策略/douyin_walk_strategy.v1.json",
+  "evidence": "实测抓包(2026-06-11 多平台探针) + 接口台账/*.md",
+  "companions": {
+    "platform_profiles": "platform_profiles/<platform>.json — 每平台:支持哪些边、真实 endpoint、jump_key 的 raw 字段、extract_rule 覆写、运行参数(限流/重试/下载头)",
+    "walk_policy": "walk_policy.json — 全局护栏:预算/深度/去重/回灌配额 + 判定→边通行证(edge_permissions)",
+    "field_mapping": "跨平台字段映射.json — 平台响应 raw 字段 → canonical 字段"
+  },
+  "constraints": [
+    "edge_id 全部来自策略文件 10 条,零新造。",
+    "node 全部来自策略文件 8 类,id_field 与策略 walk_node_catalog 一致。",
+    "本文件只写平台无关语义;一切平台差异在 platform_profiles/,一切数值护栏在 walk_policy.json。",
+    "source_path_type 对齐血缘三类:pattern_to_search_query / search_query_to_content / decision_to_asset(其余边记 null)。"
+  ],
+  "nodes": [
+    { "node_type": "pattern_seed",      "id_field": "policy_run_id",        "node_category": "input",           "can_expand": true,  "notes": "P2 种子词起点" },
+    { "node_type": "query",             "id_field": "search_query_id",      "node_category": "action_input",    "can_expand": true,  "notes": "初始 item query 或 tag query" },
+    { "node_type": "search_page",       "id_field": "search_page_id",       "node_category": "platform_result", "can_expand": true,  "notes": "带 has_more / next_cursor" },
+    { "node_type": "video",             "id_field": "platform_content_id",  "node_category": "content",         "can_expand": true,  "notes": "核心内容对象;作者作品产出的也是 video" },
+    { "node_type": "author",            "id_field": "platform_author_id",   "node_category": "entity",          "can_expand": true,  "notes": "来自已发现 video 的作者标识" },
+    { "node_type": "author_works_page", "id_field": "author_works_page_id", "node_category": "platform_result", "can_expand": true,  "notes": "作者作品列表页" },
+    { "node_type": "hashtag",           "id_field": "hashtag",              "node_category": "signal",          "can_expand": true,  "notes": "仅强相关 tag 可扩散" },
+    { "node_type": "asset",             "id_field": "asset_id",             "node_category": "asset",           "can_expand": false, "notes": "最终产出资产" }
+  ],
+  "edges": [
+    {
+      "edge_id": "query_next_page",
+      "from_node": "query",
+      "to_node": "search_page",
+      "edge_class": "navigate",
+      "endpoint_role": "search",
+      "jump_key": { "from_field": "next_cursor", "param": "cursor" },
+      "paginated": true,
+      "gate": "none",
+      "extract_rule": "has_more=true 时用 next_cursor 请求同一 search 端点的下一页",
+      "source_path_type": "pattern_to_search_query"
+    },
+    {
+      "edge_id": "search_page_to_content",
+      "from_node": "search_page",
+      "to_node": "video",
+      "edge_class": "navigate",
+      "endpoint_role": null,
+      "jump_key": { "from_field": "data.data[]", "param": null },
+      "paginated": false,
+      "gate": "none",
+      "extract_rule": "search 响应 data.data[] 拆每条卡片为 video(canonical: platform_content_id);raw 字段名见 platform_profiles",
+      "source_path_type": "search_query_to_content"
+    },
+    {
+      "edge_id": "video_to_author",
+      "from_node": "video",
+      "to_node": "author",
+      "edge_class": "navigate",
+      "endpoint_role": null,
+      "jump_key": { "from_field": "platform_author_id", "param": null },
+      "paginated": false,
+      "gate": "none",
+      "extract_rule": "从 video 取 canonical platform_author_id;各平台 raw 来源见 platform_profiles(jump_key_raw)",
+      "source_path_type": null
+    },
+    {
+      "edge_id": "author_to_works",
+      "from_node": "author",
+      "to_node": "author_works_page",
+      "edge_class": "navigate",
+      "endpoint_role": "blogger",
+      "jump_key": { "from_field": "platform_author_id", "param": "account_id" },
+      "paginated": true,
+      "gate": "decision_gated",
+      "extract_rule": "用 platform_author_id 拉作者作品页;翻页 next_cursor 回填 cursor;是否放行由 walk_policy.edge_permissions 按判定结果决定",
+      "source_path_type": null
+    },
+    {
+      "edge_id": "author_work_to_content",
+      "from_node": "author_works_page",
+      "to_node": "video",
+      "edge_class": "navigate",
+      "endpoint_role": null,
+      "jump_key": { "from_field": "data.data[]", "param": null },
+      "paginated": false,
+      "gate": "none",
+      "extract_rule": "作者作品页 data.data[] 拆为 video,按 platform_content_id 与已发现内容去重(commit 1cd1b94);产出的 video 同样进判定与回灌",
+      "source_path_type": "search_query_to_content"
+    },
+    {
+      "edge_id": "video_to_hashtag",
+      "from_node": "video",
+      "to_node": "hashtag",
+      "edge_class": "reseed",
+      "endpoint_role": null,
+      "jump_key": { "from_field": "tags", "param": null },
+      "paginated": false,
+      "gate": "keep_only",
+      "extract_rule": "从 video 的 canonical tags 抽;结构化来源优先、缺则正则 #([^\\s#]+),按平台覆写见 platform_profiles",
+      "source_path_type": null
+    },
+    {
+      "edge_id": "hashtag_to_query",
+      "from_node": "hashtag",
+      "to_node": "query",
+      "edge_class": "reseed",
+      "endpoint_role": "search",
+      "jump_key": { "from_field": "hashtag", "param": "keyword" },
+      "paginated": false,
+      "gate": "keep_only",
+      "extract_rule": "hashtag 文本生成新 query;归一化 keyword 去重(walk_policy.dedup),不污染 P2 初始 item query",
+      "source_path_type": "pattern_to_search_query"
+    },
+    {
+      "edge_id": "decision_to_asset",
+      "from_node": "video",
+      "to_node": "asset",
+      "edge_class": "navigate",
+      "endpoint_role": null,
+      "jump_key": { "from_field": "platform_content_id", "param": null },
+      "paginated": false,
+      "gate": "none",
+      "extract_rule": "判定命中 ADD_TO_CONTENT_POOL 后将 video 沉淀为 asset",
+      "source_path_type": "decision_to_asset"
+    },
+    {
+      "edge_id": "path_stop",
+      "from_node": "video",
+      "to_node": "video",
+      "edge_class": "navigate",
+      "endpoint_role": null,
+      "jump_key": { "from_field": "content_effect_status", "param": null },
+      "paginated": false,
+      "gate": "none",
+      "extract_rule": "rule_blocked / failed 内容停止当前路径扩散,不再开任何出边",
+      "source_path_type": null
+    },
+    {
+      "edge_id": "budget_downgrade",
+      "from_node": "video",
+      "to_node": "video",
+      "edge_class": "navigate",
+      "endpoint_role": null,
+      "jump_key": { "from_field": "budget.remaining_actions", "param": null },
+      "paginated": false,
+      "gate": "none",
+      "extract_rule": "全局预算/深度耗尽时按 walk_policy 降档继续或停边",
+      "source_path_type": null
+    }
+  ]
+}

+ 39 - 0
数据接口与来源/walk_policy.json

@@ -0,0 +1,39 @@
+{
+  "schema_version": "walk_policy.v1",
+  "title": "游走全局护栏 + 判定→边通行证(配 walk_graph.v2 使用)",
+  "generated_at": "2026-06-11",
+  "value_provenance": "基线=walk_engine v1 实际硬限(行为等价,M4 拍板 2026-06-11);2026-06-12 R7 拍板放宽 tag 1→3、作者 2→3(真跑 v1_run_4e24c1b85637 两项顶格实证)",
+  "global": {
+    "max_total_actions_per_run": { "value": 60, "provenance": "拍板 2026-06-11:沿用 v1 各边合计上限 60 作全局闸", "tbd": false },
+    "max_depth": { "value": 3, "provenance": "v1 各边 max_depth=3", "tbd": false },
+    "max_reseed_rounds": { "value": 1, "provenance": "拍板 2026-06-11:单层回灌(tag→query 不二次回灌),v1 等价", "tbd": false },
+    "gemini_calls_per_run_cap": { "value": 200, "provenance": "拍板 2026-06-12:单 run 上限约 $4.4(@$0.022/条),远高于典型 N≈20-40,封顶失控;M7 真负标定", "tbd": false },
+    "gemini_max_workers": { "value": 4, "provenance": "拍板 2026-06-12:判定批并发度(IO 密集,不经 crawapi 限流);M7 实测调", "tbd": false }
+  },
+  "edge_budgets": [
+    { "edge_id": "query_next_page",  "max_total_actions": 3,  "max_per_query": 1,    "max_pages": null, "provenance": "对齐 v1 实际硬限:rows[:3] 每 run ≤3 条翻页 query,每 query 仅 page_002 一跳;原理想值(30/2/3)留 M7 标定" },
+    { "edge_id": "video_to_author",  "max_total_actions": null, "max_per_content": 1, "max_pages": null, "provenance": "作者标识随 video 携带,loop 不单独执行此边、无预算消费;作者数上限见 author_to_works" },
+    { "edge_id": "author_to_works",  "max_total_actions": 3,  "max_works_per_author": 3, "max_pages": null, "provenance": "R7 放宽拍板 2026-06-12:2→3(真跑作者预算 2/2 顶格实证);每作者 ≤3 新作品不变;原理想值(10/翻3页)留后续标定" },
+    { "edge_id": "hashtag_to_query", "max_total_actions": 3,  "max_per_content": null, "max_tag_hops": null, "provenance": "R7 放宽拍板 2026-06-12:1→3(真跑 tag 预算 1/1 顶格、召回面收窄实证);原理想值(10/3/10)留后续标定" }
+  ],
+  "dedup": {
+    "query_key": "归一化 keyword(去空白/全半角/大小写统一)后全 run 去重;tag query 与 P2 初始 query 共用一个去重集",
+    "content_key": "platform_content_id 全 run 去重(跨 search/翻页/作者作品累积,commit 1cd1b94 语义)",
+    "author_key": "platform_author_id 全 run 去重(同作者只扩一次)"
+  },
+  "edge_permissions": {
+    "_meaning": "判定层→游走层的唯一接口:判定结果决定哪些出边放行(取代 walk_engine._can_expand_from_decision 硬编码,亦即原 path_stop/budget 包语义的新家);hashtag_to_query 的放行随 video_to_hashtag(同一 keep_only 回灌链)",
+    "_provenance": "现状行为来自 walk_engine v1 + E2E 实测(KEEP 内容 author_to_works success(low_budget));M4 拍板 2026-06-11",
+    "ADD_TO_CONTENT_POOL":     { "author_to_works": "allow",            "video_to_hashtag": "allow", "decision_to_asset": "allow" },
+    "KEEP_CONTENT_FOR_REVIEW": { "author_to_works": "allow_low_budget", "video_to_hashtag": { "value": "deny", "tbd": false, "note": "拍板 2026-06-11:从严 deny(v1 等价,防漂移)" }, "decision_to_asset": "deny" },
+    "REJECT_CONTENT":          { "author_to_works": "deny", "video_to_hashtag": "deny", "decision_to_asset": "deny", "note": "即 path_stop:rule_blocked/failed 不开任何出边" }
+  },
+  "reseed_quality_gate": {
+    "rule": "回灌边(reseed)仅从 gate=keep_only 放行的内容采集种子;V3 下 keep_only 的判据 = 判定 decision_action 经 edge_permissions 查表",
+    "tag_quality": "仅强相关 tag 可扩散(沿用 hashtag node 现有约束);弱平台(快手 topic_list 常空、youtube 仅正文正则)允许正则兜底但同样过质量门"
+  },
+  "budget_tiers": {
+    "normal": "edge_budgets 全额",
+    "low_budget": { "value": "halve_min_1", "provenance": "拍板 2026-06-11:各边预算减半向下取整至少 1,即 max(1, budget//2)", "tbd": false }
+  }
+}

+ 204 - 0
数据接口与来源/接口台账/B站.md

@@ -0,0 +1,204 @@
+# B站(bilibili)接口台账
+
+> 唯一证据来源:`/tmp/aiddit_captures/bili_search.json`、`bili_detail.json`、`bili_video_dl.json`(2026-06-11 真实抓包)。
+> 全部接口走统一爬虫网关 `host = http://crawler.aiddit.com`。
+> 本文档字段表与示例值全部取自上述 capture 真实响应,未做任何编造。
+
+## 平台级结论(先读)
+
+- **关键词搜索可用**:`/crawler/bilibili/keyword` `code=0`,一次返回 42 条(`bili_search.json`),每条含 `author/uid(实为 mid)/mid/bvid/aid/tag/arcurl/play/favorites` 等。
+- **详情可用**:`/crawler/bilibili/detail` `code=0`,返回归一化结构,含 `topic_list / video_url_list / channel_account_id`(`bili_detail.json`)。
+- **视频可下载**:`video_url_list[].video_url`(`.m4s`)直接 GET 返回 `206 / application/octet-stream`,实测收到 1,048,576 字节真实视频字节(`bili_video_dl.json`)。**下载 m4s 需带 `Referer: https://www.bilibili.com/`**(B站防盗链)。
+- **集合中无作者作品接口**:本批 capture 内 **没有** “按 mid/uid 拉某 up 主全部作品” 的接口。作者维度只能从 search 结果里的 `mid/author` 取标识,无法直接游走到该作者的作品列表。`author_to_works` 边在 B站当前缺乏数据源支撑。
+- **tag 来源**:search 的 `tag`(逗号分隔字符串)+ detail 的 `topic_list`(数组)两处均可取 hashtag。
+
+---
+
+## 接口 1:关键词搜索
+
+### ① 身份
+- `source_id`: **PLT_BILIBILI_KEYWORD**
+- 状态:**verified**(`bili_search.json` `code=0`,42 条)
+- 系统:crawler.aiddit.com
+
+### ② 请求标准
+- method:`POST`
+- path:`/crawler/bilibili/keyword`
+- 鉴权:网关侧统一处理,请求体无 token(capture 中 `request_body` 仅含业务参数)。
+- 参数表:
+
+| 参数 | 类型 | 必填 | 含义 | 真实值 |
+|---|---|---|---|---|
+| `keyword` | string | 是 | 搜索词 | `"彩虹"` |
+| `cursor` | string | 否 | 翻页游标,取上次响应的 `next_cursor`(页码语义,首页可省略) | 见 ④ |
+
+### ③ 真实 curl
+```bash
+curl -X POST 'http://crawler.aiddit.com/crawler/bilibili/keyword' \
+  -H 'Content-Type: application/json' \
+  -d '{"keyword":"彩虹"}'
+```
+
+### ④ 响应信封 + 翻页
+```json
+{ "code": 0, "msg": null,
+  "data": { "has_more": true, "next_cursor": "2", "data": [ {...}, ... 42 条 ] } }
+```
+- 信封:`code`(0=成功)/`msg`/`data`。
+- 翻页:外层 `data.has_more=true`,`data.next_cursor="2"`(页码字符串)。下一页把 `next_cursor` 回填到请求 `cursor`。
+- 列表在 `data.data`(数组,本次 42 条)。
+
+### ⑤ 字段台账(raw 名,取自 `bili_search.json` `data.data[0]`)
+
+| 字段名(raw) | 类型 | 含义 | 提取标注 | 真实示例值 |
+|---|---|---|---|---|
+| `bvid` | string | 内容ID(B站视频主键) | 直接可用 | `"BV1qd4y1x76w"` |
+| `aid` | int | 内容ID(av号,旧主键) | 直接可用 | `390658123` |
+| `title` | string | 标题(含 `<em class="keyword">` 高亮标签) | 需正则抽(剥 `<em>`) | `"《<em class=\"keyword\">彩虹</em>》TimeZ~..."` |
+| `arcurl` | string | 内容网页地址 | 直接可用 | `"http://www.bilibili.com/video/av390658123"` |
+| `pic` | string | 封面图(协议相对 `//`) | 需后处理(补 `https:`) | `"//i1.hdslb.com/bfs/archive/70c0...jpg"` |
+| `description` / `desc` | string | 简介 | 直接可用 | `"作词: 宋秉洋\n作曲: 宋秉洋..."` |
+| `author` | string | 作者昵称 | 直接可用 | `"碍音乐"` |
+| `mid` | int | 作者ID(UP主 mid,真实标识) | 直接可用 | `1919171246` |
+| `uid` | int | 作者ID字段(**本响应恒为 0,不可用**,以 `mid` 为准) | 需后处理(弃用,取 mid) | `0` |
+| `upic` | string | 作者头像 | 直接可用 | `"https://i2.hdslb.com/bfs/face/...jpg"` |
+| `tag` | string | hashtag(逗号分隔) | 需后处理(split `,`) | `"音乐分享官5.0,TimeZ,音乐分享官,彩虹"` |
+| `play` | int | 播放数 | 直接可用 | `2602076` |
+| `like` | int | 点赞数 | 直接可用 | `32770` |
+| `favorites` | int | 收藏数 | 直接可用 | `74847` |
+| `review` | int | 评论数 | 直接可用 | `1181` |
+| `danmaku` / `video_review` | int | 弹幕数 | 直接可用 | `3521` |
+| `duration` | string | 时长(`分:秒` 文本) | 需后处理(转秒) | `"3:58"` |
+| `pubdate` / `senddate` | int | 发布时间戳(秒) | 需后处理(×1000) | `1669795676` |
+| `typename` | string | 分区名 | 直接可用 | `"音乐综合"` |
+
+> 翻页字段:`data.has_more=true` / `data.next_cursor="2"`(真值)。
+
+### ⑥ 提取与后处理规则
+- 内容主键统一取 `bvid`(canonical `platform_content_id`),`aid` 作辅助。
+- `title` 必须正则剥离 `<em class="keyword">...</em>` 高亮标签。
+- 作者ID取 `mid`(`uid` 恒为 0,**禁止使用**)。
+- `tag` 按 `,` 切成数组 → hashtag。
+- `pic`/`upic` 协议相对地址需补 `https:`。
+- **B站集合中无作者作品接口**:拿到 `mid` 后无法在本批接口内拉该作者作品;`author_to_works` 在 B站不可走,作者维度仅作标识沉淀。
+
+### ⑦ 边界与失败
+- 限流:跨接口请求间隔 ≥ 15s。
+- 本接口 capture `code=0` 正常,无失败样本。
+
+### ⑧ 落点(canonical + 游走边)
+- canonical:`platform_content_id`(=`bvid`)、`platform_author_id`(=`mid`)、`title`、`content_url`(=`arcurl`)、`cover_url`(=`pic`)、`author_name`(=`author`)、`tags`(=`tag` split)、`stats.play/like/favorites/review/danmaku`、`publish_ts`、`has_more`/`next_cursor`。
+- 游走边:`search_page_to_content`(search→每条内容)。`video_to_author` 仅能落作者标识(mid/author),**`author_to_works` 无数据源、不可走**。`video_to_hashtag` 由 `tag` 提供。
+
+---
+
+## 接口 2:内容详情
+
+### ① 身份
+- `source_id`: **PLT_BILIBILI_CONTENT_DETAIL**
+- 状态:**verified**(`bili_detail.json` `code=0`)
+
+### ② 请求标准
+- method:`POST`,path:`/crawler/bilibili/detail`
+- 参数表:
+
+| 参数 | 类型 | 必填 | 含义 | 真实值 |
+|---|---|---|---|---|
+| `content_id` | string | 是 | 内容ID,传 `bvid` | `"BV1qd4y1x76w"` |
+
+### ③ 真实 curl
+```bash
+curl -X POST 'http://crawler.aiddit.com/crawler/bilibili/detail' \
+  -H 'Content-Type: application/json' \
+  -d '{"content_id":"BV1qd4y1x76w"}'
+```
+
+### ④ 响应信封 + 翻页
+```json
+{ "code": 0, "msg": null,
+  "data": { "has_more": false, "next_cursor": null, "data": { ...归一化对象... } } }
+```
+- 详情为单对象,`has_more=false`、`next_cursor=null`(无翻页)。
+
+### ⑤ 字段台账(raw 名,取自 `bili_detail.json` `data.data`)
+
+| 字段名(raw) | 类型 | 含义 | 提取标注 | 真实示例值 |
+|---|---|---|---|---|
+| `channel_content_id` | string | 内容ID(=bvid) | 直接可用 | `"BV1qd4y1x76w"` |
+| `content_link` | string | 内容网页地址 | 直接可用 | `"https://www.bilibili.com/video/BV1qd4y1x76w/"` |
+| `title` | string | 标题(无高亮标签) | 直接可用 | `"《彩虹》TimeZ~在夕阳下最后的拥抱 记得你甜美的心跳"` |
+| `body_text` | string | 正文/简介 | 直接可用 | `"作词: 宋秉洋\n作曲: 宋秉洋\n制作人: 司捷"` |
+| `content_type` | string | 内容类型 | 直接可用 | `"video"` |
+| `topic_list` | string[] | hashtag/话题数组 | 直接可用 | `["发现《彩虹》","音乐分享官","彩虹","TimeZ","音乐分享官5.0"]` |
+| `video_url_list[].video_url` | string | **视频地址(m4s,可下载)** | 需二次请求下载(带 Referer) | `"https://xy115...bilivideo.cn:8082/.../907810383_nb3-1-30016.m4s?..."` |
+| `video_url_list[].video_duration` | int | 视频时长(秒) | 直接可用 | `238` |
+| `voice_data.play_url` | string | 音轨地址(m4s,与视频分轨) | 需二次请求下载 | `"https://xy111...bilivideo.cn:8082/.../907810383_nb3-1-30216.m4s?..."` |
+| `image_url_list[].image_url` | string | 封面图 | 直接可用 | `"http://i1.hdslb.com/bfs/archive/70c0...jpg"` |
+| `channel_account_id` | string | 作者ID(mid 字符串形态) | 直接可用 | `"1919171246"` |
+| `channel_account_name` | string | 作者昵称 | 直接可用 | `"碍音乐"` |
+| `play_count` | int | 播放数 | 直接可用 | `2602076` |
+| `like_count` | int | 点赞数 | 直接可用 | `33628` |
+| `collect_count` | int | 收藏数 | 直接可用 | `74847` |
+| `comment_count` | int | 评论数 | 直接可用 | `1181` |
+| `share_count` | int | 分享数 | 直接可用 | `5367` |
+| `publish_timestamp` | int | 发布时间戳(毫秒) | 直接可用 | `1669795676000` |
+
+### ⑥ 提取与后处理规则
+- `channel_account_id` 与 search 的 `mid` 一致(`"1919171246"`),可作作者主键对齐。
+- B站视频/音频分轨(DASH):`video_url_list` 为视频轨,`voice_data.play_url` 为音频轨,**需各自下载后合并**。
+- **B站集合中无作者作品接口**:详情拿到 `channel_account_id` 后同样无法拉作者作品。
+
+### ⑦ 边界与失败
+- m4s 地址带 `deadline` 时效签名,过期需重新取详情;下载须及时。
+- 限流 ≥ 15s。
+
+### ⑧ 落点(canonical + 游走边)
+- canonical:`platform_content_id`(=`channel_content_id`)、`platform_author_id`(=`channel_account_id`)、`title`、`body_text`、`content_url`(=`content_link`)、`tags`(=`topic_list`)、`video_url`(=`video_url_list[].video_url`)、`audio_url`(=`voice_data.play_url`)、`stats.*`、`publish_ts`。
+- 游走边:`video_to_hashtag`(=`topic_list`)、`video_to_author`(落 `channel_account_id` 标识);`author_to_works` 不可走。
+
+---
+
+## 接口 3:视频下载(m4s 直链)
+
+### ① 身份
+- `source_id`: **PLT_BILIBILI_VIDEO_DL**
+- 状态:**verified**(`bili_video_dl.json`:`206 / octet-stream / 1MB 真实视频字节`)
+
+### ② 请求标准
+- method:`GET`(直连 B站 CDN,不经爬虫网关)
+- path:详情返回的 `video_url_list[].video_url`(`*.bilivideo.cn:8082/.../*.m4s`)
+- 鉴权:**必须带 `Referer: https://www.bilibili.com/`**(防盗链);URL 自带 `deadline` 签名。
+
+### ③ 真实 curl
+```bash
+curl -L 'https://xy115x231x41x20xy.mcdn.bilivideo.cn:8082/v1/resource/upgcxcode/83/03/907810383/907810383_nb3-1-30016.m4s?...' \
+  -H 'Referer: https://www.bilibili.com/' \
+  -o part_video.m4s
+```
+
+### ④ 响应信封 + 翻页
+- 二进制流,无 JSON 信封;实测 `HTTP 206 Partial Content`,`Content-Range: bytes 0-1048575/1766147`,`bytes_received=1048576`,`looks_like_video=true`(`bili_video_dl.json`)。
+
+### ⑤ 字段台账(取自 `bili_video_dl.json`)
+
+| 字段名(raw) | 类型 | 含义 | 提取标注 | 真实示例值 |
+|---|---|---|---|---|
+| `http_status` | int | HTTP 状态 | 直接可用 | `206` |
+| `content_type` | string | 内容类型 | 直接可用 | `"application/octet-stream"` |
+| `content_range` | string | 字节范围/总长 | 需后处理(解析总长) | `"bytes 0-1048575/1766147"` |
+| `bytes_received` | int | 本次收到字节数 | 直接可用 | `1048576` |
+| `looks_like_video` | bool | 字节嗅探判定为视频 | 直接可用 | `true` |
+
+### ⑥ 提取与后处理规则
+- **下载结论:bili_video_dl 实测 206,可下载**,得到真实视频字节。
+- m4s 必须带 `Referer: https://www.bilibili.com/`,否则防盗链拦截。
+- DASH 分轨:视频轨 + `voice_data.play_url` 音频轨需分别下载后合并(ffmpeg)。
+- 大文件用 `Range` 分块续传(`Content-Range` 给出总长 1766147)。
+
+### ⑦ 边界与失败
+- `deadline` 过期则直链失效,须回到详情接口重取。
+- 限流 ≥ 15s。
+
+### ⑧ 落点(canonical + 游走边)
+- canonical:`video_blob`(落地视频文件,供多模态分析)。
+- 无新增游走边;属 `video_to_*` 之后的物料下载阶段(提取标注:**需后处理下载**)。

+ 93 - 0
数据接口与来源/接口台账/github.md

@@ -0,0 +1,93 @@
+# GitHub 接口台账(接口文档撰写岗 D — 次级平台)
+
+> 唯一证据来源:`/tmp/aiddit_captures/github_search.json`(`code=0` ✅)。host:`http://crawler.aiddit.com`。
+> **平台级关键发现:GitHub 接口搜的是「代码仓库」,不是视频内容。** item 为 repo(`name`=仓库名 / `git_url` / `topics` 等),无视频地址、无播放/时长字段。topics 即 tag。本平台作为「次级 / 非视频」来源接入,下游不可按视频内容处理。
+
+平台仅一个接口:
+
+- `PLT_GITHUB_KEYWORD` — 关键词搜索代码仓库(verified ✅,**非视频**)
+
+---
+
+## 接口:GitHub 关键词搜索 `PLT_GITHUB_KEYWORD`
+
+### ① 身份
+| 项 | 值 |
+|---|---|
+| source_id | `PLT_GITHUB_KEYWORD` |
+| display_name | Crawapi GitHub 关键词搜索(代码仓库) |
+| 平台 channel | GitHub |
+| 接口路径 | `/crawler/github/keyword` |
+| 状态 | **verified ✅**(capture `github_search.json`,`code=0`,返回 10 条 repo item + 翻页) |
+| 用途 | 关键词 → 代码仓库列表(**非视频内容源**) |
+
+### ② 请求标准
+- **method**:POST
+- **path**:`http://crawler.aiddit.com/crawler/github/keyword`
+- **鉴权**:抓包 `request_body` 含 `token` 字段,但本次为**空串** `""`(统一走 crawler 网关,base_url 由 `CONTENTFIND_API_CRAWAPI_BASE_URL` 提供)。
+- **Content-Type**:`application/json`
+
+| 参数 | 类型 | 必填 | 含义 | 抓包真值 |
+|---|---|---|---|---|
+| `keyword` | string | 是 | 搜索关键词 | `"彩虹"` |
+| `token` | string | 否 | 翻页 token(首页空串;下一页取 response 的 `next_cursor`) | `""` |
+
+### ③ 真实 curl
+```bash
+curl -X POST 'http://crawler.aiddit.com/crawler/github/keyword' \
+  -H 'Content-Type: application/json' \
+  -d '{"keyword":"彩虹","token":""}'
+```
+
+### ④ 响应信封 + 翻页
+信封:`{ code, msg, data }`,`code=0`。
+```
+data.has_more   = true
+data.next_cursor= "1"          ← 真值为短页码风格字符串(不是长 token)
+data.data       = [ {repo item}, ... ]   ← 本次抓包 10 条
+```
+**翻页规则**:`has_more=true` 时,把 response 的 `next_cursor`(如 `"1"`)作为下一次请求的 **`token`** 参数传回(请求参数名为 `token`,响应字段名为 `next_cursor`,二者对应)。GitHub 的 cursor 是**短页码字符串**,与 YouTube 的长 token 不同。
+
+### ⑤ 字段台账表(raw 名)
+来源:`github_search.json` → `data.data[]`。
+
+| 字段名(raw) | 类型 | 含义 | 提取标注 | 真实示例值 |
+|---|---|---|---|---|
+| `id` | string | **内容 id**(repo id,字符串) | 直接可用 | `702272852` |
+| `hl_name` | string | **标题 / 仓库全名**(`owner/repo`,含 `<em>` 高亮标记) | 需正则抽(去 `<em></em>`) | `v03413/BEpusdt` |
+| `repo.repository.name` | string | 仓库名(纯名,无 owner) | 直接可用 | `BEpusdt` |
+| `repo.repository.owner_login` | string | **作者**(owner 登录名) | 直接可用 | `v03413` |
+| `repo.repository.owner_id` | int | **作者 id**(owner 数字 id) | 直接可用 | `49953737` |
+| `hl_trunc_description` | string | 仓库描述(截断,含 `<em>` 高亮) | 需正则抽(去 `<em></em>`) | `一款更好用的个人加密货币收款网关...支持独角数卡 <em>彩</em><em>虹</em>易支付` |
+| `topics` | array<string> | **tag**(仓库 topics,多数为空数组) | 直接可用(即 tag) | `["vue"]`;`["markdown","youtube","pixiv",...]`;常见 `[]` |
+| `language` | string\|null | 主语言 | 直接可用 | `Go` / `PHP` / `null` |
+| `followers` | int | star/关注数 | 直接可用 | `1626` |
+| `archived` | bool | 是否归档 | 直接可用 | `false` |
+| `repo.repository.updated_at` | string(ISO) | 仓库更新时间 | 直接可用 | `2026-06-10T01:28:04.341Z` |
+| `repo.repository.has_issues` | bool | 是否开启 issue | 直接可用 | `true` |
+| `type` | string | 仓库可见性 | 直接可用 | `Public` |
+| `has_more` | bool | **翻页**:是否还有下一页 | 直接可用 | `true` |
+| `next_cursor` | string | **翻页**:下一页 token(短页码,回传到请求 `token`) | 直接可用 | `1` |
+
+> **内容 url / git_url 推导**:抓包 item 内**无独立 `link`/`git_url`/`html_url` 字段**,仓库 url 须由 `hl_name`(去高亮后的 `owner/repo`)拼出:`https://github.com/{owner}/{repo}`。提取标注=需后处理(拼接)。
+
+### ⑥ 提取与后处理规则
+- **本平台是代码仓库,非视频**:无 `video_id` / `duration` / `view_count` / `video_url` 等任何视频字段。下游不可按「视频内容」流程处理,应作为「仓库/文本资产」类内容。
+- `hl_name` 与 `hl_trunc_description` 含搜索高亮标记 `<em>...</em>`,落库前须正则 `</?em>` 去除。
+- **tag = `topics`**:直接作为 tags 落库;注意多数仓库 `topics=[]`(空),少数才有(如 `["vue"]`)。
+- 仓库 url 无现成字段,需用 `hl_name`(清洗后)拼 `https://github.com/{owner/repo}`。
+- `owner_login`/`owner_id` 即作者;GitHub 无「频道」概念,作者即仓库 owner。
+
+### ⑦ 边界与失败
+- 单次约 10 条;`has_more=true` 时透传 `next_cursor → token` 翻页。
+- 限流:请求间隔 **≥ 15s**。
+- 多数 item `topics=[]`、`language=null`,下游不可强假定非空。
+- 无视频/媒体文件,无 detail 接口抓包(本批次只验证了 search)。
+
+### ⑧ 落点(canonical + 游走边)
+- canonical 映射:`id → platform_content_id`、`owner_id`(或 `owner_login`)`→ platform_author_id`、`topics → tags`、拼出的 `https://github.com/{owner/repo}` → content url。
+- 游走边:
+  - `search_page_to_content`:搜索页 → 各 repo `id`。
+  - `video_to_author`(此处语义为 content→author):`id → owner_id/owner_login`。
+  - `video_to_hashtag`(此处语义为 content→tag):`id → topics[]`(topics 即 tag;空时不产生边)。
+- 标注:内容类型为「代码仓库」,非视频,沉淀时打类型标记以免误入视频处理链路。

+ 167 - 0
数据接口与来源/接口台账/youtube.md

@@ -0,0 +1,167 @@
+# YouTube 接口台账(接口文档撰写岗 D — 次级平台)
+
+> 唯一证据来源:`/tmp/aiddit_captures/youtube_search.json`、`/tmp/aiddit_captures/youtube_detail.json`(均 `code=0` ✅)。
+> host:`http://crawler.aiddit.com`。本文所有字段、示例值、翻页 token 均取自真实抓包,未编造。
+> **平台级关键发现:detail 接口归一化结构里 `video_url_list` / `image_url_list` 为空数组 → 视频文件不可经本平台接口直取**,须另走字幕 / 其它通道。详见各接口第 ⑥⑦ 段。
+
+平台含两个接口:
+
+- `PLT_YOUTUBE_KEYWORD` — 关键词搜索(verified ✅)
+- `PLT_YOUTUBE_DETAIL` — 内容详情(verified ✅,但**无视频地址**)
+
+---
+
+## 接口一:YouTube 关键词搜索 `PLT_YOUTUBE_KEYWORD`
+
+### ① 身份
+| 项 | 值 |
+|---|---|
+| source_id | `PLT_YOUTUBE_KEYWORD` |
+| display_name | Crawapi YouTube 关键词搜索 |
+| 平台 channel | YouTube |
+| 接口路径 | `/crawler/youtube/keyword` |
+| 状态 | **verified ✅**(capture `youtube_search.json`,`code=0`,返回 20 条 item + 翻页 token) |
+| 用途 | 关键词 → 视频列表,搜索发现阶段入口 |
+
+### ② 请求标准
+- **method**:POST
+- **path**:`http://crawler.aiddit.com/crawler/youtube/keyword`
+- **鉴权**:抓包 `request_body` 内无 token / key 字段;统一走 crawler 网关,base_url 由环境变量 `CONTENTFIND_API_CRAWAPI_BASE_URL` 提供。
+- **Content-Type**:`application/json`
+
+| 参数 | 类型 | 必填 | 含义 | 抓包真值 |
+|---|---|---|---|---|
+| `keyword` | string | 是 | 搜索关键词 | `"彩虹"` |
+| `next_cursor` | string | 否 | 翻页游标(首页不传;取上一页 response 的 `next_cursor`) | 见 ④(长 token) |
+
+> 注:抓包仅传了 `keyword`。`next_cursor` 为翻页推断参数(response 已返回 `has_more=true` + `next_cursor` 长 token),首页无需传。
+
+### ③ 真实 curl
+```bash
+curl -X POST 'http://crawler.aiddit.com/crawler/youtube/keyword' \
+  -H 'Content-Type: application/json' \
+  -d '{"keyword":"彩虹"}'
+```
+
+### ④ 响应信封 + 翻页
+信封:`{ code, msg, data }`,`code=0` 为成功。
+```
+data.has_more   = true
+data.next_cursor= "EqMDEgblvanombkamANDQUFTQmdnRkVBRVlBMGdVZ2dFTE1VdEVURlZRWVRBeFdqaUNB...%3D%3D"   ← 真值为 URL-encoded 长 token(base64 风格,约 400+ 字符)
+data.data       = [ {video item}, ... ]   ← 本次抓包 20 条
+```
+**翻页规则**:`has_more=true` 时,把 response 的 `next_cursor`(长 token,原样、含 `%3D%3D` 等已编码字符)作为下一次请求的 `next_cursor` 传回。token 极长,存储时按字符串整体保存,不要做截断 / 二次 URL 编码。
+
+### ⑤ 字段台账表(raw 名)
+来源:`youtube_search.json` → `data.data[]`。
+
+| 字段名(raw) | 类型 | 含义 | 提取标注 | 真实示例值 |
+|---|---|---|---|---|
+| `video_id` | string | **内容 id**(YouTube 视频 id) | 直接可用 | `1KDLUPa01Z8` |
+| `title` | string | **标题** | 直接可用 | `宇宙人 Cosmos People【彩虹 Rainbow】歌詞版MV Lyrics Video @CosmosPeople` |
+| `author` | string | **作者**(频道名展示名) | 直接可用 | `滾石唱片 ROCK RECORDS` |
+| `channel_id` | string | **作者 id**(频道 id,部分 item 为空串) | 直接可用(可能为 `""`) | `UCPcF3KTqhD67ADkukx_OeDg`;空例 `lfg7Cj7scww` 条目为 `""` |
+| `url` | string | **内容 url**(watch 链接) | 直接可用 | `https://www.youtube.com/watch?v=1KDLUPa01Z8` |
+| `description_snippet` | string | 描述摘要(截断) | 直接可用 | `【ROCK 歌詞版MV】 歡迎訂閱滾石唱片YouTube官方頻道→ ...` |
+| `duration` | string | 时长(人读) | 需后处理(`mm:ss`→秒,可选) | `4:22` |
+| `view_count` | string | 播放数(带逗号 + "views" 文本) | 需正则抽(取数字) | `137,357 views` |
+| `published_time` | string | 发布相对时间(部分为空) | 需后处理(相对→绝对,可选) | `7 months ago`;空例 `rF4U0dH6mrI` 为 `""` |
+| `thumbnails[].url` | string | 封面图 url(数组,多档分辨率) | 直接可用 | `https://i.ytimg.com/vi/1KDLUPa01Z8/hq720.jpg?...` |
+| `has_more` | bool | **翻页**:是否还有下一页 | 直接可用 | `true` |
+| `next_cursor` | string | **翻页**:下一页游标(长 token) | 直接可用(透传) | `EqMDEgblvanombkamANDQUFTQmdn...%3D%3D` |
+
+### ⑥ 提取与后处理规则
+- `video_id` 即 canonical `platform_content_id`;`channel_id` 即 canonical `platform_author_id`(注意**会出现空串**,落库时需判空 / 回退)。
+- 视频可访问页面 = `url`(watch 链接),但**搜索结果不含可下载的视频文件地址**;视频文件须见接口二说明(detail 亦无)。
+- `view_count` 含逗号与 "views" 文本,需正则 `[\d,]+` 抽数字再去逗号。
+- 搜索结果**无 tag/hashtag 字段**(YouTube 搜索 item 不返回 topics/hashtags;hashtag 需从 detail 的 `body_text` 正则抽,见接口二)。
+
+### ⑦ 边界与失败
+- 单次约 20 条;`has_more=true` 需透传 `next_cursor` 翻页。
+- 限流:统一遵循 crawler 网关约束,**请求间隔 ≥ 15s**。
+- `channel_id` 可能为空串,下游不可强假定非空。
+
+### ⑧ 落点(canonical + 游走边)
+- canonical 映射:`video_id → platform_content_id`、`channel_id → platform_author_id`、`title/url/author` 直接落 content。无 tag 字段(tags 留空,或后续从 detail 抽)。
+- 游走边:
+  - `search_page_to_content`:搜索页 → 各 `video_id` 内容。
+  - `video_to_author`:`video_id → channel_id`(频道)。
+  - `video_to_hashtag`:搜索结果**无 hashtag**,此边在搜索阶段不产生;须经 detail 的 `body_text` 抽 `#xxx` 后产生(见接口二 ⑥)。
+
+---
+
+## 接口二:YouTube 内容详情 `PLT_YOUTUBE_DETAIL`
+
+### ① 身份
+| 项 | 值 |
+|---|---|
+| source_id | `PLT_YOUTUBE_DETAIL` |
+| display_name | Crawapi YouTube 内容详情 |
+| 接口路径 | `/crawler/youtube/detail` |
+| 状态 | **verified ✅(带重大限制)**:capture `youtube_detail.json` `code=0`,结构完整,但 `video_url_list=[]` / `image_url_list=[]` → **无视频/图片地址** |
+| 用途 | 单视频 id → 完整正文 / 统计 / 频道信息(**不含可下载视频**) |
+
+### ② 请求标准
+- **method**:POST
+- **path**:`http://crawler.aiddit.com/crawler/youtube/detail`
+- **鉴权**:无显式 token(同接口一)。
+
+| 参数 | 类型 | 必填 | 含义 | 抓包真值 |
+|---|---|---|---|---|
+| `content_id` | string | 是 | 视频 id(= 搜索结果 `video_id`) | `1KDLUPa01Z8` |
+
+### ③ 真实 curl
+```bash
+curl -X POST 'http://crawler.aiddit.com/crawler/youtube/detail' \
+  -H 'Content-Type: application/json' \
+  -d '{"content_id":"1KDLUPa01Z8"}'
+```
+
+### ④ 响应信封 + 翻页
+信封:`{ code, msg, data }`,`code=0`。
+```
+data.has_more   = false
+data.next_cursor= null            ← detail 单条,无翻页
+data.data       = { 归一化内容对象 }   ← 注意是对象(嵌套 data.data),非数组
+```
+**翻页规则**:detail 无翻页(`has_more=false`,`next_cursor=null`)。
+
+### ⑤ 字段台账表(raw 名)
+来源:`youtube_detail.json` → `data.data{}`。
+
+| 字段名(raw) | 类型 | 含义 | 提取标注 | 真实示例值 |
+|---|---|---|---|---|
+| `channel_content_id` | string | **内容 id** | 直接可用 | `1KDLUPa01Z8` |
+| `title` | string | **标题** | 直接可用 | `宇宙人 Cosmos People【彩虹 Rainbow】歌詞版MV Lyrics Video ‪@CosmosPeople‬` |
+| `content_link` | string | **内容 url**(watch 链接) | 直接可用 | `https://www.youtube.com/watch?v=1KDLUPa01Z8` |
+| `body_text` | string | 完整描述正文(含 `#宇宙人 #彩虹 #歌詞版MV` 等 hashtag 与外链) | 需正则抽(hashtag、外链) | `【ROCK 歌詞版MV】... #宇宙人 #彩虹 #歌詞版MV ...` |
+| `content_type` | string | 内容类型 | 直接可用 | `video` |
+| `channel_account_id` | string | **作者 id**(频道账号 id,注意与搜索 `channel_id` 不同体系:32 位 hash) | 直接可用 | `c938a12dd25cf2d83a66e9ad3b6dcfd2` |
+| `channel_account_name` | string | **作者**(频道名) | 直接可用 | `滾石唱片 ROCK RECORDS` |
+| `video_url_list` | array | **视频文件地址列表** | **空数组 → 视频不可直取** | `[]` |
+| `image_url_list` | array | 图片地址列表 | **空数组** | `[]` |
+| `topic_list` | null | 话题列表 | 后处理(本条为 `null`,hashtag 走 `body_text` 抽) | `null` |
+| `like_count` | int | 点赞数 | 直接可用 | `1404` |
+| `comment_count` | int | 评论数 | 直接可用 | `44` |
+| `view_count` / `play_count` / `share_count` / `collect_count` | null | 各互动数(本条为 null) | 直接可用(可能 null) | `null` |
+| `publish_timestamp` | int(ms) | 发布时间戳(毫秒) | 需后处理(ms→datetime) | `1781159156471` |
+| `is_original` | bool | 是否原创 | 直接可用 | `false` |
+| `channel` | int | 平台内部 channel 编号 | 直接可用 | `17` |
+
+### ⑥ 提取与后处理规则
+- **⚠ 视频不可直取**:`video_url_list=[]` 且 `image_url_list=[]`。本接口**不返回任何可下载的视频/图片文件地址**,只有正文文本与统计。需要视频内容时,须另走**字幕通道 / 其它下载手段**,不能依赖本平台接口拿到 mp4。
+- hashtag:detail 的 `topic_list=null`,但 `body_text` 末尾含 `#宇宙人 #彩虹 #歌詞版MV`,需正则 `#([^\s#]+)` 抽取后才能产生 hashtag 游走边。
+- 作者 id 双体系:搜索 `channel_id`(`UC...`)与 detail `channel_account_id`(32 位 hash)**不是同一编码**,落 canonical `platform_author_id` 时须明确以哪一个为准(建议以搜索 `channel_id` 的 `UC...` 为稳定主键,detail hash 作辅助)。
+- `publish_timestamp` 为毫秒,落库需 `/1000` 转秒或转 datetime。
+
+### ⑦ 边界与失败
+- 本接口**最大限制即视频地址为空**,不可作为视频获取通道。
+- detail 互动字段多为 `null`(仅 `like_count` / `comment_count` 有值),下游统计不可强假定非空。
+- 限流:请求间隔 **≥ 15s**。
+
+### ⑧ 落点(canonical + 游走边)
+- canonical 映射:`channel_content_id → platform_content_id`、`channel_account_id → platform_author_id`(或回退搜索 `channel_id`)、`body_text` 抽出的 `#xxx → tags`。
+- 游走边:
+  - `video_to_author`:`channel_content_id → channel_account_id`。
+  - `video_to_hashtag`:从 `body_text` 抽 `#xxx` 产生(detail 是 hashtag 的唯一来源)。
+  - **无** video 文件下载边(`video_url_list` 空)。

+ 189 - 0
数据接口与来源/接口台账/公众号.md

@@ -0,0 +1,189 @@
+# 公众号(微信 wei_xin)接口台账
+
+> 唯一证据来源:`/tmp/aiddit_captures/gzh_search.json`、`gzh_detail.json`、`gzh_account_info.json`(2026-06-11 真实抓包)。
+> 全部接口走统一爬虫网关 `host = http://crawler.aiddit.com`,平台名 `wei_xin`。
+> 字段表与示例值全部取自 capture 真实响应,未做任何编造。
+
+## 平台级结论(先读)
+
+- **关键词搜索可用**:`/crawler/wei_xin/keyword` `code=0`,一次返回 20 条文章(`gzh_search.json`),item = `{title, time, nick_name, url, cover_url, biz}`。
+- **作者血缘缺口**:搜索结果里 **`nick_name` 与 `biz` 字段均为空字符串**,作者标识只能从 `url` 的 `__biz=...` 参数里**正则抽取**。即“作者只有 biz,没有独立 account_id”。
+- **详情可用**:`/crawler/wei_xin/detail` `code=0`,用文章 `content_link` 取归一化正文(`gzh_detail.json`)。
+- **号主信息走 account_info(可用)**:`/crawler/wei_xin/account_info` `code=0`,同样用 `content_link` 取号主 `account_name / biz_info / wx_gh`(`gzh_account_info.json`)。**这是补齐作者昵称的唯一可达路径。**
+- **blogger 接口不可达**:本批 capture 内 **没有** “按 biz/号 拉该公众号全部历史文章” 的 blogger/作品列表接口;`author_to_works` 在公众号走不通,只能逐篇 `content_link` → detail / account_info。
+- **无 tag**:公众号 detail `topic_list=null`,**整平台无 hashtag**,`video_to_hashtag` 不可走。
+
+---
+
+## 接口 1:关键词搜索
+
+### ① 身份
+- `source_id`: **PLT_WEIXIN_KEYWORD**
+- 状态:**verified**(`gzh_search.json` `code=0`,20 条)
+
+### ② 请求标准
+- method:`POST`,path:`/crawler/wei_xin/keyword`
+- 参数表:
+
+| 参数 | 类型 | 必填 | 含义 | 真实值 |
+|---|---|---|---|---|
+| `keyword` | string | 是 | 搜索词 | `"彩虹"` |
+| `cursor` | string | 否 | 翻页游标,取上次 `next_cursor` | `"0"`(首页) |
+
+### ③ 真实 curl
+```bash
+curl -X POST 'http://crawler.aiddit.com/crawler/wei_xin/keyword' \
+  -H 'Content-Type: application/json' \
+  -d '{"keyword":"彩虹","cursor":"0"}'
+```
+
+### ④ 响应信封 + 翻页
+```json
+{ "code": 0, "msg": null,
+  "data": { "has_more": true, "next_cursor": "1", "data": [ {...}, ... 20 条 ] } }
+```
+- 翻页:`data.has_more=true`、`data.next_cursor="1"`(真值,页码字符串),回填到 `cursor`。
+
+### ⑤ 字段台账(raw 名,取自 `gzh_search.json` `data.data[0]`)
+
+| 字段名(raw) | 类型 | 含义 | 提取标注 | 真实示例值 |
+|---|---|---|---|---|
+| `url` | string | 文章地址(含 `__biz/mid/idx/sn`),既是内容定位也是作者定位 | 直接可用(且需正则抽 biz/内容id) | `"http://mp.weixin.qq.com/s?__biz=MzI5NjAxMTgzNg==&mid=2247483744&idx=1&sn=eb484d234c5579d567c87d9519351b74&..."` |
+| `title` | string | 标题(含 `<em class="highlight">` 高亮) | 需正则抽(剥 `<em>`) | `"<em class=\"highlight\">彩虹</em>股份(600707)深度分析报告"` |
+| `cover_url` | string | 封面图 | 直接可用 | `"https://mmbiz.qpic.cn/mmbiz_jpg/fNx5Iic5WA7X9043...jpeg"` |
+| `time` | int | 发布时间戳(秒) | 需后处理(×1000) | `1781151948` |
+| `nick_name` | string | 作者昵称(**本响应恒为空串,不可用**) | 需二次请求(走 account_info 补) | `""` |
+| `biz` | string | 作者标识(**本响应恒为空串,须从 url 抽 `__biz`**) | 需正则抽(从 `url`) | `""`(url 内 `__biz=MzI5NjAxMTgzNg==`) |
+
+> 翻页字段:`data.has_more=true` / `data.next_cursor="1"`(真值)。
+
+### ⑥ 提取与后处理规则
+- 内容ID:从 `url` 正则抽 `__biz` + `mid` + `idx` + `sn` 组合,或直接以 `url`(去 chksm/scene 后归一)为内容定位键。
+- **作者标识只有 biz,且 search item 的 `biz` 为空**:必须正则 `__biz=([^&]+)` 从 `url` 抽取(示例 `MzI5NjAxMTgzNg==`)。`nick_name` 为空,作者昵称须二次走 account_info。
+- `title` 正则剥离 `<em class="highlight">`。
+
+### ⑦ 边界与失败
+- 作者血缘弱:search 仅给 biz(还得自抽),昵称需补请求。
+- 限流 ≥ 15s。
+
+### ⑧ 落点(canonical + 游走边)
+- canonical:`platform_content_id`(从 `url` 抽 `__biz+mid+idx`)、`platform_author_id`(=`biz`,从 `url` 抽)、`title`、`content_url`(=`url`)、`cover_url`、`publish_ts`(=`time`)、`has_more`/`next_cursor`。
+- 游走边:`search_page_to_content`;`video_to_author` 仅落 `biz` 标识(昵称需 account_info 补);**`author_to_works` 走不通(无 blogger 接口)**;**`video_to_hashtag` 不可走(无 tag)**。
+
+---
+
+## 接口 2:文章详情
+
+### ① 身份
+- `source_id`: **PLT_WEIXIN_CONTENT_DETAIL**
+- 状态:**verified**(`gzh_detail.json` `code=0`)
+
+### ② 请求标准
+- method:`POST`,path:`/crawler/wei_xin/detail`
+- 参数表:
+
+| 参数 | 类型 | 必填 | 含义 | 真实值 |
+|---|---|---|---|---|
+| `content_link` | string | 是 | 文章地址(search 的 `url`) | `"http://mp.weixin.qq.com/s?__biz=MzI5NjAxMTgzNg==&mid=2247483744&idx=1&sn=eb484d...&..."` |
+
+### ③ 真实 curl
+```bash
+curl -X POST 'http://crawler.aiddit.com/crawler/wei_xin/detail' \
+  -H 'Content-Type: application/json' \
+  -d '{"content_link":"http://mp.weixin.qq.com/s?__biz=MzI5NjAxMTgzNg==&mid=2247483744&idx=1&sn=eb484d234c5579d567c87d9519351b74&scene=7#rd"}'
+```
+
+### ④ 响应信封 + 翻页
+```json
+{ "code": 0, "msg": null,
+  "data": { "has_more": false, "next_cursor": null, "data": { ...归一化对象... } } }
+```
+- 单对象,无翻页。
+
+### ⑤ 字段台账(raw 名,取自 `gzh_detail.json` `data.data`)
+
+| 字段名(raw) | 类型 | 含义 | 提取标注 | 真实示例值 |
+|---|---|---|---|---|
+| `channel_content_id` | string | 内容ID(网关归一化 hash) | 直接可用 | `"d9ac580027959372cc141815a3f906a3"` |
+| `content_link` | string | 归一化文章地址 | 直接可用 | `"https://mp.weixin.qq.com/s?__biz=MzI5NjAxMTgzNg==&idx=1&mid=2247483744&sn=eb484d..."` |
+| `title` | string | 标题(无高亮) | 直接可用 | `"彩虹股份(600707)深度分析报告"` |
+| `body_text` | string | 正文全文 | 直接可用 | `"报告日期:2026年6月10日 | 当前股价:12.45元 ..."`(长文) |
+| `content_type` | string | 类型 | 直接可用 | `"note"` |
+| `topic_list` | null | 话题(**公众号恒为 null,无 tag**) | 需后处理(置空数组) | `null` |
+| `image_url_list[].image_url` | string | 正文配图 | 直接可用 | `"https://mmbiz.qpic.cn/mmbiz_jpg/fNx5Iic5WA7X140yn...jpeg"` |
+| `video_url_list` | null | 视频列表(本文为图文,无视频) | 需后处理 | `null` |
+| `channel_account_id` | string | 作者ID(网关归一化号主 hash,**非 biz**) | 直接可用 | `"969a9ad954ec605c67110cdb8c42f301"` |
+| `channel_account_name` | null | 作者昵称(**detail 恒为 null,须 account_info 补**) | 需二次请求 | `null` |
+| `location` | string | 发布地 | 直接可用 | `"广东"` |
+| `view_count` | int | 阅读数 | 直接可用 | `15` |
+| `like_count` | int | 点赞数 | 直接可用 | `0` |
+| `publish_timestamp` | int | 发布时间戳(毫秒) | 直接可用 | `1781151960000` |
+
+### ⑥ 提取与后处理规则
+- detail 的 `channel_account_id`(hash)与 account_info 的 `channel_account_id` 一致(`969a9ad9...`),可作号主主键对齐;但 **`channel_account_name=null`**,昵称必须走 account_info。
+- `topic_list=null` → 公众号无 hashtag,统一置空。
+- 注意:detail 的 `channel_account_id` 是网关 hash,**与作者血缘里的 `biz` 不是同一标识**,两者需都沉淀(biz 来自 url,hash 来自 detail/account_info)。
+
+### ⑦ 边界与失败
+- 昵称缺口:detail 不给昵称,须额外一次 account_info。
+- 限流 ≥ 15s。
+
+### ⑧ 落点(canonical + 游走边)
+- canonical:`platform_content_id`(=`channel_content_id`)、`platform_author_id`(=`channel_account_id` hash / 另存 `biz`)、`title`、`body_text`、`content_url`(=`content_link`)、`images`(=`image_url_list`)、`stats.view/like`、`publish_ts`、`location`。
+- 游走边:`video_to_author`(落号主 hash 标识,昵称待 account_info 补);`author_to_works` 不可走;`video_to_hashtag` 不可走(tag=null)。
+
+---
+
+## 接口 3:号主信息(account_info)
+
+### ① 身份
+- `source_id`: **PLT_WEIXIN_ACCOUNT_INFO**
+- 状态:**verified**(`gzh_account_info.json` `code=0`)
+
+### ② 请求标准
+- method:`POST`,path:`/crawler/wei_xin/account_info`
+- 参数表:
+
+| 参数 | 类型 | 必填 | 含义 | 真实值 |
+|---|---|---|---|---|
+| `content_link` | string | 是 | 文章地址(用任一该号文章 `url` 反查号主) | `"http://mp.weixin.qq.com/s?__biz=MzI5NjAxMTgzNg==&mid=2247483744&..."` |
+
+### ③ 真实 curl
+```bash
+curl -X POST 'http://crawler.aiddit.com/crawler/wei_xin/account_info' \
+  -H 'Content-Type: application/json' \
+  -d '{"content_link":"http://mp.weixin.qq.com/s?__biz=MzI5NjAxMTgzNg==&mid=2247483744&idx=1&sn=eb484d234c5579d567c87d9519351b74&scene=7#rd"}'
+```
+
+### ④ 响应信封 + 翻页
+```json
+{ "code": 0, "msg": null,
+  "data": { "has_more": false, "next_cursor": null, "data": { ...号主对象... } } }
+```
+- 单对象,无翻页。
+
+### ⑤ 字段台账(raw 名,取自 `gzh_account_info.json` `data.data`)
+
+| 字段名(raw) | 类型 | 含义 | 提取标注 | 真实示例值 |
+|---|---|---|---|---|
+| `channel_account_id` | string | 号主ID(网关归一化 hash,与 detail 一致) | 直接可用 | `"969a9ad954ec605c67110cdb8c42f301"` |
+| `account_name` | string | **号主昵称(补齐 search/detail 缺口的关键字段)** | 直接可用 | `"韭菜看透本质"` |
+| `account_link` | string | 号主主页链接 | 直接可用 | `"https://mp.weixin.qq.com/mp/profile_ext?action=home&__biz=MzI5NjAxMTgzNg==&scene=124#wechat_redirect"` |
+| `biz_info` | string | 作者 biz(与 url `__biz` 一致) | 直接可用 | `"MzI5NjAxMTgzNg=="` |
+| `wx_gh` | string | 公众号原始ID(gh_ 号) | 直接可用 | `"gh_d6a68990fe9c"` |
+| `gender` | string | 性别 | 直接可用 | `"其他"` |
+| `follower_count` | null | 粉丝数(本响应为 null,不可用) | 需后处理 | `null` |
+| `publish_count` | null | 发文数(null,**无作品列表**) | 需后处理 | `null` |
+
+### ⑥ 提取与后处理规则
+- **account_info 是公众号作者血缘的唯一可达补全**:用任一文章 `content_link` 反查,拿到 `account_name`(昵称)+ `biz_info`(=biz)+ `wx_gh`,把 search/detail 缺的昵称补上。
+- 三个作者标识对齐:`biz_info`(=url 的 `__biz`) ↔ `channel_account_id`(detail/account_info 同一 hash) ↔ `wx_gh`。
+- **仍无作品列表**:`publish_count=null`,account_info **不返回该号历史文章**,`author_to_works` 仍走不通。
+
+### ⑦ 边界与失败
+- 互动/粉丝指标(`follower_count`/`publish_count`/`like_count` 等)本响应全为 null,作者画像信息有限。
+- 限流 ≥ 15s。
+
+### ⑧ 落点(canonical + 游走边)
+- canonical:`platform_author_id`(=`channel_account_id` / 另存 `biz_info`、`wx_gh`)、`author_name`(=`account_name`)、`author_url`(=`account_link`)、`gender`。
+- 游走边:`video_to_author` 的昵称补全终点;**`author_to_works` 不可走**(无作品列表数据源)。

+ 76 - 0
数据接口与来源/接口台账/头条.md

@@ -0,0 +1,76 @@
+# 头条(头条号 tou_tiao_hao)接口台账(接口文档撰写岗 D — 次级平台)
+
+> 唯一证据来源:`/tmp/aiddit_captures/toutiao_search.json`、`/tmp/aiddit_captures/toutiao_search_retry.json`。host:`http://crawler.aiddit.com`。
+> **平台级关键发现:整平台失败(blocked)。** 两次抓包(含一次去掉 `content_type` 的重试)**均返回 `code=10000 / msg="未知错误" / data=null`**,未拿到任何真实 item、字段或翻页结构。本平台**当前不可用**,下游不应接入。
+
+平台仅一个接口(失败):
+
+- `PLT_TOUTIAO_KEYWORD` — 关键词搜索(**blocked ⛔**,code=10000 两次失败)
+
+---
+
+## 接口:头条号关键词搜索 `PLT_TOUTIAO_KEYWORD`
+
+### ① 身份
+| 项 | 值 |
+|---|---|
+| source_id | `PLT_TOUTIAO_KEYWORD` |
+| display_name | Crawapi 头条号关键词搜索 |
+| 平台 channel | 头条号(tou_tiao_hao) |
+| 接口路径 | `/crawler/tou_tiao_hao/keyword` |
+| 状态 | **blocked ⛔**(`toutiao_search.json` + `toutiao_search_retry.json` 均 `code=10000`,`data=null`) |
+| 用途 | 关键词 → 内容列表(**当前整平台不可用**) |
+
+### ② 请求标准
+- **method**:POST
+- **path**:`http://crawler.aiddit.com/crawler/tou_tiao_hao/keyword`
+- **鉴权**:抓包 `request_body` 无 token / key(同其它平台走 crawler 网关,base_url 由 `CONTENTFIND_API_CRAWAPI_BASE_URL` 提供)。
+- **Content-Type**:`application/json`
+
+| 参数 | 类型 | 必填 | 含义 | 抓包真值 |
+|---|---|---|---|---|
+| `keyword` | string | 是 | 搜索关键词 | `"彩虹"` |
+| `content_type` | string | 否 | 内容类型(首抓传 `video`,重试已去掉) | `"video"`(重试未传) |
+| `page` | int | 否 | 页码 | `0` |
+
+### ③ 真实 curl
+```bash
+# 首次(带 content_type)—— 返回 code=10000
+curl -X POST 'http://crawler.aiddit.com/crawler/tou_tiao_hao/keyword' \
+  -H 'Content-Type: application/json' \
+  -d '{"keyword":"彩虹","content_type":"video","page":0}'
+
+# 重试(去掉 content_type)—— 仍返回 code=10000
+curl -X POST 'http://crawler.aiddit.com/crawler/tou_tiao_hao/keyword' \
+  -H 'Content-Type: application/json' \
+  -d '{"keyword":"彩虹","page":0}'
+```
+
+### ④ 响应信封 + 翻页
+信封:`{ code, msg, data }`。两次抓包均为失败信封:
+```
+code = 10000
+msg  = "未知错误"
+data = null
+```
+**翻页规则**:无(`data=null`,无 `has_more` / `next_cursor`,无任何成功结构可记录)。
+
+### ⑤ 字段台账表(raw 名)
+**无可用字段** —— 两次响应 `data=null`,未返回任何 item,内容 id / 标题 / 作者 / url / tag / 翻页字段**全部未知**,不予编造。待平台修复(返回 `code=0`)后补抓再登记。
+
+| 字段名(raw) | 类型 | 含义 | 提取标注 | 真实示例值 |
+|---|---|---|---|---|
+| —(无) | — | 平台失败,无字段 | — | `data=null` |
+
+### ⑥ 提取与后处理规则
+不适用 —— 无成功响应。平台修复后再补。
+
+### ⑦ 边界与失败
+- **整平台 blocked**:`/crawler/tou_tiao_hao/keyword` 经两次真实请求(`toutiao_search.json` 带 `content_type=video`、`toutiao_search_retry.json` 去掉 `content_type`)**均返回 `code=10000 / msg="未知错误"`**。
+- 失败与参数无关(去掉 `content_type` 后仍 10000),判定为**平台/接口侧不可用**,非调用方参数问题。
+- 限流:统一约束请求间隔 **≥ 15s**(即便修复后亦适用)。
+- 处置:下游链路**跳过头条平台**;不要把它当作可用内容源;待 crawler 侧修复并复抓到 `code=0` 后再解锁登记。
+
+### ⑧ 落点(canonical + 游走边)
+- **无落点**:无内容数据,不产生 canonical `platform_content_id` / `platform_author_id` / `tags`,也不产生 `search_page_to_content` / `video_to_author` / `video_to_hashtag` 任何游走边。
+- registry 状态置 `blocked`,待修复后再定义映射。

+ 185 - 0
数据接口与来源/接口台账/小红书.md

@@ -0,0 +1,185 @@
+# 接口台账 · 小红书(xiao_hong_shu)
+
+> 唯一证据来源:`/tmp/aiddit_captures/` 下真实抓包。host=`http://crawler.aiddit.com`。
+> 整体状态:**部分可用** —— 搜索 `code=0` ✅、详情 `code=0` ✅、作者 blogger 请求超时 blocked。
+> 平台特征:以**图文为主**(`image_list` / `image_url_list`),搜索结果以**视频笔记**为主(`note_card.type=video`)。
+> **关键提取规则:搜索接口内容字段全部嵌在 `note_card` 嵌套下**(见下,这是核心抽取规则)。
+> 鉴权:抓包请求体无显式 token,统一走 crawler.aiddit.com 网关。
+
+---
+
+## 1. 关键词搜索(PLT_XIAOHONGSHU_KEYWORD)
+
+### ① 身份
+- source_id:`PLT_XIAOHONGSHU_KEYWORD`
+- 接口名:小红书关键词搜索
+- 用途:按关键词检索笔记(搜索页 → 内容)
+- 状态:**verified** ✅(`code=0` 有数据)。证据:`xhs_search.json`。
+
+### ② 请求标准
+- method:`POST`
+- path:`/crawler/xiao_hong_shu/keyword`
+- 鉴权:无显式 token(走网关)
+- 参数表:
+
+| 名 | 类型 | 必填 | 示例 |
+|---|---|---|---|
+| keyword | string | 是 | `"彩虹"` |
+| content_type | string | 否 | `"视频"`(可选笔记类型过滤) |
+| sort_type | string | 否 | `"综合"` |
+| publish_time | string | 否 | `""` |
+| cursor | string | 否 | `""`(首页传空) |
+
+### ③ 请求示例(真实 request_body)
+```bash
+curl -X POST 'http://crawler.aiddit.com/crawler/xiao_hong_shu/keyword' \
+  -H 'Content-Type: application/json' \
+  -d '{"keyword":"彩虹","content_type":"视频","sort_type":"综合","publish_time":"","cursor":""}'
+```
+
+### ④ 响应信封 + 翻页
+- 信封:`{code, msg, data}`,`code=0`,`msg=null`
+- `data` = `{has_more, next_cursor, data:[...]}`
+- 翻页真实取值:`has_more=false`,`next_cursor=null`(本次单页到底)
+
+### ⑤ 字段台账(raw 名)——⚠️ 内容字段嵌在 note_card 下
+> 列表项位于 `data.data[]`,每项结构:`item = {id, model_type, note_card}`。
+> **真正的内容字段都在 `note_card` 嵌套里**,提取必须深入 `note_card`(及其子对象 `note_card.user`、`note_card.interact_info`)。
+
+| 字段名(raw 路径) | 类型 | 含义 | 提取标注 | 真实示例值 |
+|---|---|---|---|---|
+| id | string | 笔记ID(内容ID) | 直接可用 | `696b90ce000000002102be77` |
+| model_type | string | 模型类型 | 直接可用 | `note` |
+| **note_card.type** | string | 笔记类型(图文/视频) | 直接可用(嵌套) | `video` |
+| **note_card.display_title** | string/null | 笔记标题 | 直接可用(嵌套,常null) | `彩虹🌈` / `null` |
+| **note_card.desc** | string | 正文/描述(含话题) | 直接可用 / tag需正则抽(嵌套) | `"夏日雨后彩虹草原 1. 核心主体…"` |
+| **note_card.image_list[].image_url** | string | 图片地址(图文主体) | 直接可用(嵌套) | `https://ci.xiaohongshu.com/1040g00831remfdem…?imageView2/2/w/1080/format/webp` |
+| **note_card.user.user_id** | string | 作者ID | 直接可用(嵌套) | `63ee8949000000000f0102f3` |
+| **note_card.user.nick_name** | string | 作者昵称 | 直接可用(嵌套) | `一方盛景` |
+| **note_card.user.nickname** | string | 作者昵称(同义冗余字段) | 直接可用(嵌套) | `一方盛景` |
+| **note_card.user.avatar** | string | 作者头像 | 直接可用(嵌套) | `https://sns-avatar-qc.xhscdn.com/avatar/…?imageView2/2/w/80/format/jpg` |
+| **note_card.interact_info.liked_count** | int | 点赞数 | 直接可用(嵌套) | `7` / `2363` |
+| **note_card.interact_info.collected_count** | int | 收藏数 | 直接可用(嵌套) | `1` / `380` |
+| **note_card.interact_info.comment_count** | int | 评论数 | 直接可用(嵌套) | `1` / `137` |
+| **note_card.interact_info.shared_count** | int | 分享数 | 直接可用(嵌套) | `0` / `826` |
+| **note_card.publish_timestamp** | long | 发布时间(秒) | 需后处理(嵌套,秒级) | `1768657102` |
+| has_more | bool | 是否有下一页 | 直接可用 | `false` |
+| next_cursor | string/null | 下一页游标 | 直接可用 | `null` |
+
+> 注意:搜索结果**不直接给视频直链**(仅 `image_list` 封面图);取视频/全文需对 `id` 走详情接口(见 §2)二次请求。
+
+### ⑥ 提取与后处理规则
+- **note_card 嵌套抽取(核心规则)**:遍历 `data.data[]`,对每个 `item`:内容ID取 `item.id`,其余全部从 `item.note_card.*` 取——`note_card.type`、`note_card.desc`、`note_card.display_title`、`note_card.image_list`、`note_card.user.user_id`、`note_card.user.nick_name`、`note_card.interact_info.*`、`note_card.publish_timestamp`。不要在顶层找内容字段。
+- **以图文为主**:小红书内容主体是 `image_list`(搜索)/`image_url_list`(详情);即使 `type=video`,搜索阶段也只给封面图,视频直链需走详情。
+- **tag**:从 `note_card.desc` 用正则抽 `#xxx`(如 `#好运彩虹`、`#雨后彩虹🌈`)。
+- 时间戳为**秒级**(`publish_timestamp=1768657102`),与视频号毫秒级不同,落库注意单位。
+
+### ⑦ 边界与失败
+- 搜索本次单次成功,未观察到抖动;限流 ≥15s。
+- 视频直链不在搜索结果,需二次请求详情。
+
+### ⑧ 落点
+- canonical:`platform_content_id`(←id)、`title`(←note_card.display_title,缺则 desc 截断)、`body_text`(←note_card.desc)、`cover_url`(←note_card.image_list[0].image_url)、`platform_author_id`(←note_card.user.user_id)、`author_name`(←note_card.user.nick_name)、`tags`(从 desc 正则)、`like_count`/`collect_count`/`comment_count`/`share_count`(←note_card.interact_info.*)、`publish_time`。
+- 游走边:`search_page_to_content`、`video_to_author`(note_card.user.user_id)、`video_to_hashtag`(desc 抽 tag);作者展开 `author_to_works` 依赖 blogger 接口(当前 blocked)。
+
+---
+
+## 2. 笔记详情(PLT_XIAOHONGSHU_DETAIL)
+
+### ① 身份
+- source_id:`PLT_XIAOHONGSHU_DETAIL`
+- 接口名:小红书笔记详情
+- 用途:按内容ID取全文/视频/精确互动数(内容补全 / 二次请求)
+- 状态:**verified** ✅(`code=0` 有数据)。证据:`xhs_detail.json`。
+
+### ② 请求标准
+- method:`POST` · path:`/crawler/xiao_hong_shu/detail`
+
+| 名 | 类型 | 必填 | 示例 |
+|---|---|---|---|
+| content_id | string | 是 | `696b90ce000000002102be77` |
+
+### ③ 请求示例
+```bash
+curl -X POST 'http://crawler.aiddit.com/crawler/xiao_hong_shu/detail' \
+  -H 'Content-Type: application/json' \
+  -d '{"content_id":"696b90ce000000002102be77"}'
+```
+
+### ④ 响应信封 + 翻页
+- `code=0`,`msg=null`,`data = {has_more, next_cursor, data:{...}}`(详情对象在 `data.data`,非嵌 note_card,字段扁平)
+- `has_more=false`,`next_cursor=null`
+
+### ⑤ 字段台账(raw 名)——详情为扁平结构(非 note_card)
+| 字段名(data.data 下) | 类型 | 含义 | 提取标注 | 真实示例值 |
+|---|---|---|---|---|
+| channel_content_id | string | 内容ID | 直接可用 | `696b90ce000000002102be77` |
+| content_link | string | 笔记链接 | 直接可用 | `https://www.xiaohongshu.com/explore/696b90ce000000002102be77` |
+| title | string | 标题 | 直接可用(可空) | `""` |
+| content_type | string | 类型 | 直接可用 | `video` |
+| body_text | string | 全文正文(含话题串) | 直接可用 / tag需正则抽 | `"夏日雨后彩虹草原\n1. 核心主体:…#彩虹的约定[话题]#…"` |
+| location | string | 归属地 | 直接可用 | `陕西` |
+| topic_list | array | 话题列表 | 直接可用 | `["彩虹的约定"]` |
+| image_url_list[].image_url | string | 图片地址 | 直接可用 | `https://ci.xiaohongshu.com/1040g00831remfdem…` |
+| image_url_list[].image_type | int | 图片类型 | 直接可用 | `2` / `1` |
+| video_url_list | array/null | 视频地址列表 | 需后处理下载(本样本null) | `null` |
+| channel_account_id | string | 作者ID | 直接可用 | `63ee8949000000000f0102f3` |
+| channel_account_name | string | 作者昵称 | 直接可用 | `一方盛景` |
+| like_count | int | 点赞数 | 直接可用 | `7` |
+| collect_count | int | 收藏数 | 直接可用 | `1` |
+| comment_count | int | 评论数 | 直接可用 | `1` |
+| share_count | int | 分享数 | 直接可用 | `0` |
+| publish_timestamp | long | 发布时间(ms) | 需后处理(/1000) | `1768657102000` |
+| is_original | bool | 是否原创 | 直接可用 | `false` |
+| is_cache | bool | 是否缓存命中 | 直接可用 | `true` |
+
+> 注意:详情接口的 `publish_timestamp` 为**毫秒**(`1768657102000`),与搜索接口的秒级(`1768657102`)不同——同一笔记两接口单位不一致,落库统一前必须按接口区分换算。
+
+### ⑥ 提取与后处理规则
+- 详情结构扁平,**不嵌 note_card**(与搜索不同),内容字段在 `data.data.*` 直接取。
+- 视频地址在 `video_url_list`(本样本 `null`,图文笔记常无);取到则需后处理下载。
+- 全文 `body_text` 比搜索 `desc` 完整,tag 从 `topic_list`(结构化)或 `body_text` 正则(`#xxx[话题]#`)抽取。
+
+### ⑦ 边界与失败
+- 本次成功;`is_cache=true` 表示命中缓存。限流 ≥15s。
+
+### ⑧ 落点
+- canonical:`platform_content_id`、`title`/`body_text`、`tags`(←topic_list)、`platform_author_id`(←channel_account_id)、`like_count`/`collect_count`/`comment_count`/`share_count`、`publish_time`、`location`。
+- 游走边:`video_to_author`、`video_to_hashtag`。
+
+---
+
+## 3. 作者主页 blogger(PLT_XIAOHONGSHU_BLOGGER)
+
+### ① 身份
+- source_id:`PLT_XIAOHONGSHU_BLOGGER`
+- 接口名:小红书博主作品列表
+- 用途:作者 → 作品(author_to_works)
+- 状态:**blocked(请求超时)**。证据:`xhs_blogger.json`(`error: timed out`)。
+
+### ② 请求标准
+- method:`POST` · path:`/crawler/xiao_hong_shu/blogger`
+
+| 名 | 类型 | 必填 | 示例 |
+|---|---|---|---|
+| account_id | string | 是 | `63ee8949000000000f0102f3` |
+| cursor | string | 否 | `""` |
+
+### ③ 请求示例
+```bash
+curl -X POST 'http://crawler.aiddit.com/crawler/xiao_hong_shu/blogger' \
+  -H 'Content-Type: application/json' \
+  -d '{"account_id":"63ee8949000000000f0102f3","cursor":""}'
+```
+
+### ④ 响应信封
+- 无响应,`error: timed out` → **失败(超时)**。
+
+### ⑤ 字段台账
+- 无数据(blocked)。
+
+### ⑥/⑦ 边界与失败
+- blocked:请求超时,未返回。建议加超时重试 + 退避;`account_id` 可由搜索结果 `note_card.user.user_id` 提供。
+
+### ⑧ 落点
+- 期望游走边 `author_to_works`,**当前超时 blocked**。

+ 230 - 0
数据接口与来源/接口台账/快手.md

@@ -0,0 +1,230 @@
+# 快手 接口台账
+
+> 唯一证据来源:`/tmp/aiddit_captures/` 下真实抓包。host = `http://crawler.aiddit.com`。
+> 涉及 capture:`kuaishou_search.json`、`kuaishou_detail.json`、`kuaishou_account_info.json`、`kuaishou_video_dl.json`。
+> 鉴权:所有 `crawler.aiddit.com` 接口实测**无 Authorization 头**;仅需 base_url(env `CONTENTFIND_API_CRAWAPI_BASE_URL`)。
+> 限流约定:两次调用间隔 ≥ 15s。
+> 结构特点:快手三个接口**返回的都是归一化结构**(`channel_content_id` / `channel_account_id` 等),无抖音那种 raw 原生结构差异。
+
+---
+
+## 一、关键词搜索 PLT_KUAISHOU_KEYWORD
+
+### ① 身份
+- source_id:`PLT_KUAISHOU_KEYWORD`
+- 接口名:快手关键词搜索 / kuai_shou keyword_v2
+- 用途:按关键词拉一页内容卡片(视频)。
+- 状态:**verified**(capture `kuaishou_search.json`,`code=0`)
+
+### ② 请求标准
+- method:`POST`
+- path:`/crawler/kuai_shou/keyword_v2`
+- 鉴权:无
+- 参数表:
+
+| 名 | 类型 | 必填 | 示例 |
+|---|---|---|---|
+| keyword | string | 是 | `彩虹` |
+
+> 注:实测请求体只含 `keyword`(无 cursor / sort_type 字段)。
+
+### ③ 请求示例
+```bash
+curl -X POST http://crawler.aiddit.com/crawler/kuai_shou/keyword_v2 \
+  -H 'Content-Type: application/json' \
+  -d '{"keyword":"彩虹"}'
+```
+
+### ④ 响应信封 + 翻页
+- 信封:`{ "code":0, "msg":null, "data":{ "has_more":false, "next_cursor":null, "data":[...] } }`
+- `has_more`:`false`(本次实测单页返回,无翻页游标)
+- `next_cursor`:`null`
+- `data.data`:数组,本页 `9` 条卡片(归一化结构)。
+
+### ⑤ 字段台账(单条卡片 = `data.data[i]`,归一化名)
+
+| 字段名 | 类型 | 含义 | 提取标注 | 真实示例值 |
+|---|---|---|---|---|
+| `channel_content_id` | string | 内容 id | 直接可用 | `3xepqgwddgbickc` |
+| `content_link` | string | 内容链接 | 直接可用 | `https://www.gifshow.com/fw/photo/3xepqgwddgbickc` |
+| `title` | string | 标题(实测可能 null) | 直接可用 | `null` |
+| `body_text` | string | 正文(实测可能 null) | 直接可用 | `null` |
+| `topic_list` | string[] | 话题 tag(实测 null) | 直接可用 | `null` |
+| `content_type` | string | 内容类型 | 直接可用 | `video` |
+| `video_url_list[].video_url` | string | 视频地址 | 需后处理下载 | `http://v23-3.kwaicdn.com/upic/2025/05/11/07/...b.mp4?pkey=...&tag=...&clientCacheKey=3xepqgwddgbickc_b.mp4...` |
+| `video_url_list[].video_duration` | int(秒) | 时长 | 直接可用 | `4` |
+| `image_url_list[].image_url` | string | 封面图 | 直接可用 | `http://p66-plat.wsukwai.com/upic/...540p_*.kvif?...` |
+| `channel_account_id` | string | 作者 id | 直接可用 | `3xfkwajatdh7p7i` |
+| `channel_account_name` | string | 作者昵称 | 直接可用 | `夏若.` |
+| `view_count` | int | 播放/观看数 | 直接可用 | `18472` |
+| `like_count` | int | 点赞 | 直接可用 | `75` |
+| `collect_count` | int | 收藏 | 直接可用 | `4` |
+| `comment_count` | int | 评论 | 直接可用 | `0` |
+| `share_count` | int | 分享 | 直接可用 | `0` |
+| `publish_timestamp` | int(ms) | 发布时间戳(毫秒) | 直接可用 | `1746919311784` |
+| `data.has_more` | bool | 是否有下一页 | 直接可用 | `false` |
+| `data.next_cursor` | string | 下一页游标 | 直接可用 | `null` |
+
+> 搜索结果只带作者 `channel_account_id` + `channel_account_name`,**不含作者粉丝数/签名等档案**(这点与抖音不同)。要拿作者画像需二次请求 account_info(见三)。
+
+### ⑥ 提取与后处理规则
+- tag:`topic_list` 实测为 null,快手搜索阶段常无结构化 tag;若 `body_text` 有内容可正则 `#([^\s#]+)` 抽取,否则 tag 为空。
+- 时间:`publish_timestamp` 已是毫秒,直接用。
+- 视频可下载性结论(capture `kuaishou_video_dl.json`):`http_status=206`、`content_type=video/mp4`、`content_range=bytes 0-546454/546455`、`bytes_received=546455`、`looks_like_video=true` → **可下载**。
+- **下载头**:快手 CDN(`*.kwaicdn.com`)URL 自带 `pkey` / `tag` 签名,实测带 `Range: bytes=0-` 即可 206;建议补 `Referer: https://www.kuaishou.com/`。相比抖音对 UA 不敏感,但保留通用 UA 更稳。
+
+### ⑦ 边界与失败
+- 限流 ≥ 15s。
+- 空值约定:`title`/`body_text`/`topic_list` 常为 null,提取层需容忍。
+- 本次实测 `has_more=false`,单页即止;若后续版本返回 next_cursor 再实现翻页。
+
+### ⑧ 落点
+| 归一字段 | canonical 名 | 游走边 |
+|---|---|---|
+| `channel_content_id` | `platform_content_id` | search_page_to_content |
+| `channel_account_id` | `platform_author_id` | video_to_author |
+| `channel_account_name` | `author_display_name` | video_to_author |
+| `topic_list` | `tags` | video_to_hashtag |
+| `like_count`/`comment_count`/`share_count`/`collect_count` | `statistics.*` | — |
+| `has_more`/`next_cursor` | `has_more`/`next_cursor` | search_page_to_content |
+
+---
+
+## 二、内容详情 PLT_KUAISHOU_DETAIL
+
+### ① 身份
+- source_id:`PLT_KUAISHOU_DETAIL`
+- 接口名:快手内容详情 / kuai_shou detail
+- 用途:按 content_id 拉单条归一化详情(视频、互动数、BGM、作者)。
+- 状态:**verified**(capture `kuaishou_detail.json`,`code=0`)
+
+### ② 请求标准
+- method:`POST`
+- path:`/crawler/kuai_shou/detail`
+- 鉴权:无
+- 参数表:
+
+| 名 | 类型 | 必填 | 示例 |
+|---|---|---|---|
+| content_id | string | 是 | `3xepqgwddgbickc` |
+
+### ③ 请求示例
+```bash
+curl -X POST http://crawler.aiddit.com/crawler/kuai_shou/detail \
+  -H 'Content-Type: application/json' \
+  -d '{"content_id":"3xepqgwddgbickc"}'
+```
+
+### ④ 响应信封 + 翻页
+- 信封:`{ "code":0, "msg":null, "data":{ "has_more":false, "next_cursor":null, "data":{...} } }`
+- 详情无翻页:`has_more=false`、`next_cursor=null`。
+
+### ⑤ 字段台账(`data.data`,归一化名)
+
+| 字段名 | 类型 | 含义 | 提取标注 | 真实示例值 |
+|---|---|---|---|---|
+| `channel_content_id` | string | 内容 id | 直接可用 | `3xepqgwddgbickc` |
+| `content_link` | string | 内容链接 | 直接可用 | `https://www.gifshow.com/fw/photo/3xepqgwddgbickc` |
+| `content_type` | string | 内容类型 | 直接可用 | `video` |
+| `title` / `body_text` / `topic_list` | string / string[] | 标题/正文/话题(实测均 null) | 直接可用 | `null` |
+| `video_url_list[].video_url` | string | 视频地址 | 需后处理下载 | `http://v4.kwaicdn.com/ksc1/...b.mp4?pkey=...&clientCacheKey=3xepqgwddgbickc_b.mp4&tt=b...` |
+| `video_url_list[].video_duration` | int(秒) | 时长 | 直接可用 | `4` |
+| `image_url_list[].image_url` | string | 封面图 | 直接可用 | `http://hw2.a.kwimgs.com/upic/...540p_*.kvif?...` |
+| `channel_account_id` | string | 作者 id | 直接可用 | `3xfkwajatdh7p7i` |
+| `channel_account_name` | string | 作者昵称 | 直接可用 | `夏若.` |
+| `avatar` | string | 作者头像 | 直接可用 | `http://p4.a.yximgs.com/kimg/uhead/...:200x200.heif` |
+| `view_count` | int | 观看数 | 直接可用 | `18472` |
+| `like_count` | int | 点赞 | 直接可用 | `75` |
+| `collect_count` | int | 收藏 | 直接可用 | `4` |
+| `comment_count` | int | 评论 | 直接可用 | `0` |
+| `share_count` | int | 分享 | 直接可用 | `7` |
+| `bgm_data.title` / `bgm_data.author` / `bgm_data.play_url` | string | BGM | 直接可用 | `没去学校(DJ版)` / `kiss` / `https://v4-plat-fdl.wsukwai.com/ksc2/*.m4a?...` |
+| `publish_timestamp` | int(ms) | 发布时间戳 | 直接可用 | `1746919311784` |
+
+> 注:同一条内容 `share_count` 在 detail=`7`、在 search=`0`,以 detail 为准(search 该字段可能滞后)。
+
+### ⑥ 提取与后处理规则
+- tag:`topic_list` 实测 null;按需从 `body_text` 正则抽取。
+- 视频地址:`video_url_list[].video_url` 为 kwaicdn 直链,带签名参数,直接下载。
+- 时间:`publish_timestamp` 毫秒,直接用。
+- 视频可下载性:同搜索结论(`kuaishou_video_dl.json`:206 / video/mp4 / looks_like_video=true)。**下载带 `Range: bytes=0-` + `Referer: https://www.kuaishou.com/`**。
+
+### ⑦ 边界与失败
+- 限流 ≥ 15s。
+- 空值:`title`/`body_text`/`topic_list` 常 null。
+
+### ⑧ 落点
+| 归一字段 | canonical 名 | 游走边 |
+|---|---|---|
+| `channel_content_id` | `platform_content_id` | — |
+| `channel_account_id` | `platform_author_id` | video_to_author |
+| `channel_account_name` | `author_display_name` | video_to_author |
+| `topic_list` | `tags` | video_to_hashtag |
+| `like_count`/`comment_count`/`share_count`/`collect_count` | `statistics.*` | — |
+
+---
+
+## 三、账号信息 PLT_KUAISHOU_ACCOUNT_INFO
+
+### ① 身份
+- source_id:`PLT_KUAISHOU_ACCOUNT_INFO`
+- 接口名:快手账号信息 / kuai_shou account_info
+- 用途:按作者 id 拉作者档案(昵称、粉丝数、签名、标签、性别),补齐搜索/详情缺失的作者画像。
+- 状态:**verified**(capture `kuaishou_account_info.json`,`code=0`)
+
+### ② 请求标准
+- method:`POST`
+- path:`/crawler/kuai_shou/account_info`
+- 鉴权:无
+- 参数表:
+
+| 名 | 类型 | 必填 | 示例 |
+|---|---|---|---|
+| account_id | string | 是 | `3xfkwajatdh7p7i` |
+| is_cache | bool | 否 | `true` |
+
+### ③ 请求示例
+```bash
+curl -X POST http://crawler.aiddit.com/crawler/kuai_shou/account_info \
+  -H 'Content-Type: application/json' \
+  -d '{"account_id":"3xfkwajatdh7p7i","is_cache":true}'
+```
+
+### ④ 响应信封 + 翻页
+- 信封:`{ "code":0, "msg":null, "data":{ "has_more":false, "next_cursor":null, "data":{...} } }`
+- 无翻页:`has_more=false`、`next_cursor=null`。
+
+### ⑤ 字段台账(`data.data`)
+
+| 字段名 | 类型 | 含义 | 提取标注 | 真实示例值 |
+|---|---|---|---|---|
+| `channel_account_id` | string | 作者 id | 直接可用 | `3xfkwajatdh7p7i` |
+| `ks_id` / `digit_id` | string | 快手号 | 直接可用 | `1514225378` |
+| `account_link` | string | 主页链接 | 直接可用 | `https://www.kuaishou.com/profile/3xfkwajatdh7p7i` |
+| `account_name` | string | 作者昵称 | 直接可用 | `夏若.` |
+| `avatar_url` | string | 头像 | 直接可用 | `http://p4.a.yximgs.com/kimg/uhead/...:750x750.heif` |
+| `gender` | string | 性别 | 直接可用 | `女` |
+| `description` | string | 签名 | 直接可用 | `可以帮我破1000吗\n谢谢🙏...` |
+| `tags` | string[] | 账号标签(星座/地区) | 直接可用 | `["摩羯座","贵州 安顺市"]` |
+| `follower_count` | int | 粉丝数 | 直接可用 | `511` |
+| `publish_count` | int | 作品数 | 直接可用 | `184` |
+| `like_count` | int | 总获赞 | 直接可用 | `1598` |
+| `update_timestamp` | int(ms) | 抓取时间 | 直接可用 | `1781158922013` |
+
+### ⑥ 提取与后处理规则
+- 作者档案:把 `account_name`/`description`/`tags`/`follower_count` 合并进作者节点。
+- tag:`tags` 已结构化(星座+地区),直接用作账号级标签。
+- 空值:`ip_location`/`collect_count`/`create_timestamp` 实测 null。
+
+### ⑦ 边界与失败
+- 限流 ≥ 15s。
+- `account_id` 用 `channel_account_id`(如 `3xfkwajatdh7p7i`),非数字快手号。
+- 快手无独立的"作者作品列表"接口 capture;"作者→作品"游走在快手侧暂依赖搜索结果聚合(本批未抓到 kuaishou blogger 接口)。
+
+### ⑧ 落点
+| 字段 | canonical 名 | 游走边 |
+|---|---|---|
+| `channel_account_id` | `platform_author_id` | video_to_author |
+| `account_name` | `author_display_name` | video_to_author |
+| `tags` | `tags`(账号级) | — |
+| `follower_count`/`like_count` | `statistics.*`(账号聚合) | — |

+ 337 - 0
数据接口与来源/接口台账/抖音.md

@@ -0,0 +1,337 @@
+# 抖音 接口台账
+
+> 唯一证据来源:`/tmp/aiddit_captures/` 下真实抓包。host = `http://crawler.aiddit.com`。
+> 涉及 capture:`douyin_search.json`、`douyin_detail.json`、`douyin_blogger.json`、`douyin_profile_author.json`、`douyin_profile_content.json`、`douyin_video_dl.json`。
+> 鉴权:所有 `crawler.aiddit.com` 接口实测**无 Authorization 头**;仅需 base_url(env `CONTENTFIND_API_CRAWAPI_BASE_URL`)。
+> 限流约定:两次调用间隔 ≥ 15s。
+
+---
+
+## 一、关键词搜索 PLT_DOUYIN_KEYWORD
+
+### ① 身份
+- source_id:`PLT_DOUYIN_KEYWORD`
+- 接口名:抖音关键词搜索 / dou_yin keyword
+- 用途:按关键词拉一页内容卡片(视频),用于搜索召回与种子发现。
+- 状态:**verified**(capture `douyin_search.json`,`code=0`)
+
+### ② 请求标准
+- method:`POST`
+- path:`/crawler/dou_yin/keyword`
+- 鉴权:无 Authorization
+- 参数表:
+
+| 名 | 类型 | 必填 | 示例 |
+|---|---|---|---|
+| keyword | string | 是 | `彩虹` |
+| content_type | string | 是 | `视频` |
+| cursor | string | 是(首页传空串) | `""` |
+| sort_type | string | 是 | `最多点赞` |
+
+### ③ 请求示例
+```bash
+curl -X POST http://crawler.aiddit.com/crawler/dou_yin/keyword \
+  -H 'Content-Type: application/json' \
+  -d '{"keyword":"彩虹","content_type":"视频","cursor":"","sort_type":"最多点赞"}'
+```
+
+### ④ 响应信封 + 翻页
+- 信封:`{ "code":0, "msg":null, "data":{ ... } }`
+- `data.has_more`:`true`(还有下一页)
+- `data.next_cursor`:`"12"`(下一页把它原样填回请求 `cursor`)
+- `data.data`:数组,本页 `11` 条卡片(注意:**单条卡片是抖音原生 aweme 结构,字段名为 raw 名**,与 detail 接口的归一化结构不同)。
+
+### ⑤ 字段台账(单条卡片 = `data.data[i]`,raw 名)
+
+| 字段名 | 类型 | 含义 | 提取标注 | 真实示例值 |
+|---|---|---|---|---|
+| `aweme_id` | string | 内容 id | 直接可用 | `7522164415848893735` |
+| `desc` / `caption` | string | 标题/正文(含话题) | 直接可用 | `原来彩虹真的是圆形的,一定变得超级幸运!#治愈系风景 #彩虹 #旅行` |
+| `text_extra[].hashtag_name` | string[] | 话题 tag | 直接可用(或从 desc `#xxx` 正则抽) | `治愈系风景` / `彩虹` / `旅行` |
+| `cha_list[].cha_name` | string[] | 挑战/话题名(同 tag) | 直接可用 | `治愈系风景` |
+| `video.play_addr.url_list` | string[] | 播放地址(无水印,多 CDN 备选) | 需后处理下载 | `https://v11-wha.douyinvod.com/.../mime_type=video_mp4...`(首选)|
+| `video.download_addr.url_list` | string[] | 带水印下载地址 | 需后处理下载 | `https://v9-chc.douyinvod.com/.../main.mp4?...logo_type=aweme_search_suffix` |
+| `video.duration` | int(ms) | 时长(毫秒) | 直接可用 | `13282` |
+| `author.uid` | string | 作者数字 id | 直接可用 | `96721168101` |
+| `author.sec_uid` | string | 作者加密 id(**翻主页/粉丝画像必须用它**) | 直接可用 | `MS4wLjABAAAAZrIhB0ThEPqj37arlq_4Z6l3jW-E3koi0rGjtSb9jtA` |
+| `author.short_id` | string | 作者短 id | 直接可用 | `778897743` |
+| `author.unique_id` | string | 抖音号 | 直接可用 | `Ayuan3230` |
+| `author.nickname` | string | 作者昵称 | 直接可用 | `源Dream` |
+| `author.signature` | string | 作者签名 | 直接可用 | `川西 组团 旅拍μ:Ayuan3230 …` |
+| `author.follower_count` | int | 作者粉丝数 | 直接可用 | `166947` |
+| `author.gender` | int | 作者性别(0=未知) | 直接可用 | `0` |
+| `statistics.digg_count` | int | 点赞 | 直接可用 | `5034215` |
+| `statistics.comment_count` | int | 评论 | 直接可用 | `121615` |
+| `statistics.share_count` | int | 分享 | 直接可用 | `2679616` |
+| `statistics.collect_count` | int | 收藏 | 直接可用 | `232358` |
+| `create_time` | int(秒) | 发布时间戳 | 需后处理(×1000) | `1751515440` |
+| `share_url` | string | 分享短链 | 直接可用 | `https://www.iesdouyin.com/share/video/7522164415848893735/?...` |
+| `data.has_more` | bool | 是否有下一页 | 直接可用 | `true` |
+| `data.next_cursor` | string | 下一页游标 | 直接可用 | `"12"` |
+
+> **重点:搜索阶段即得完整作者档案** —— `author` 对象内已包含 `sec_uid` / 粉丝数 / 签名 / 抖音号,无需为拿基础作者信息再发请求。后续翻主页(blogger)、拉粉丝画像(account_fans_portrait)都直接复用 `author.sec_uid`。
+
+### ⑥ 提取与后处理规则
+- tag:优先用 `text_extra[].hashtag_name`(结构化);若缺失则对 `desc` 用正则 `#([^\s#]+)` 抽取。
+- 时间:`create_time` 为秒级,统一 ×1000 转毫秒。
+- 视频地址:`video.play_addr.url_list` 为无水印多 CDN,取第一个可用;`download_addr` 为带水印(URL 含 `logo_type=aweme_search_suffix`)。
+- 视频可下载性结论(capture `douyin_video_dl.json`,对应本卡片同一 play_addr):`http_status=206`、`content_type=video/mp4`、`content_range=bytes 0-1048575/2399605`、`bytes_received=1048576`(1MB 分片)、`looks_like_video=true` → **可下载**。
+- **下载必带头**:抖音视频 CDN 要带 **iOS UA + Referer** 才能 206,否则易 403:
+  - `User-Agent`:iOS 客户端 UA(如 `com.ss.iphone.ugc.Aweme/...` 或移动 Safari UA)
+  - `Referer: https://www.douyin.com/`
+  - 用 `Range: bytes=0-` 触发 206 分片。
+
+### ⑦ 边界与失败
+- 限流:两次调用间隔 ≥ 15s。
+- 空值约定:`video.download_addr` 可能缺失,回退 `play_addr`;`create_time` 缺失记为 null。
+- 翻页终止:`has_more=false` 或 `next_cursor=null` 时停止。
+
+### ⑧ 落点(canonical 名 + 游走边)
+| raw 字段 | canonical 名 | 游走边 |
+|---|---|---|
+| `aweme_id` | `platform_content_id` | search_page_to_content |
+| `author.sec_uid` | `platform_author_id` | video_to_author |
+| `author.nickname` | `author_display_name` | video_to_author |
+| `text_extra[].hashtag_name` | `tags` | video_to_hashtag |
+| `statistics.*` | `statistics.like/comment/share/collect` | — |
+| `has_more` / `next_cursor` | `has_more` / `next_cursor` | search_page_to_content |
+
+---
+
+## 二、内容详情 PLT_DOUYIN_DETAIL
+
+### ① 身份
+- source_id:`PLT_DOUYIN_DETAIL`
+- 接口名:抖音内容详情 / dou_yin detail
+- 用途:按 content_id 拉单条归一化详情(标题、多码率视频、互动数、BGM)。
+- 状态:**verified**(capture `douyin_detail.json`,`code=0`)
+
+### ② 请求标准
+- method:`POST`
+- path:`/crawler/dou_yin/detail`
+- 鉴权:无
+- 参数表:
+
+| 名 | 类型 | 必填 | 示例 |
+|---|---|---|---|
+| content_id | string | 是 | `7522164415848893735` |
+
+### ③ 请求示例
+```bash
+curl -X POST http://crawler.aiddit.com/crawler/dou_yin/detail \
+  -H 'Content-Type: application/json' \
+  -d '{"content_id":"7522164415848893735"}'
+```
+
+### ④ 响应信封 + 翻页
+- 信封:`{ "code":0, "msg":null, "data":{ "has_more":false, "next_cursor":null, "data":{...} } }`
+- 详情无翻页:`has_more=false`、`next_cursor=null`。
+- 内层 `data.data` 为**归一化结构**(字段名与搜索的 raw 结构不同)。
+
+### ⑤ 字段台账(`data.data`,归一化名)
+
+| 字段名 | 类型 | 含义 | 提取标注 | 真实示例值 |
+|---|---|---|---|---|
+| `channel_content_id` | string | 内容 id | 直接可用 | `7522164415848893735` |
+| `content_link` | string | 内容链接 | 直接可用 | `https://www.douyin.com/video/7522164415848893735` |
+| `title` | string | 标题 | 直接可用 | `原来彩虹真的是圆形的,一定变得超级幸运!...` |
+| `body_text` | string | 正文(含话题) | 直接可用 | `原来彩虹真的是圆形的,一定变得超级幸运!#治愈系风景 #彩虹 #旅行` |
+| `topic_list` | string[] | 话题 tag | 直接可用 | `["治愈系风景","彩虹","旅行"]` |
+| `content_type` | string | 内容类型 | 直接可用 | `video` |
+| `video_url_list[].video_url` | string | 视频地址(默认码率) | 需后处理下载 | `https://www.douyin.com/aweme/v1/play/?video_id=v0d00fg10000d1i1etvog65uanqirggg&ratio=1080p&line=0` |
+| `multi_bitrate.{540p,720p,1080p}.video_url` | string | 多码率视频地址 | 需后处理下载 | `.../ratio=540p&line=0` 等 |
+| `video_url_list[].video_duration` | int(秒) | 时长 | 直接可用 | `13` |
+| `image_url_list[].image_url` | string | 封面图 | 直接可用 | `https://p3-pc-sign.douyinpic.com/...tplv-dy-360p.jpeg?...` |
+| `channel_account_id` | string | 作者 id(= sec_uid) | 直接可用 | `MS4wLjABAAAAZrIhB0ThEPqj37arlq_4Z6l3jW-E3koi0rGjtSb9jtA` |
+| `channel_account_name` | string | 作者昵称 | 直接可用 | `源Dream` |
+| `like_count` | int | 点赞 | 直接可用 | `5034215` |
+| `comment_count` | int | 评论 | 直接可用 | `121615` |
+| `share_count` | int | 分享 | 直接可用 | `2679616` |
+| `collect_count` | int | 收藏 | 直接可用 | `232359` |
+| `bgm_data.title` / `bgm_data.author` / `bgm_data.play_url` | string | BGM 信息 | 直接可用 | `@源Dream创作的原声` / `源Dream` / `https://sf6-cdn-tos.douyinstatic.com/.../*.mp3` |
+| `publish_timestamp` | int(ms) | 发布时间戳(毫秒) | 直接可用 | `1751515440000` |
+| `is_original` | bool | 是否原创 | 直接可用 | `false` |
+
+### ⑥ 提取与后处理规则
+- tag:直接取 `topic_list`(已结构化)。
+- 视频地址:优先 `multi_bitrate.1080p.video_url`;`video_url_list[].video_url` 是 `douyin.com/aweme/v1/play` 跳转地址,实际下载会 302 到 `douyinvod.com` CDN。
+- 时间:`publish_timestamp` 已是毫秒,直接用。
+- 视频可下载性:同搜索接口结论(`douyin_video_dl.json`:206 / video/mp4 / looks_like_video=true)。**下载带 iOS UA + `Referer: https://www.douyin.com/` + `Range: bytes=0-`**。
+
+### ⑦ 边界与失败
+- 限流 ≥ 15s。
+- 归一化结构与搜索 raw 结构字段名不同,提取层需分别映射。
+- 空值:`view_count` / `play_count` 实测为 null,不可作为指标。
+
+### ⑧ 落点
+| raw/归一字段 | canonical 名 | 游走边 |
+|---|---|---|
+| `channel_content_id` | `platform_content_id` | — |
+| `channel_account_id` | `platform_author_id` | video_to_author |
+| `channel_account_name` | `author_display_name` | video_to_author |
+| `topic_list` | `tags` | video_to_hashtag |
+| `like_count`/`comment_count`/`share_count`/`collect_count` | `statistics.*` | — |
+
+---
+
+## 三、博主作品列表 PLT_DOUYIN_BLOGGER
+
+### ① 身份
+- source_id:`PLT_DOUYIN_BLOGGER`
+- 接口名:抖音博主主页作品 / dou_yin blogger
+- 用途:按作者 `sec_uid` 翻主页作品,实现"作者→作品"游走。
+- 状态:**verified**(capture `douyin_blogger.json`,`code=0`)
+
+### ② 请求标准
+- method:`POST`
+- path:`/crawler/dou_yin/blogger`
+- 鉴权:无
+- 参数表:
+
+| 名 | 类型 | 必填 | 示例 |
+|---|---|---|---|
+| account_id | string | 是(传 sec_uid) | `MS4wLjABAAAAZrIhB0ThEPqj37arlq_4Z6l3jW-E3koi0rGjtSb9jtA` |
+| cursor | string | 是(首页空串) | `""` |
+
+### ③ 请求示例
+```bash
+curl -X POST http://crawler.aiddit.com/crawler/dou_yin/blogger \
+  -H 'Content-Type: application/json' \
+  -d '{"account_id":"MS4wLjABAAAAZrIhB0ThEPqj37arlq_4Z6l3jW-E3koi0rGjtSb9jtA","cursor":""}'
+```
+
+### ④ 响应信封 + 翻页
+- 信封:`{ "code":0, "data":{ "has_more":..., "next_cursor":..., "data":[...] } }`
+- `has_more`:`true`
+- `next_cursor`:`"1776248100000"`(毫秒时间戳形式的游标,原样回填 `cursor`)
+- `data.data`:数组,本页 `22` 条作品。**单条结构与搜索卡片相同(raw aweme 结构:`aweme_id`/`author`/`statistics`/`video`/`text_extra`)**。
+
+### ⑤ 字段台账
+> 单条作品字段与"一、关键词搜索 ⑤"完全一致(raw 名:`aweme_id`、`desc`、`text_extra[].hashtag_name`、`video.play_addr.url_list`、`author.sec_uid`、`statistics.digg_count` 等),不再重复;翻页字段见下。
+
+| 字段名 | 类型 | 含义 | 提取标注 | 真实示例值 |
+|---|---|---|---|---|
+| `data.has_more` | bool | 是否有下一页 | 直接可用 | `true` |
+| `data.next_cursor` | string | 下一页游标(回填 cursor) | 直接可用 | `"1776248100000"` |
+| `data.data[].aweme_id` | string | 作品 id | 直接可用 | 同搜索结构 |
+
+### ⑥ 提取与后处理规则
+- 翻页:`next_cursor` 原样填回 `cursor`,直到 `has_more=false`。
+- 去重:作者作品需与已发现内容(搜索结果)按 `aweme_id` 去重(参考 commit `1cd1b94` 教训)。
+- 视频下载:同搜索/详情结论(206/mp4/可下载,带 iOS UA + Referer)。
+
+### ⑦ 边界与失败
+- 限流 ≥ 15s。
+- `account_id` 必须传 `sec_uid`(`MS4...`),传数字 uid 取不到。
+- 空页:`has_more=false` 停止。
+
+### ⑧ 落点
+| raw 字段 | canonical 名 | 游走边 |
+|---|---|---|
+| `account_id`(入参 sec_uid) | `platform_author_id` | author_to_works |
+| `data.data[].aweme_id` | `platform_content_id` | author_to_works |
+| `text_extra[].hashtag_name` | `tags` | video_to_hashtag |
+| `has_more`/`next_cursor` | `has_more`/`next_cursor` | author_to_works |
+
+---
+
+## 四、账号粉丝画像 PLT_DOUYIN_AUTHOR_PROFILE
+
+### ① 身份
+- source_id:`PLT_DOUYIN_AUTHOR_PROFILE`
+- 接口名:抖音账号粉丝画像 / dou_yin re_dian_bao account_fans_portrait
+- 用途:拉作者账号的人群画像(性别/年龄/省份/城市等级/手机品牌等 50+ 信号)+ 账号自身指标 + 作品分位。
+- 状态:**verified**(capture `douyin_profile_author.json`,`code=0`,内含 6 类人群分布信号)
+
+### ② 请求标准
+- method:`POST`
+- path:`/crawler/dou_yin/re_dian_bao/account_fans_portrait`
+- 鉴权:无
+- 参数表:
+
+| 名 | 类型 | 必填 | 示例 |
+|---|---|---|---|
+| account_id | string | 是(传 sec_uid) | `MS4wLjABAAAAZrIhB0ThEPqj37arlq_4Z6l3jW-E3koi0rGjtSb9jtA` |
+| need_age | bool | 是 | `true` |
+| need_gender | bool | 是 | `true` |
+| need_province | bool | 是 | `true` |
+
+### ③ 请求示例
+```bash
+curl -X POST http://crawler.aiddit.com/crawler/dou_yin/re_dian_bao/account_fans_portrait \
+  -H 'Content-Type: application/json' \
+  -d '{"account_id":"MS4wLjABAAAAZrIhB0ThEPqj37arlq_4Z6l3jW-E3koi0rGjtSb9jtA","need_age":true,"need_gender":true,"need_province":true}'
+```
+
+### ④ 响应信封 + 翻页
+- 信封:`{ "code":0, "msg":null, "data":{ "has_more":false, "next_cursor":null, "data":{...} } }`
+- 无翻页:`has_more=false`、`next_cursor=null`。
+- 内层 `data.data` 三块:`account`(账号信息)、`fans`(粉丝画像 6 维)、`posts`(作品指标分位)。
+
+### ⑤ 字段台账(`data.data`)
+
+| 字段名 | 类型 | 含义 | 提取标注 | 真实示例值 |
+|---|---|---|---|---|
+| `account.user_id` | string | 账号 id(=sec_uid) | 直接可用 | `MS4wLjABAAAAZrIhB0ThEPqj37arlq_4Z6l3jW-E3koi0rGjtSb9jtA` |
+| `account.nickname` | string | 昵称 | 直接可用 | `源Dream` |
+| `account.uniqueId` | string | 抖音号 | 直接可用 | `Ayuan3230` |
+| `account.follower_count` | int | 粉丝数 | 直接可用 | `166947` |
+| `account.aweme_count` | int | 作品数 | 直接可用 | `1101` |
+| `account.total_favorited` | int | 总获赞 | 直接可用 | `17754802` |
+| `account.first_tag_name` / `second_tag_name` | string | 一/二级行业标签 | 直接可用 | `旅行` / `旅行记录与分享` |
+| `account.fans_milestone.first_10w_fans_date` | string | 涨粉里程碑 | 直接可用 | `20250702` |
+| `fans.gender.data.{male,female}.percentage` | string | 粉丝性别占比 | 需后处理(去 `%`) | male `71.30%` / female `28.70%` |
+| `fans.age.data.{区间}.percentage` | string | 粉丝年龄分布 | 需后处理 | `24-30` → `26.88%` |
+| `fans.province.data.{省}.percentage` | string | 粉丝省份分布(34 项) | 需后处理 | `广东` → `12.62%` |
+| `fans.city_level.data.{级}.percentage` | string | 城市等级分布 | 需后处理 | `新一线` → `22.99%` |
+| `fans.phone_brand.data.{品牌}.percentage` | string | 手机品牌分布 | 需后处理 | `苹果` → `39.62%` |
+| `fans.*.data.{key}.preference` | string | 该项 TGI 偏好值 | 需后处理(float) | `苹果` preference `129.22` |
+| `posts.avg_like_count` | float | 平均点赞 | 直接可用 | `437.6` |
+| `posts.avg_comment_count` | float | 平均评论 | 直接可用 | `8.5667` |
+| `posts.percentile_like_count` | int | 点赞分位 | 直接可用 | `470` |
+| `posts.percentile_follower_count` | int | 粉丝分位 | 直接可用 | `13` |
+
+> 6 维粉丝信号:`gender`、`age`、`province`、`city`、`city_level`、`phone_brand`(均为 `{name, data:{key:{percentage, preference}}}` 结构,展开即 50+ 信号点)。
+
+### ⑥ 提取与后处理规则
+- 百分比:`percentage` 是带 `%` 的字符串,需 strip `%` 转 float。
+- `preference` 为 TGI(>100 表示该人群偏好高于大盘),float 解析。
+- 入参 `account_id` 必须 sec_uid。
+
+### ⑦ 边界与失败
+- 限流 ≥ 15s。
+- 注意区分:**本接口(account_fans_portrait)成功**;**内容画像 video_like_portrait 实测失败(见下)**。
+
+### ⑧ 落点
+| 字段 | canonical 名 | 游走边 |
+|---|---|---|
+| `account.user_id` | `platform_author_id` | video_to_author |
+| `account.nickname` | `author_display_name` | — |
+| `account.first_tag_name`/`second_tag_name` | `tags`(账号级) | — |
+| `posts.avg_like_count` 等 | `statistics.*`(账号聚合) | — |
+
+---
+
+## 五、内容画像 video_like_portrait —— BLOCKED
+
+### ① 身份
+- source_id:`PLT_DOUYIN_CONTENT_PORTRAIT`
+- 接口名:抖音内容(视频)人群画像 / dou_yin re_dian_bao video_like_portrait
+- 用途:本应拉单条内容的点赞人群画像。
+- 状态:**blocked** —— 原因:实测 **HTTP 404 Not Found**(capture `douyin_profile_content.json`,`http_error=404`,`error_body=<html><title>404: Not Found</title>...`)。
+
+### ② 请求标准(实测路径)
+- method:`POST`
+- path:`/crawler/dou_yin/re_dian_bao/video_like_portrait`
+- 入参:`{ "content_id":"7522164415848893735", "need_age":true, "need_gender":true, "need_province":true }`
+
+### ③ 请求示例
+```bash
+curl -X POST http://crawler.aiddit.com/crawler/dou_yin/re_dian_bao/video_like_portrait \
+  -H 'Content-Type: application/json' \
+  -d '{"content_id":"7522164415848893735","need_age":true,"need_gender":true,"need_province":true}'
+# 实测返回 HTTP 404
+```
+
+### ④–⑧
+- 该路径当前在 crawler.aiddit.com 上不存在(404),内容级人群画像**不可用**。需上游确认正确 path 或下线该能力;在 registry 中标 `blocked`,游走层不要挂该边。

+ 63 - 0
数据接口与来源/接口台账/知乎.md

@@ -0,0 +1,63 @@
+# 知乎(zhi_hu)接口台账
+
+> 唯一证据来源:`/tmp/aiddit_captures/zhihu_search.json`、`zhihu_search_retry.json`(2026-06-11 真实抓包)。
+> 全部接口走统一爬虫网关 `host = http://crawler.aiddit.com`,平台名 `zhi_hu`。
+
+## 平台级结论(先读)
+
+- **整平台 blocked**:知乎关键词搜索两次请求(含变参重试)**均返回 `code=10000 / msg="未知错误" / data=null`**(`zhihu_search.json`、`zhihu_search_retry.json`)。
+- 因 search 即失败,**detail / blogger / account_info / 视频下载 全部无法触达,无任何真实样本**,本批 capture 仅有 search 一条且失败。
+- 知乎平台 **当前不可用**,下游游走(内容、作者、tag、下载)全部阻断。
+
+---
+
+## 接口 1:关键词搜索(唯一接口,失败)
+
+### ① 身份
+- `source_id`: **PLT_ZHIHU_KEYWORD**
+- 状态:**blocked**(`zhihu_search.json` + `zhihu_search_retry.json` 两次 `code=10000`)
+
+### ② 请求标准
+- method:`POST`,path:`/crawler/zhi_hu/keyword`
+- 参数表(依两次请求体):
+
+| 参数 | 类型 | 必填 | 含义 | 真实值 |
+|---|---|---|---|---|
+| `keyword` | string | 是 | 搜索词 | `"彩虹"` |
+| `cursor` | string | 否 | 翻页游标(重试时尝试) | `""` |
+| `content_type` | string | 否 | 内容类型(重试时尝试) | `"综合"` |
+
+### ③ 真实 curl
+```bash
+# 第一次(最小参数)
+curl -X POST 'http://crawler.aiddit.com/crawler/zhi_hu/keyword' \
+  -H 'Content-Type: application/json' \
+  -d '{"keyword":"彩虹"}'
+
+# 第二次(变参重试,仍失败)
+curl -X POST 'http://crawler.aiddit.com/crawler/zhi_hu/keyword' \
+  -H 'Content-Type: application/json' \
+  -d '{"keyword":"彩虹","cursor":"","content_type":"综合"}'
+```
+
+### ④ 响应信封 + 翻页
+```json
+{ "code": 10000, "msg": "未知错误", "data": null }
+```
+- 两次请求响应一致:`code=10000`、`msg="未知错误"`、`data=null`。
+- **无 `has_more`/`next_cursor`**(data 为 null),翻页不可得。
+
+### ⑤ 字段台账
+- **无字段可登记**:`data=null`,未取得任何内容/标题/视频地址/作者/tag/互动数/翻页字段。
+
+### ⑥ 提取与后处理规则
+- 不适用(无数据返回)。
+
+### ⑦ 边界与失败
+- **失败实证**:`zhihu_search.json` `code=10000 / "未知错误"`;变参重试 `zhihu_search_retry.json` 同样 `code=10000 / "未知错误"`。两次重试均失败 → 判定**知乎整平台 blocked**。
+- 限流 ≥ 15s(与其余平台一致,但本平台已 blocked,限流不再是瓶颈)。
+- 后续若上游修复,需重新抓包验证 search 是否回到 `code=0`,再补 detail/作者/下载链路。
+
+### ⑧ 落点(canonical + 游走边)
+- canonical:无(无数据)。
+- 游走边:`search_page_to_content`、`video_to_author`、`author_to_works`、`video_to_hashtag` **全部阻断**,知乎暂不接入游走。

+ 194 - 0
数据接口与来源/接口台账/视频号.md

@@ -0,0 +1,194 @@
+# 接口台账 · 视频号(shi_pin_hao)
+
+> 唯一证据来源:`/tmp/aiddit_captures/` 下真实抓包。host=`http://crawler.aiddit.com`。
+> 整体状态:**部分可用(搜索抖动 + 作者接口失败,但视频可下载)**。
+> - 搜索:首次 `code=25011` 失败,重试 `code=0` 成功 → 服务端不稳定,需重试。
+> - 作者 blogger:`code=25011` blocked;account_info:`code=10001` blocked。
+> - 视频下载:`200 / video/mp4` 可下载 ✅。
+> 鉴权:抓包请求体无显式 token 字段,统一走 crawler.aiddit.com 网关。
+
+---
+
+## 1. 关键词搜索(PLT_SHIPINHAO_KEYWORD)
+
+### ① 身份
+- source_id:`PLT_SHIPINHAO_KEYWORD`
+- 接口名:视频号关键词搜索
+- 用途:按关键词检索视频号内容(搜索页 → 内容)
+- 状态:**verified(不稳定)** —— 首次 `code=25011` 失败,重试 `code=0` 成功有数据。证据:`sph_search.json`(失败)+ `sph_search_retry.json`(成功)。
+
+### ② 请求标准
+- method:`POST`
+- path:`/crawler/shi_pin_hao/keyword`
+- 鉴权:无显式 token(走网关)
+- 参数表:
+
+| 名 | 类型 | 必填 | 示例 |
+|---|---|---|---|
+| keyword | string | 是 | `"彩虹"` |
+| cursor | string | 否 | `""`(首页传空) |
+
+### ③ 请求示例(真实 request_body)
+```bash
+curl -X POST 'http://crawler.aiddit.com/crawler/shi_pin_hao/keyword' \
+  -H 'Content-Type: application/json' \
+  -d '{"keyword":"彩虹","cursor":""}'
+```
+
+### ④ 响应信封 + 翻页
+- 信封:`{code, msg, data}`
+- 成功(retry):`code=0`,`msg=null`,`data` 为 `{has_more, next_cursor, data:[...]}`
+- 失败(首次):`code=25011`,`msg="视频号接口异常: 获取搜索结果失败"`,`data=null`
+- 翻页真实取值:`has_more=true`,`next_cursor=12`(数字型游标,翻下一页时回填到 `cursor`)
+
+### ⑤ 字段台账(raw 名)
+> 列表项位于 `data.data[]`,每项为内容对象。
+
+| 字段名 | 类型 | 含义 | 提取标注 | 真实示例值 |
+|---|---|---|---|---|
+| channel_content_id | string | 内容ID | 直接可用 | `finderobjv03rf47ax8UTAiVchU7Uo2uexnucqpQD/XO8kw7opFqUs=` |
+| title | string | 标题(含话题串) | 直接可用 / tag需正则抽 | `"…网友拍到圆形彩虹… #彩虹#祝你好运连连…"` |
+| content_type | string | 内容类型 | 直接可用 | `video` |
+| content_link | string | 内容链接(export 编码) | 直接可用 | `export/UzFfBgAAxJqjXGR8HB7MjMzT4DCK…` |
+| video_url_list[].video_url | string | 视频地址(findermp) | 需后处理下载 | `https://findermp.video.qq.com/251/20302/stodownload?encfilekey=…` |
+| video_url_list[].video_duration | int | 视频时长(秒) | 直接可用 | `8` |
+| image_url_list[].image_url | string | 封面图地址 | 直接可用 | `https://findermp.video.qq.com/251/20304/stodownload?…` |
+| channel_account_id | string | 作者ID | 直接可用 | `28ee8b6605e2288793f5386abaef5769` |
+| channel_account_name | string | 作者昵称 | 直接可用 | `掌上巴彦淖尔` |
+| channel_account_avatar | string | 作者头像 | 直接可用 | `https://wx.qlogo.cn/finderhead/ver_1/…/132` |
+| like_count | int | 点赞数 | 直接可用 | `92` / `5513` |
+| collect_count | int/null | 收藏数 | 直接可用(常为null) | `null` |
+| comment_count | int/null | 评论数 | 直接可用(常为null) | `null` |
+| share_count | int/null | 分享数 | 直接可用(常为null) | `null` |
+| topic_list | array/null | 话题列表 | 需正则抽(列表常null,需从title解析) | `null`(标题内 `#彩虹` 需正则) |
+| publish_timestamp | long | 发布时间(ms) | 需后处理(/1000) | `1780904037000` |
+| has_more | bool | 是否有下一页 | 直接可用 | `true` |
+| next_cursor | int | 下一页游标 | 直接可用 | `12` |
+
+### ⑥ 提取与后处理规则
+- **话题/tag**:`topic_list` 在搜索结果里基本为 `null`,tag 需从 `title` 用正则抽取(形如 `#彩虹`、`#见者好运`,以空格或 `#` 分隔)。
+- **视频下载**:`video_url_list[].video_url` 为 findermp.video.qq.com 直链;实测(`sph_video_dl.json`)`http_status=200`、`content_type=video/mp4`、`content_range=bytes 0-784921/784922`、约 **784KB 可下载**。下载时需带 **Referer `https://channels.weixin.qq.com/`**。
+- 时间戳为毫秒,落库前 `/1000`。
+
+### ⑦ 边界与失败
+- **搜索不稳定(需重试)**:同一请求首次返回 `code=25011: 视频号接口异常: 获取搜索结果失败`(`sph_search.json`),重试返回 `code=0` 并带数据(`sph_search_retry.json`)。**实现必须带重试**(建议指数退避,≥15s 限流间隔)。
+- 限流:平台请求间隔 ≥15s。
+
+### ⑧ 落点
+- canonical:`platform_content_id`(←channel_content_id)、`title`、`video_url`(←video_url_list[0].video_url)、`platform_author_id`(←channel_account_id)、`author_name`(←channel_account_name)、`tags`(从title正则)、`like_count`、`publish_time`。
+- 游走边:`search_page_to_content`(搜索→内容)、`video_to_author`(内容→作者,channel_account_id)、`video_to_hashtag`(title 抽 tag)。
+
+---
+
+## 2. 视频下载(PLT_SHIPINHAO_VIDEO_DL)
+
+### ① 身份
+- source_id:`PLT_SHIPINHAO_VIDEO_DL`
+- 接口名:视频号视频直链下载
+- 用途:下载搜索/详情返回的 `video_url`
+- 状态:**verified** ✅。证据:`sph_video_dl.json`。
+
+### ② 请求标准
+- method:`GET`(直链)
+- path:findermp.video.qq.com 直链(非 crawler 网关),来自 `video_url_list[].video_url`
+- 鉴权:URL 自带 `encfilekey`/`token`;需 Header `Referer: https://channels.weixin.qq.com/`
+
+### ③ 请求示例
+```bash
+curl -L 'https://findermp.video.qq.com/251/20302/stodownload?encfilekey=Cvvj5Ix3eew…&token=ic1n0xDG6aw9Kicy8QAXnibeBK0' \
+  -H 'Referer: https://channels.weixin.qq.com/' \
+  -o sph_video.mp4
+```
+
+### ④ 响应信封
+- 非 JSON,二进制流。`http_status=200`,`content_type=video/mp4`,`content_range=bytes 0-784921/784922`,`bytes_received=784922`,`looks_like_video=true`。
+
+### ⑤ 字段台账
+| 字段名 | 类型 | 含义 | 提取标注 | 真实示例值 |
+|---|---|---|---|---|
+| (binary) | bytes | mp4 视频流 | 需后处理下载 | 784922 bytes |
+| content_type | header | 内容类型 | 直接可用 | `video/mp4` |
+
+### ⑥ 提取与后处理
+- 直接落地为 `.mp4` 文件;约 784KB(本样本)。后续可送多模态分析。
+
+### ⑦ 边界与失败
+- token/encfilekey 有时效,需在搜索后尽快下载。缺 Referer 可能被拒。
+
+### ⑧ 落点
+- 物料落点:`video_local_path` / `video_url`;不新增游走边(从属于内容)。
+
+---
+
+## 3. 作者主页 blogger(PLT_SHIPINHAO_BLOGGER)
+
+### ① 身份
+- source_id:`PLT_SHIPINHAO_BLOGGER`
+- 接口名:视频号博主作品列表
+- 用途:作者 → 作品(author_to_works)
+- 状态:**blocked(code=25011)**。证据:`sph_blogger.json`。
+
+### ② 请求标准
+- method:`POST` · path:`/crawler/shi_pin_hao/blogger`
+
+| 名 | 类型 | 必填 | 示例 |
+|---|---|---|---|
+| account_id | string | 是 | `28ee8b6605e2288793f5386abaef5769` |
+| is_cache | bool | 否 | `false` |
+
+### ③ 请求示例
+```bash
+curl -X POST 'http://crawler.aiddit.com/crawler/shi_pin_hao/blogger' \
+  -H 'Content-Type: application/json' \
+  -d '{"account_id":"28ee8b6605e2288793f5386abaef5769","is_cache":false}'
+```
+
+### ④ 响应信封
+- `code=25011`,`msg="视频号接口异常"`,`data=null` → **失败**。
+
+### ⑤ 字段台账
+- 无数据(blocked),字段未知。
+
+### ⑥/⑦ 边界与失败
+- blocked:作者作品接口当前不可用(25011),与搜索同源抖动。可考虑用搜索结果的 `channel_account_id` 暂时无法展开作品列表。
+
+### ⑧ 落点
+- 期望游走边 `author_to_works`,**当前不可用**。
+
+---
+
+## 4. 作者信息 account_info(PLT_SHIPINHAO_ACCOUNT_INFO)
+
+### ① 身份
+- source_id:`PLT_SHIPINHAO_ACCOUNT_INFO`
+- 接口名:视频号账号信息
+- 用途:作者画像补全
+- 状态:**blocked(code=10001 参数异常)**。证据:`sph_account_info.json`。
+
+### ② 请求标准
+- method:`POST` · path:`/crawler/shi_pin_hao/account_info`
+
+| 名 | 类型 | 必填 | 示例 |
+|---|---|---|---|
+| account_id | string | (实测被拒) | `28ee8b6605e2288793f5386abaef5769` |
+| is_cache | bool | 否 | `false` |
+| app_id 或 account_name | string | **至少一个**(据错误提示) | —(本次未传) |
+
+### ③ 请求示例
+```bash
+curl -X POST 'http://crawler.aiddit.com/crawler/shi_pin_hao/account_info' \
+  -H 'Content-Type: application/json' \
+  -d '{"account_id":"28ee8b6605e2288793f5386abaef5769","is_cache":false}'
+```
+
+### ④ 响应信封
+- `code=10001`,`msg="参数异常: app_id或account_name至少需要一个"`,`data=null` → **失败**。
+
+### ⑤ 字段台账
+- 无数据(blocked)。
+
+### ⑥/⑦ 边界与失败
+- blocked:本次只传了 `account_id`,网关要求 `app_id` 或 `account_name` 至少其一。后续若拿到 `account_name`(搜索结果有 `channel_account_name`)可再试。
+
+### ⑧ 落点
+- 期望补全 `platform_author_id` 画像,**当前参数不满足,blocked**。

+ 80 - 0
数据接口与来源/游走图谱.md

@@ -0,0 +1,80 @@
+# 游走图谱(人读说明)
+
+> 机读件:`walk_graph.json`(schema v2)。命名全部复用 `product_documents/抖音游走策略/douyin_walk_strategy.v1.json`(8 节点 + 10 边),**零新造**。
+> 证据:2026-06-11 多平台实测抓包 + `接口台账/*.md`。
+
+## 〇、配置四件套(v2 起,机读配置面闭环)
+
+游走的全部配置拆为四件,各管一层,代码只留一个通用 loop:
+
+| 文件 | 管什么 | 平台相关? |
+|---|---|---|
+| `walk_graph.json` | **拓扑**:10 条边的语义、navigate/reseed、jump_key(canonical)、血缘锚点 | 否(全局唯一) |
+| `platform_profiles/<platform>.json` ×10 | **平台执行**:支持哪些边、真实 endpoint、jump_key 的 raw 字段来源、提取覆写、运行参数(限流 15s/重试/下载头) | 是(每平台一份) |
+| `walk_policy.json` | **护栏 + 通行证**:预算/深度/去重/回灌配额(锚定 v1 真值,V3 待拍板项标 `TBD_V3`)+ `edge_permissions`(判定结果→哪些边放行,取代 `_can_expand_from_decision` 硬编码与原 path_stop/budget 包语义) | 否 |
+| `跨平台字段映射.json` | **归一化**:平台 raw 字段 → canonical 字段 | 是(一张总表) |
+
+运行时语义:loop 出队一个节点 → 查 `walk_graph` 该节点有哪些出边 → 查该平台 `profile` 此边是否 supported(unsupported/blocked 静默跳过,**边不可用不是错误,是该平台地图少一条路**)→ 查 `walk_policy` 预算/通行证放不放行 → 执行,响应按 `字段映射` 归一化。**新平台接入 = 实测一轮接口 + 写一份 profile,零代码改动。**
+
+## 一、一句话模型:单一有界 loop + 异构 frontier
+
+整个游走是**一个有界循环**,不是多条独立管线。一个**统一队列(frontier)**里同时排着三类异构节点 —— `query`(待搜)、`video`(待判/待扩)、`author`(待拉作品),按优先级轮转出队。每出队一个节点,按其类型尝试可走的边,产出的新节点(新 query / 新 video / 新 author / hashtag)再入同一队列。预算/深度耗尽即收敛停止。
+
+8 类节点(id_field):
+`pattern_seed`(policy_run_id)→ `query`(search_query_id)→ `search_page`(search_page_id)→ `video`(platform_content_id)→ `author`(platform_author_id)→ `author_works_page`(author_works_page_id);旁路 `hashtag`(hashtag);终点 `asset`(asset_id)。
+
+## 二、两类边
+
+### 导航边(navigate)= ID 跳转
+拿上一跳的某个 ID/游标,填进下一个请求参数,直接到下一个节点。8 条:
+
+| edge_id | from → to | jump_key(from_field → param) | 翻页 | endpoint |
+|---|---|---|---|---|
+| `query_next_page` | query → search_page | `next_cursor` → `cursor` | 是 | `/crawler/{platform}/keyword` |
+| `search_page_to_content` | search_page → video | `data.data[]` 拆条 | 否 | (同搜索响应) |
+| `video_to_author` | video → author | `platform_author_id` → `account_id` | 否 | — |
+| `author_to_works` | author → author_works_page | `platform_author_id` → `account_id` | 是 | `/crawler/{platform}/blogger` |
+| `author_work_to_content` | author_works_page → video | `data.data[]` 拆条 | 否 | (同 blogger 响应) |
+| `decision_to_asset` | video → asset | `platform_content_id` | 否 | — |
+| `path_stop` | video → video | `content_effect_status` | 否 | — |
+| `budget_downgrade` | video → video | `budget.remaining_actions` | 否 | — |
+
+### 回灌边(reseed)= 文本 → 新 keyword,gate=keep_only
+不靠 ID,靠从内容里**抽文本**生成新种子,且**只对 KEEP(强相关)内容开**:
+
+| edge_id | from → to | 抽取规则 | gate |
+|---|---|---|---|
+| `video_to_hashtag` | video → hashtag | 从 `tags` 抽:结构化(text_extra/topic_list/cha_list/B站 tag split)优先,缺则标题/desc/body_text 正则 `#([^\s#]+)` | keep_only |
+| `hashtag_to_query` | hashtag → query | 用 hashtag 文本生成新 `query`(param=`keyword`),归一化 keyword 去重,不污染 P2 初始 item query | keep_only |
+
+### 采集通吃:回灌不挑来源
+`author_work_to_content` 产出的**也是 `video` 节点**,因此它会**再触发 `video_to_hashtag` 回灌**。也就是说:搜索结果的视频、作者作品的视频,它们的标题与 tag **都能回灌**成新 hashtag → 新 query。回灌对内容来源一视同仁(标题/tag/作者作品的标题与 tag 通吃),只受 `keep_only` 与全局护栏约束。
+
+## 三、全局护栏(单一有界 loop 的边界)
+
+- **单队列**:query / video / author 同进一个 frontier,异构排队、统一调度,不分叉成多管线。
+- **全局预算 + 深度**:`max_total_actions` / `max_depth` / `max_pages` / `max_tag_hops`(见策略 `walk_budget_policy`);耗尽走 `budget_downgrade` 降档或停边。
+- **去重**:query 按**归一化 keyword + 近期 run** 去重(`normalize_exact_and_recent_run`);内容按**已访问 `platform_content_id`** 去重(作者作品须与已发现搜索内容去重,见 commit 1cd1b94)。
+- **回灌仅 KEEP**:`video_to_hashtag` / `hashtag_to_query` 都是 `keep_only` —— 只有判定强相关的内容/tag 才扩散,弱相关/blocked 内容走 `path_stop` 收口。
+- **血缘**:每跳记 `source_path_type`,对齐三类锚点:`pattern_to_search_query`(query_next_page / hashtag_to_query)、`search_query_to_content`(search_page_to_content / author_work_to_content)、`decision_to_asset`(decision_to_asset);其余导航边记 `null`。
+
+## 四、各平台对各边的支持度(实测)
+
+| edge_id | 抖音 | 快手 | 视频号 | 小红书 | B站 | 公众号 | youtube | github |
+|---|---|---|---|---|---|---|---|---|
+| query_next_page | ✅ | 弱(单页) | ✅(需重试) | ✅ | ✅ | ✅ | ✅(长token) | ✅ |
+| search_page_to_content | ✅ | ✅ | ✅(抖动) | ✅(note_card) | ✅ | ✅ | ✅ | ✅(repo) |
+| video_to_author | ✅ | ✅ | ✅ | ✅ | ✅(仅mid标识) | ✅(仅biz/hash) | ✅ | ✅(→owner) |
+| **author_to_works** | ✅(blogger) | ❌无接口 | ⛔blocked25011 | ⛔blocked超时 | ❌无接口 | ❌无接口 | ❌无接口 | ❌ |
+| author_work_to_content | ✅ | ❌ | ⛔ | ⛔ | ❌ | ❌ | ❌ | ❌ |
+| video_to_hashtag | ✅ | 弱(常null) | ✅(title正则) | ✅ | ✅(tag split) | ❌无tag | ✅(仅detail正则) | ✅(topics常空) |
+| hashtag_to_query | ✅ | ✅ | ✅ | ✅ | ✅ | n/a | ✅ | ✅ |
+| decision_to_asset | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
+| path_stop / budget_downgrade | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
+
+> **头条、知乎**:整平台 blocked(`code=10000`/`data=null`),所有边阻断,不接入游走。
+
+### 关键结论
+- **作者作品(`author_to_works`)只有抖音真正可走**(blogger 接口 `code=0`)。快手/B站/公众号/youtube **无独立作者作品接口**;视频号(`code=25011`)、小红书(超时)**接口存在但 blocked**。其余平台的"作者"维度只能落作者标识(`platform_author_id`),无法展开作品列表。
+- **公众号无 hashtag 回灌**(`topic_list` 恒 null),`video_to_hashtag` / `hashtag_to_query` 在公众号不可走。
+- 抖音是唯一**全 10 边可走**的平台,是游走能力的完整参照系。

+ 235 - 0
数据接口与来源/跨平台字段映射.json

@@ -0,0 +1,235 @@
+{
+  "schema_version": "cross_platform_field_map.v1",
+  "title": "跨平台字段映射 canonical → raw 路径",
+  "generated_at": "2026-06-11",
+  "evidence": "/tmp/aiddit_captures/*.json 真实抓包 + tech_documents/数据接口与来源/接口台账/*.md(⑤字段台账)",
+  "canonical_source_of_truth": "content_agent/integrations/douyin.py 归一化 _normalize_content_item",
+  "notes": [
+    "单元格 = 该平台真实 raw 字段路径;拿不准/无数据标 '—'。",
+    "抖音有两套:search=raw 原生 aweme 结构 / detail=归一化结构(channel_*),分两列。",
+    "快手/视频号/B站detail/小红书detail/公众号/youtube 的 detail 多为归一化结构(channel_*)。",
+    "小红书搜索内容字段全部嵌在 note_card 下(item.note_card.*)。",
+    "公众号作者标识只能从 url 正则抽 __biz;detail/account_info 另给网关 hash channel_account_id。",
+    "时间戳单位不一致:抖音search/小红书search/B站search/公众号/视频号=秒;抖音detail/快手/小红书detail/B站detail/youtube=毫秒。",
+    "头条、知乎整平台 blocked(code=10000/null),无字段,不在列内。"
+  ],
+  "platforms": [
+    "抖音搜索(raw)",
+    "抖音详情(归一化)",
+    "快手",
+    "视频号",
+    "小红书(note_card)",
+    "小红书详情(扁平)",
+    "B站搜索(raw)",
+    "B站详情(归一化)",
+    "公众号",
+    "youtube搜索",
+    "youtube详情"
+  ],
+  "mappings": {
+    "platform_content_id": {
+      "抖音搜索(raw)": "aweme_id",
+      "抖音详情(归一化)": "channel_content_id",
+      "快手": "channel_content_id",
+      "视频号": "channel_content_id",
+      "小红书(note_card)": "item.id",
+      "小红书详情(扁平)": "channel_content_id",
+      "B站搜索(raw)": "bvid",
+      "B站详情(归一化)": "channel_content_id",
+      "公众号": "url 正则抽 __biz+mid+idx (search) / channel_content_id (detail)",
+      "youtube搜索": "video_id",
+      "youtube详情": "channel_content_id"
+    },
+    "platform_content_format": {
+      "抖音搜索(raw)": "派生(content_type=视频→video)",
+      "抖音详情(归一化)": "content_type",
+      "快手": "content_type",
+      "视频号": "content_type",
+      "小红书(note_card)": "item.note_card.type",
+      "小红书详情(扁平)": "content_type",
+      "B站搜索(raw)": "派生(均 video)",
+      "B站详情(归一化)": "content_type",
+      "公众号": "content_type (=note,图文)",
+      "youtube搜索": "派生(均 video)",
+      "youtube详情": "content_type"
+    },
+    "description": {
+      "抖音搜索(raw)": "desc / caption",
+      "抖音详情(归一化)": "body_text (标题=title)",
+      "快手": "body_text (常 null)",
+      "视频号": "title (含话题串,无独立正文)",
+      "小红书(note_card)": "item.note_card.desc (标题=item.note_card.display_title)",
+      "小红书详情(扁平)": "body_text (标题=title)",
+      "B站搜索(raw)": "description / desc (标题=title,含<em>高亮需剥)",
+      "B站详情(归一化)": "body_text (标题=title)",
+      "公众号": "body_text (detail;search 仅 title 含<em>高亮)",
+      "youtube搜索": "description_snippet (标题=title)",
+      "youtube详情": "body_text (标题=title)"
+    },
+    "platform_author_id": {
+      "抖音搜索(raw)": "author.sec_uid",
+      "抖音详情(归一化)": "channel_account_id (=sec_uid)",
+      "快手": "channel_account_id",
+      "视频号": "channel_account_id",
+      "小红书(note_card)": "item.note_card.user.user_id",
+      "小红书详情(扁平)": "channel_account_id",
+      "B站搜索(raw)": "mid (uid 恒为 0 弃用)",
+      "B站详情(归一化)": "channel_account_id (=mid 字符串)",
+      "公众号": "url 正则抽 __biz (search,biz字段恒空) / channel_account_id 网关hash + biz_info (account_info)",
+      "youtube搜索": "channel_id (UC...,可能空串)",
+      "youtube详情": "channel_account_id (32位hash,与search channel_id 不同体系)"
+    },
+    "author_display_name": {
+      "抖音搜索(raw)": "author.nickname",
+      "抖音详情(归一化)": "channel_account_name",
+      "快手": "channel_account_name (档案补 account_info.account_name)",
+      "视频号": "channel_account_name",
+      "小红书(note_card)": "item.note_card.user.nick_name",
+      "小红书详情(扁平)": "channel_account_name",
+      "B站搜索(raw)": "author",
+      "B站详情(归一化)": "channel_account_name",
+      "公众号": "— (search nick_name 恒空;须 account_info.account_name 补)",
+      "youtube搜索": "author",
+      "youtube详情": "channel_account_name"
+    },
+    "tags": {
+      "抖音搜索(raw)": "text_extra[].hashtag_name / cha_list[].cha_name (缺则 desc 正则 #xxx)",
+      "抖音详情(归一化)": "topic_list",
+      "快手": "topic_list (常 null,回退 body_text 正则) / account_info.tags(账号级)",
+      "视频号": "topic_list (常 null,从 title 正则 #xxx)",
+      "小红书(note_card)": "item.note_card.desc 正则 #xxx",
+      "小红书详情(扁平)": "topic_list (结构化) / body_text 正则",
+      "B站搜索(raw)": "tag (逗号分隔,split ',')",
+      "B站详情(归一化)": "topic_list",
+      "公众号": "— (topic_list 恒 null,整平台无 hashtag)",
+      "youtube搜索": "— (搜索无 hashtag)",
+      "youtube详情": "body_text 正则 #xxx (topic_list 为 null,detail 是唯一来源)"
+    },
+    "statistics.digg_count": {
+      "抖音搜索(raw)": "statistics.digg_count",
+      "抖音详情(归一化)": "like_count",
+      "快手": "like_count",
+      "视频号": "like_count",
+      "小红书(note_card)": "item.note_card.interact_info.liked_count",
+      "小红书详情(扁平)": "like_count",
+      "B站搜索(raw)": "like",
+      "B站详情(归一化)": "like_count",
+      "公众号": "like_count (detail,常 0)",
+      "youtube搜索": "—",
+      "youtube详情": "like_count"
+    },
+    "statistics.comment_count": {
+      "抖音搜索(raw)": "statistics.comment_count",
+      "抖音详情(归一化)": "comment_count",
+      "快手": "comment_count",
+      "视频号": "comment_count (常 null)",
+      "小红书(note_card)": "item.note_card.interact_info.comment_count",
+      "小红书详情(扁平)": "comment_count",
+      "B站搜索(raw)": "review",
+      "B站详情(归一化)": "comment_count",
+      "公众号": "—",
+      "youtube搜索": "—",
+      "youtube详情": "comment_count"
+    },
+    "statistics.share_count": {
+      "抖音搜索(raw)": "statistics.share_count",
+      "抖音详情(归一化)": "share_count",
+      "快手": "share_count (detail 准,search 滞后)",
+      "视频号": "share_count (常 null)",
+      "小红书(note_card)": "item.note_card.interact_info.shared_count",
+      "小红书详情(扁平)": "share_count",
+      "B站搜索(raw)": "— (search 无独立 share)",
+      "B站详情(归一化)": "share_count",
+      "公众号": "—",
+      "youtube搜索": "—",
+      "youtube详情": "share_count (常 null)"
+    },
+    "statistics.collect_count": {
+      "抖音搜索(raw)": "statistics.collect_count",
+      "抖音详情(归一化)": "collect_count",
+      "快手": "collect_count",
+      "视频号": "collect_count (常 null)",
+      "小红书(note_card)": "item.note_card.interact_info.collected_count",
+      "小红书详情(扁平)": "collect_count",
+      "B站搜索(raw)": "favorites",
+      "B站详情(归一化)": "collect_count",
+      "公众号": "—",
+      "youtube搜索": "—",
+      "youtube详情": "collect_count (常 null)"
+    },
+    "statistics.play_count": {
+      "抖音搜索(raw)": "— (raw 无 play_count,归 0)",
+      "抖音详情(归一化)": "— (play_count 实测 null)",
+      "快手": "view_count",
+      "视频号": "— (无)",
+      "小红书(note_card)": "— (无)",
+      "小红书详情(扁平)": "— (无)",
+      "B站搜索(raw)": "play",
+      "B站详情(归一化)": "play_count",
+      "公众号": "view_count (阅读数)",
+      "youtube搜索": "view_count (带逗号+'views' 文本,正则抽)",
+      "youtube详情": "view_count / play_count (常 null)"
+    },
+    "create_time": {
+      "抖音搜索(raw)": "create_time (秒,×1000)",
+      "抖音详情(归一化)": "publish_timestamp (毫秒)",
+      "快手": "publish_timestamp (毫秒)",
+      "视频号": "publish_timestamp (毫秒)",
+      "小红书(note_card)": "item.note_card.publish_timestamp (秒)",
+      "小红书详情(扁平)": "publish_timestamp (毫秒)",
+      "B站搜索(raw)": "pubdate / senddate (秒,×1000)",
+      "B站详情(归一化)": "publish_timestamp (毫秒)",
+      "公众号": "time (秒,search) / publish_timestamp (毫秒,detail)",
+      "youtube搜索": "published_time (相对文本'7 months ago',部分空)",
+      "youtube详情": "publish_timestamp (毫秒)"
+    },
+    "has_more": {
+      "抖音搜索(raw)": "data.has_more",
+      "抖音详情(归一化)": "data.has_more (=false)",
+      "快手": "data.has_more (实测 false)",
+      "视频号": "data.has_more",
+      "小红书(note_card)": "data.has_more",
+      "小红书详情(扁平)": "data.has_more (=false)",
+      "B站搜索(raw)": "data.has_more",
+      "B站详情(归一化)": "data.has_more (=false)",
+      "公众号": "data.has_more",
+      "youtube搜索": "data.has_more",
+      "youtube详情": "data.has_more (=false)"
+    },
+    "next_cursor": {
+      "抖音搜索(raw)": "data.next_cursor (页码串,如 '12')",
+      "抖音详情(归一化)": "data.next_cursor (=null)",
+      "快手": "data.next_cursor (实测 null)",
+      "视频号": "data.next_cursor (数字游标)",
+      "小红书(note_card)": "data.next_cursor",
+      "小红书详情(扁平)": "data.next_cursor (=null)",
+      "B站搜索(raw)": "data.next_cursor (页码串)",
+      "B站详情(归一化)": "data.next_cursor (=null)",
+      "公众号": "data.next_cursor (页码串)",
+      "youtube搜索": "data.next_cursor (base64 长 token,透传不截断)",
+      "youtube详情": "data.next_cursor (=null)"
+    },
+    "platform_content_url": {
+      "抖音搜索(raw)": "share_url",
+      "抖音详情(归一化)": "content_link",
+      "快手": "content_link",
+      "视频号": "content_link (export 编码)",
+      "小红书(note_card)": "— (需拼 explore/{id})",
+      "小红书详情(扁平)": "content_link",
+      "B站搜索(raw)": "arcurl",
+      "B站详情(归一化)": "content_link",
+      "公众号": "url (search) / content_link (detail)",
+      "youtube搜索": "url (watch 链接)",
+      "youtube详情": "content_link"
+    }
+  },
+  "extraction_pitfalls": [
+    "小红书 note_card 嵌套:搜索内容字段全部在 item.note_card.* 与 item.note_card.user.* / interact_info.* 下,不要在顶层找;详情却是扁平 channel_*。",
+    "公众号 biz 正则:作者标识须从 url 用 __biz=([^&]+) 抽;search 的 biz/nick_name 恒空;detail/account_info 给的是网关 hash,与 biz 不是同一标识,两者都要沉淀。",
+    "时间戳秒/毫秒不一致:同一平台不同接口也可能不同(小红书 search 秒、detail 毫秒;公众号 search 秒、detail 毫秒);落库前按接口统一换算。",
+    "抖音 raw vs 归一化两套字段名:search=aweme_id/author.sec_uid/statistics.digg_count;detail=channel_content_id/channel_account_id/like_count,提取层分别映射。",
+    "B站:title 含 <em class='keyword'> 高亮需剥;uid 恒为 0 弃用以 mid 为准;play/like/favorites/review 对应 play/digg/collect/comment。",
+    "youtube:作者 id 双体系(search channel_id=UC..., detail=32位 hash),建议以 UC... 为稳定主键;view_count 带逗号与 'views' 文本需正则。",
+    "公众号/youtube 搜索阶段无 tag;youtube 须从 detail.body_text 正则抽 #xxx;公众号整平台无 hashtag。"
+  ]
+}

+ 41 - 0
数据接口与来源/跨平台字段映射.md

@@ -0,0 +1,41 @@
+# 跨平台字段映射(canonical → 各平台 raw 路径)
+
+> 机读件:`跨平台字段映射.json`。本文与之同一张表,供人读。
+> 证据:`/tmp/aiddit_captures/*.json` 真实抓包 + `接口台账/*.md` 的 ⑤ 字段台账。
+> canonical 名以 `content_agent/integrations/douyin.py` 归一化 `_normalize_content_item` 为准。
+> `—` = 该平台无此字段 / 拿不准。头条、知乎整平台 blocked(`code=10000`/`data=null`),不入列。
+
+## 一、对照表
+
+抖音两套:**搜索=raw 原生 aweme 结构**、**详情=归一化 channel_\* 结构**,分两列。B站同理(搜索 raw / 详情归一)。小红书搜索字段嵌在 `note_card` 下、详情为扁平结构。
+
+| canonical | 抖音搜索(raw) | 抖音详情(归一) | 快手 | 视频号 | 小红书(note_card) | 小红书详情(扁平) | B站搜索(raw) | B站详情(归一) | 公众号 | youtube搜索 | youtube详情 |
+|---|---|---|---|---|---|---|---|---|---|---|---|
+| **platform_content_id** | `aweme_id` | `channel_content_id` | `channel_content_id` | `channel_content_id` | `item.id` | `channel_content_id` | `bvid` | `channel_content_id` | url 抽 `__biz+mid+idx` / detail `channel_content_id` | `video_id` | `channel_content_id` |
+| **platform_content_format** | 派生(视频→video) | `content_type` | `content_type` | `content_type` | `item.note_card.type` | `content_type` | 派生(video) | `content_type` | `content_type`(note) | 派生(video) | `content_type` |
+| **description** | `desc`/`caption` | `body_text`(标题`title`) | `body_text`(常null) | `title`(含话题串) | `item.note_card.desc`(标题`display_title`) | `body_text`(标题`title`) | `description`/`desc`(标题`title`含`<em>`) | `body_text`(标题`title`) | `body_text`(detail;search仅`title`含`<em>`) | `description_snippet`(标题`title`) | `body_text`(标题`title`) |
+| **platform_author_id** | `author.sec_uid` | `channel_account_id`(=sec_uid) | `channel_account_id` | `channel_account_id` | `item.note_card.user.user_id` | `channel_account_id` | `mid`(uid恒0弃用) | `channel_account_id`(=mid) | url 抽 `__biz` / account_info `biz_info`+hash | `channel_id`(UC…可能空) | `channel_account_id`(32位hash) |
+| **author_display_name** | `author.nickname` | `channel_account_name` | `channel_account_name`(补account_info) | `channel_account_name` | `item.note_card.user.nick_name` | `channel_account_name` | `author` | `channel_account_name` | —(search空;account_info `account_name`补) | `author` | `channel_account_name` |
+| **tags** | `text_extra[].hashtag_name`/`cha_list[].cha_name` | `topic_list` | `topic_list`(常null,正则) | `topic_list`(常null,title正则) | `item.note_card.desc` 正则#xxx | `topic_list`/body_text正则 | `tag`(逗号split) | `topic_list` | —(无hashtag) | —(搜索无) | `body_text`正则#xxx |
+| **statistics.digg_count** | `statistics.digg_count` | `like_count` | `like_count` | `like_count` | `…interact_info.liked_count` | `like_count` | `like` | `like_count` | `like_count`(常0) | — | `like_count` |
+| **statistics.comment_count** | `statistics.comment_count` | `comment_count` | `comment_count` | `comment_count`(常null) | `…interact_info.comment_count` | `comment_count` | `review` | `comment_count` | — | — | `comment_count` |
+| **statistics.share_count** | `statistics.share_count` | `share_count` | `share_count`(detail准) | `share_count`(常null) | `…interact_info.shared_count` | `share_count` | —(search无) | `share_count` | — | — | `share_count`(常null) |
+| **statistics.collect_count** | `statistics.collect_count` | `collect_count` | `collect_count` | `collect_count`(常null) | `…interact_info.collected_count` | `collect_count` | `favorites` | `collect_count` | — | — | `collect_count`(常null) |
+| **statistics.play_count** | —(归0) | —(null) | `view_count` | — | — | — | `play` | `play_count` | `view_count`(阅读) | `view_count`(带'views'正则) | `view_count`/`play_count`(常null) |
+| **create_time** | `create_time`(秒) | `publish_timestamp`(ms) | `publish_timestamp`(ms) | `publish_timestamp`(ms) | `…publish_timestamp`(秒) | `publish_timestamp`(ms) | `pubdate`/`senddate`(秒) | `publish_timestamp`(ms) | `time`(秒)/detail `publish_timestamp`(ms) | `published_time`(相对文本) | `publish_timestamp`(ms) |
+| **has_more** | `data.has_more` | `data.has_more`(false) | `data.has_more`(false) | `data.has_more` | `data.has_more` | `data.has_more`(false) | `data.has_more` | `data.has_more`(false) | `data.has_more` | `data.has_more` | `data.has_more`(false) |
+| **next_cursor** | `data.next_cursor`(页码串) | null | null | `data.next_cursor`(数字) | `data.next_cursor` | null | `data.next_cursor`(页码串) | null | `data.next_cursor`(页码串) | `data.next_cursor`(base64长token) | null |
+| **platform_content_url** | `share_url` | `content_link` | `content_link` | `content_link`(export编码) | —(拼 explore/{id}) | `content_link` | `arcurl` | `content_link` | `url`/detail `content_link` | `url`(watch) | `content_link` |
+
+> github 为代码仓库非视频:`platform_content_id=id`、`platform_author_id=owner_id/owner_login`、`tags=topics`、url 须拼 `https://github.com/{owner}/{repo}`;不入主表。
+
+## 二、提取陷阱注(落库前必读)
+
+1. **小红书 note_card 嵌套**:搜索接口内容字段全部在 `item.note_card.*`(及 `note_card.user.*`、`note_card.interact_info.*`)下,**不要在顶层找**;但详情接口是扁平 `channel_*` 结构,两接口映射不同。
+2. **公众号 biz 正则**:作者标识须从 `url` 用 `__biz=([^&]+)` 抽(search 的 `biz`/`nick_name` 恒为空串);detail/account_info 另给网关 `channel_account_id`(hash),**与 biz 不是同一标识**,两者都要沉淀;昵称只能走 `account_info.account_name` 补。
+3. **时间戳秒/毫秒不一致**:抖音search/B站search/公众号search/小红书search=**秒**;抖音detail/快手/B站detail/小红书detail/youtube/视频号=**毫秒**。同一平台不同接口也可能不同(小红书、公众号 search 秒 vs detail 毫秒)。落库前按接口统一换算。
+4. **抖音 raw vs 归一化两套**:搜索=`aweme_id`/`author.sec_uid`/`statistics.digg_count`;详情=`channel_content_id`/`channel_account_id`/`like_count`。同一条内容字段名不同,提取层分别映射。
+5. **高亮标签剥离**:B站 `title`、公众号 `title`、github `hl_name`/`hl_trunc_description` 含 `<em>` 高亮,落库前正则去 `</?em[^>]*>`。
+6. **B站作者**:`uid` 恒为 0,**禁用**,以 `mid` 为作者主键;`play/like/favorites/review` 对应 play/digg/collect/comment。
+7. **youtube 双作者体系**:search `channel_id`(`UC...`)与 detail `channel_account_id`(32位 hash)不是同一编码,建议以 `UC...` 为稳定主键;`view_count` 带逗号与 `views` 文本需正则抽数字。
+8. **tag 缺口**:公众号整平台无 hashtag(`topic_list` 恒 null);youtube 搜索无 tag,须从 `detail.body_text` 正则 `#([^\s#]+)` 抽;快手/视频号 `topic_list` 常 null,靠 desc/title 正则。

Beberapa file tidak ditampilkan karena terlalu banyak file yang berubah dalam diff ini