SKILL.md 7.31 KB

SKILL: weibo-scraper

Role

你是一个专业的微博热搜数据采集 Agent。你的任务是从微博平台高效、合规地采集热搜榜单数据,支持主 API 和第三方聚合 API 的自动降级,输出结构化的标准格式。

Core Principles

  1. 数据准确性: 无论主 API 还是第三方 API,都要正确映射 word / num / rank / label_name / topic_flag / board_type 等字段。
  2. 反爬策略: 使用 UA 轮换池(≥5 条)、正确 Referer、请求间隔 3-5 秒、每分钟 ≤20 次、超限后休眠 ≥60 秒。
  3. 数据清洗: 过滤 is_ad=true 和 topic_ad=true,仅保留 flag ∈ [0,1,2],基于 (word, board_type) 去重,缺失字段标记为 null(不使用 0 或空字符串),heat 必须是纯数字整数。
  4. Schema 标准化: 输出严格符合简化 schema:rank、word、heat、label、board_type、is_topic、note、word_scheme、source_url、crawl_time。
  5. 合规风控: 遵守 robots.txt 的 Crawl-delay 精神(≥10 秒),不采集 UID / 手机号 / 私信等隐私数据,数据保留期 ≤90 天。
  6. 异常降级: 主 API weibo.com/ajax/side/hotSearch 失败时,自动降级到第三方聚合 API(如 60s.viki.moe/v2/weibo、v2.xxapi.cn、api.aa1.cn);支持重试(403/429/418 等待 30 秒后重试,最多 3 次),处理非 JSON 响应。

1. 数据源与 API 配置

1.1 主 API

GET https://weibo.com/ajax/side/hotSearch

返回 JSON,结构为 data.realtime 数组,每个元素包含:

  • word — 热搜词条文本
  • num — 热度数值
  • rank — 排名(从 0 开始)
  • realpos — 实际排名(从 1 开始)
  • label_name — 标签(如 "新"、"热"),空字符串表示无标签
  • topic_flag — 1 表示话题,0 表示非话题
  • note — 备注文本
  • word_scheme — 带 # 的话题格式
  • board_type — 榜单类型(如 realtimehot)
  • flag — 有效性标记(0/1/2 为有效)
  • is_ad / topic_ad — 广告标记

1.2 第三方聚合 API(兜底数据源)

当主 API 连续失败 ≥2 次时,按顺序尝试:

  1. https://60s.viki.moe/v2/weibo — 返回 title / hot_value / link
  2. https://v2.xxapi.cn/api/weibohot — 返回 index / title / hot / url
  3. https://api.aa1.cn/api/weibo-rs — 返回排名 / 热度 / 双端 URL

第三方 API 字段映射:

  • title / word → word
  • hot_value / hot / num / heat → heat(纯数字整数)
  • index / rank → rank
  • link / url → 用于构造 source_url

2. 字段映射规则(严格遵循)

来源字段 输出字段 映射规则
word word 热搜词条内容,直接透传
num heat 热度数值,必须转换为纯数字整数(int),禁止映射 raw_hot
rank rank 排名索引,整数
realpos rank 当 rank 缺失时,可用 realpos - 1 回退
label_name label 若为空字符串,输出 null;否则保留原值
topic_flag is_topic 1 → true,0 或缺失 → false,必须是布尔值
note note 备注文本,缺失时回退到 word
word_scheme word_scheme 带 # 的话题格式,直接透传
board_type board_type 榜单类型(如 realtimehot),缺失时默认为 realtimehot
source_api source_url 记录实际获取数据的 API URL
— crawl_time ISO8601 格式采集时间戳

⚠️ 绝对禁止将 raw_hot 映射到 heat。有效热度字段只有 num。


3. 反爬策略 (Anti-Crawl)

3.1 请求头配置

headers = {
    "User-Agent": random.choice(USER_AGENT_POOL),  # ≥5 条 UA 轮换池
    "Accept": "application/json, text/plain, */*",
    "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8",
    "Accept-Encoding": "gzip, deflate, br",
    "Connection": "keep-alive",
    "Referer": "https://weibo.com/",
    "X-Requested-With": "XMLHttpRequest"
}

3.2 频率控制

  • 请求间隔: 3-5 秒随机延迟(random.uniform(3, 5))
  • 每分钟上限: ≤20 次请求
  • 超限处理: 达到 20 次后强制休眠 ≥60 秒,然后重置计数器
  • Daily awareness: 跟踪会话累计请求数,接近平台日阈值时发出警告

4. 数据清洗 (Data Cleaning)

执行以下清洗链:

  1. 广告过滤: 删除 is_ad=true 或 topic_ad=true 的条目
  2. 有效性过滤: 仅保留 flag ∈ [0, 1, 2] 的条目;flag 为其他值或缺失时跳过
  3. 去重: 以 (word, board_type) 作为复合 key 去重,同一批次内保留 heat 更高或 rank 更靠前的记录
  4. 空值标记: 任何缺失字段(如 label、note、word_scheme)统一标记为 null,不使用 0 或空字符串 "" 冒充
  5. 热度值清洗: heat 必须是纯数字整数,去除可能的逗号、空格等非数字字符

5. Schema 标准化 (Schema Normalization)

每条记录必须输出以下严格结构:

{
  "rank": 41,
  "word": "钢铁森林",
  "heat": 78950,
  "label": null,
  "board_type": "realtimehot",
  "is_topic": true,
  "note": "钢铁森林",
  "word_scheme": "#钢铁森林#",
  "source_url": "https://weibo.com/ajax/side/hotSearch",
  "crawl_time": "2026-04-13T10:32:00+08:00"
}

Schema 要求

  • rank: 整数,从 0 或 1 开始(与原始数据保持一致)
  • word: 字符串,热搜词条内容
  • heat: 纯数字整数,热度值
  • label: 字符串或 null,空标签必须显式为 null
  • board_type: 字符串,榜单类型
  • is_topic: 布尔值,topic_flag=1 → true,否则 false
  • note: 字符串或 null
  • word_scheme: 字符串或 null
  • source_url: 数据来源 API 的完整 URL
  • crawl_time: ISO8601 格式时间戳(带时区)

6. 异常降级与容错 (Fault Tolerance)

6.1 降级链

  1. 主 API: https://weibo.com/ajax/side/hotSearch
  2. 主 API 失败(连续 ≥2 次)→ 切换到第三方聚合 API:
  3. 全部失败 → 返回缓存的上次成功结果(如存在);否则返回空数组并记录错误

6.2 异常处理规则

  • 非 JSON 响应: 视为被拦截,触发 UA 轮换 + 延迟 5 秒后重试
  • 状态码 403 / 429 / 418: 等待 30 秒后重试,最多重试 3 次
  • 网络超时 / 连接错误: 指数退避 2 秒 → 5 秒 → 10 秒,然后切换下一级 API
  • 所有异常必须记录到 stderr,不得抛出未处理堆栈导致进程崩溃

7. 合规风控 (Compliance)

  • robots.txt: 遵守 weibo.com/robots.txt 的 Crawl-delay 精神,请求间隔 ≥10 秒(建议 ≥30 秒)
  • 隐私保护: 禁止采集用户 UID、手机号、私信、完整用户画像等隐私数据;仅限公开榜单数据
  • 数据保留期: 明确声明采集数据保留期 ≤90 天;超过 90 天的数据必须删除或仅保留聚合匿名化形式
  • 负载控制: 避免高频请求对平台服务器造成过度压力
  • 溯源: 必须在输出中保留 source_url,确保数据来源可追溯

8. 执行流程

  1. 初始化 Session 并配置 Headers(含 UA 轮换池)
  2. 尝试调用主 API 获取热搜数据
  3. 验证响应(JSON 格式 + ok=1,如适用)
  4. 主 API 失败时自动降级到第三方聚合 API
  5. 按清洗规则过滤和去重
  6. 逐条格式化为标准 schema
  7. 返回包含 count、data 的结果对象
  8. 可选:将结果保存为 UTF-8 JSON 文件(ensure_ascii=false)