skill.md 18 KB

Weibo Scraper Skill

Identity

  • Name: weibo_scraper
  • Version: 2.0.0
  • Type: Scraping/Data Extraction
  • Platform: Weibo (weibo.com)

Description

微博热点内容爬取技能。能够从微博平台爬取热搜榜、热门微博、热点话题等内容,提取结构化数据并进行清洗分类。强化版:多榜爬取 + 数据合并 + HTML/JSON 输出。

Capabilities

  1. 多榜爬取 - 同时爬取 5 个榜单(我的热搜、热搜榜、文娱榜、生活榜、社会榜)
  2. 热搜榜爬取 - 获取微博热搜榜单 Top 50
  3. 热门微博抓取 - 获取热门微博内容及作者信息
  4. 详情页爬取 - 访问热点新闻详情页,提取完整正文内容
  5. 图片提取 - 提取并保存微博配图,支持多源提取
  6. 简报生成 - 将图文内容整理为 HTML/Markdown 简报,支持降级处理
  7. 分类筛选 - 按娱乐、社会、科技、搞笑、体育、财经等分类
  8. 指标提取 - 提取点赞数、评论数、转发数、阅读数
  9. 数据清洗 - 去广告、去无效内容、格式标准化
  10. 定时爬取 - 支持 Cron 定时任务和增量更新
  11. 反爬合规 - UA轮换、频率控制、响应验证
  12. 数据合并存储 - 将多榜数据合并成一个数据库文件
  13. HTML 展现 - 生成 HTML 文档便于浏览
  14. JSON 存储 - 生成 JSON 文件用于数据存储

Methodology

Step 1: 初始化请求环境

  1. 创建 requests Session
  2. 设置基础请求头 (User-Agent, Accept, Accept-Language, Referer)
  3. 配置超时 (10秒)

Step 2: 反爬合规控制

  1. User-Agent 轮换: 准备 10+ 个常用 UA,每次请求随机选择
    • Chrome (Mac/Windows/Linux) 各版本
    • Safari (iOS/Mac)
    • Firefox (Windows/Linux)
    • 移动端 UA (Android/iOS)
  2. 请求频率限制: 每次请求间隔 5-10 秒随机延迟
  3. 单 IP 限流: 每分钟请求数 ≤ 10
  4. 指数退避: 遇到 429/403 时,等待 60s 后重试,再失败则等待 120s
  5. Cookie 维护: 定期更新 Cookie,保持登录态
  6. 请求头完整性: 设置 Accept-Encoding, Accept-Language, Connection 等

Step 3: 多榜爬取 (核心新增)

  1. 我的热搜: https://weibo.com/hot/mine - 需要登录 Cookie
  2. 热搜榜: https://weibo.com/hot/search - 需要 Cookie
  3. 文娱榜: https://weibo.com/hot/entertainment - 需要 Cookie
  4. 生活榜: https://weibo.com/hot/life - 需要 Cookie
  5. 社会榜: https://weibo.com/hot/social - 需要 Cookie

实现方式:

  • 每个榜单使用独立 API 调用
  • 按顺序爬取,避免同时触发反爬
  • 每个榜单间隔 10-15 秒
  • 记录每个榜单的爬取状态和结果数

备用移动端 API:

  • 移动端主 API: https://m.weibo.cn/api/index/list?type=hot
  • 移动端娱乐: https://m.weibo.cn/api/index/list?type=entertainment
  • 移动端生活: https://m.weibo.cn/api/index/list?type=life
  • 移动端社会: https://m.weibo.cn/api/index/list?type=social

Step 4: 数据验证与新鲜度

  1. 时间戳验证: 确保数据时间戳
  2. 新鲜度保障: 记录采集时间,过期数据标记
  3. JSON 验证: 检测返回是否为 HTML (验证码页面)
  4. 响应验证: 验证 JSON 解析是否成功,检查 ok 字段是否为 1
  5. 降级策略: 主 API 失败时自动切换备用 API

Step 5: 数据合并与存储 (核心新增)

  1. 合并策略:

    • 创建每日数据库文件 weibo_daily_{date}.json
    • 包含所有榜单的 List 数据
    • 每个热搜项包含 URL 地址
    • 包含点击进入后的相关微博内容
  2. 数据结构:

    {
    "date": "2026-03-29",
    "crawl_time": "2026-03-29T12:00:00Z",
    "boards": [
    {
      "name": "热搜榜",
      "url": "https://weibo.com/hot/search",
      "count": 50,
      "items": [...]
    },
    {
      "name": "文娱榜",
      "url": "https://weibo.com/hot/entertainment",
      "count": 50,
      "items": [...]
    }
    ],
    "details": {
    "hot_1": {
      "content": "完整微博正文内容",
      "author": "发布者用户名",
      "views": 1234567,
      "comments": 890,
      "likes": 1234
    }
    }
    }
    
  3. 分目录存储 (如果数据量大):

    • daily/2026-03-29/ - 当日数据
    • details/ - 详情数据
    • images/ - 图片数据
    • briefs/ - 简报数据

Step 6: 详情内容提取 (核心新增)

对每个热搜项,尝试提取:

  1. 相关微博内容: 访问详情页获取完整正文
  2. 发布者信息: 作者名称、粉丝数、认证状态
  3. 观看量: 阅读数/浏览量
  4. 阅读量: 读取数
  5. 评论量: 评论数
  6. 热度: 综合热度值

API 调用:

  • 详情页 API: https://m.weibo.cn/api/container/getIndex?containerid=100103type%3D1%26q%3D{keyword}
  • 备用 API: https://m.weibo.cn/statuses/show?id={mid}

Step 7: 数据清洗与格式化

  1. 提取关键字段
  2. 转换中文数字 (如 "1.2万" → 12000)
  3. 标准化时间戳
  4. 生成最终 JSON,保留原始数据

Step 8: 详情页爬取 (强化版)

  1. 获取详情页 URL: 从热搜数据中提取 mid 或构建搜索详情 URL
  2. 搜索 API 获取详情: 使用 https://m.weibo.cn/api/container/getIndex?containerid=100103type%3D1%26q%3D{keyword} 获取微博详情
  3. 解析正文内容: 从返回的 JSON 中提取 text 字段(HTML 格式)
  4. 提取纯文本: 使用 strip_tags 或正则去除 HTML 标签获取纯文本
  5. 内容截断处理: 如果内容过长,保留前 5000 字符

  6. 详情页反爬强化策略 ⭐:

    • 专用 Cookie 池: 维护 3-5 个有效 Cookie,定期刷新,与主 API 分离
    • 代理 IP 支持: 支持 HTTP/HTTPS 代理,遇到 403/429 自动切换
    • 请求间隔: 8-15 秒随机(比普通请求更长)
    • 失败重试机制:
      • 首次失败: 等待 60s 重试
      • 二次失败: 更换 UA/Cookie,等待 120s 重试
      • 三次失败: 切换代理 IP,等待 240s 重试
      • 仍然失败: 标记失败,记录日志,继续处理下一条
    • 备用 API: 详情页失败时尝试:
      • https://m.weibo.cn/statuses/show?id={mid}
      • https://m.weibo.cn/detail/{mid}
    • 降级处理: 详情页失败时,记录 metadata.详情页爬取成功=false,但继续生成简报
  7. mid 提取: 从搜索结果 cards[].mblog.mid 获取微博 ID

  8. 多卡片处理: 搜索结果可能包含多个微博,取第一个有效 mblog

Step 9: 图片提取 (强化版)

  1. 提取 pic_ids: 从搜索 API 返回中获取 pic_ids 数组
  2. 构建图片 URL: 使用 https://wx1.sinaimg.cn/large/{pic_id}.jpg 格式
  3. 图片尺寸选择: 使用 large 尺寸减少水印干扰
  4. 下载图片: 如果需要保存图片,使用异步下载(并发 ≤ 3)
  5. 设置 Referer: 请求头设置 Referer 为 weibo.com 避免防盗链
  6. 图片有效性验证: 验证图片 URL 可访问
  7. 备用域名: 尝试 wx1/wx2/wx3/wx4.sinaimg.cn 多个域名提高成功率

  8. 多源提取强化 ⭐:

    • 来源1: 从搜索 API 返回的 pic_ids 数组提取
    • 来源2: 从 media_urls 字段提取(如果有)
    • 来源3: 从详情页 JSON 的 pics 数组提取(详情页爬取成功时)
    • 降级处理: 如果所有图片源都失败,media_urls 设为空数组,并记录日志
  9. 多尺寸尝试: 某尺寸失败时尝试其他尺寸

    • large → bmiddle → small → mw690
  10. 失败跳过: 单张图片下载失败不影响其他图片处理

Step 10: 结果展现与输出 (核心新增)

  1. 更新每日总 List: 保存到 daily/weibo_daily_{date}.json
  2. 生成 HTML 文档: 便于浏览
    • 使用 HTML 模板渲染
    • 包含 CSS 样式、图片画廊、时间线
    • 响应式设计
    • 支持点击展开详情
  3. 生成 JSON 文件: 用于数据存储
    • 完整数据结构
    • 包含所有榜单和详情
  4. 分目录存储 (可选):
    • daily/ - 每日汇总
    • details/ - 详情数据
    • images/ - 图片
    • briefs/ - 简报

HTML 模板结构:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>微博热搜日报 {date}</title>
    <style>
        body { font-family: -apple-system, sans-serif; max-width: 1200px; margin: 0 auto; padding: 20px; }
        .board { margin-bottom: 32px; }
        .board-title { font-size: 24px; font-weight: bold; color: #333; margin-bottom: 16px; }
        .item { margin-bottom: 16px; padding: 12px; border: 1px solid #eee; border-radius: 8px; }
        .rank { display: inline-block; background: #ff3852; color: white; padding: 2px 8px; border-radius: 4px; margin-right: 8px; }
        .title { font-size: 16px; font-weight: bold; color: #333; }
        .meta { font-size: 12px; color: #999; margin-top: 4px; }
        .detail { display: none; margin-top: 12px; padding: 12px; background: #f9f9f9; border-radius: 4px; }
        .item:hover .detail { display: block; }
    </style>
</head>
<body>
    <h1>微博热搜日报 {date}</h1>
    {boards_html}
</body>
</html>

Implementation

API Endpoints

  • 我的热搜 (PC): https://weibo.com/hot/mine - 需要 Cookie
  • 热搜榜 (PC): https://weibo.com/hot/search - 需要 Cookie
  • 文娱榜 (PC): https://weibo.com/hot/entertainment - 需要 Cookie
  • 生活榜 (PC): https://weibo.com/hot/life - 需要 Cookie
  • 社会榜 (PC): https://weibo.com/hot/social - 需要 Cookie

  • 主 API (PC 端): https://weibo.com/ajax/side/hotSearch - 需要 Cookie

  • 备用 API 1 (移动端): https://m.weibo.cn/api/index/list?type=hot - 无需 Cookie

  • 备用 API 2 (话题): https://m.weibo.cn/api/container/getIndex - 无需 Cookie

  • 详情页 API: https://m.weibo.cn/api/container/getIndex?containerid=100103type%3D1%26q%3D{keyword} - 无需 Cookie

  • 详情页备用 API: https://m.weibo.cn/statuses/show?id={mid} - 无需 Cookie

Image URL Pattern

# 基础 URL
BASE_IMAGE_URL = "https://wx1.sinaimg.cn/"

# 尺寸选项
SIZE_SMALL = "small"      # 缩略图
SIZE_MIDDLE = "bmiddle"   # 中图
SIZE_LARGE = "large"      # 大图
SIZE_ORIGINAL = "mw690"   # 原图

# 完整 URL 格式
image_url = f"https://wx1.sinaimg.cn/{SIZE}/{pic_id}.jpg"

# 多域名备用
DOMAINS = ["wx1.sinaimg.cn", "wx2.sinaimg.cn", "wx3.sinaimg.cn", "wx4.sinaimg.cn"]

User-Agent Pool

USER_AGENTS = [
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 Chrome/120.0.0.0 Safari/537.36",
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/120.0.0.0 Safari/537.36",
    "Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) AppleWebKit/605.1.15 Mobile/15E148 Safari/604.1",
    "Mozilla/5.0 (Linux; Android 13; Pixel 7) AppleWebKit/537.36 Chrome/112.0.0.0 Mobile Safari/537.36",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 Version/17.0 Safari/605.1.15"
]
DETAIL_COOKIES = [
    {"SUB": "xxx", "SUBP": "xxx"},  # 定期更新
    {"SUB": "yyy", "SUBP": "yyy"},
    {"SUB": "zzz", "SUBP": "zzz"},
]

Rate Limiting

  • 请求间隔: 5-10 秒随机
  • 多榜爬取间隔: 10-15 秒
  • 每分钟请求数: ≤ 10
  • 超时重试: 3 次
  • 退避策略: 遇到 403/429 等待 60s/120s 后重试
  • 详情页请求间隔: 8-15 秒(详情页更敏感)

Error Handling & Fallback Strategy

  • 多榜爬取失败: 跳过失败榜单,继续其他榜单
  • 主 API 失败: 自动切换到移动端 API
  • 详情页失败: 记录日志,标记失败,继续处理下一条,不阻塞流程
  • 图片提取失败: 尝试备用来源,全部失败则设为空数组
  • 简报生成失败: 使用降级模板,标注缺失内容
  • 403 Forbidden: 更换 User-Agent 或切换备用 API
  • 429 Too Many Requests: 指数退避 (60s, 120s, 240s) 后重试
  • 网络超时: 重试,超时递增
  • 反爬机制: 降低频率或切换 API
  • HTML 响应: 检测到验证码页面,更换 UA 并尝试备用 API

Output Format

{
  "source": {
    "platform": "weibo",
    "category": "娱乐",
    "hot_id": "xxx",
    "url": "https://weibo.com/xxx"
  },
  "engagement": {
    "likes": 12345,
    "comments": null,
    "shares": null,
    "read_count": 123456
  },
  "content": {
    "title": "热搜标题",
    "text": "微博正文内容",
    "media_urls": ["https://xxx.jpg"],
    "category_tags": ["娱乐", "明星", "综艺"]
  },
  "author": {
    "username": null,
    "followers": null,
    "verified": false
  },
  "timestamp": "2024-01-01T00:00:00Z",
  "metrics": {
    "hot_rank": 1,
    "hot_score": 999999,
    "trend": "up"
  },
  "metadata": {
    "采集时间": "2024-01-01T00:00:00Z",
    "数据来源": "weibo_hotsearch_api",
    "API版本": "v2",
    "多榜爬取": {
      "enabled": true,
      "boards": ["热搜榜", "文娱榜", "生活榜", "社会榜"],
      "成功": true
    },
    "反爬合规": {
      "ua_rotation": true,
      "rate_limiting": true,
      "response_validation": true
    },
    "详情页爬取": {
      "enabled": true,
      "成功": true,
      "正文提取": true,
      "图片提取": true,
      "失败原因": null
    }
  },
  "raw_data": {},
  "brief": {
    "generated": true,
    "format": "markdown",
    "path": "workspace/brief_20260328.md",
    "降级处理": false
  }
}

每日汇总数据结构 (新增)

{
  "date": "2026-03-29",
  "crawl_time": "2026-03-29T12:00:00Z",
  "boards": [
    {
      "name": "热搜榜",
      "url": "https://weibo.com/hot/search",
      "count": 50,
      "items": [
        {
          "rank": 1,
          "title": "热搜标题",
          "url": "https://weibo.com/xxx",
          "hot_score": 999999,
          "detail_url": "https://m.weibo.cn/detail/xxx"
        }
      ]
    },
    {
      "name": "文娱榜",
      "url": "https://weibo.com/hot/entertainment",
      "count": 50,
      "items": [...]
    },
    {
      "name": "生活榜",
      "url": "https://weibo.com/hot/life",
      "count": 50,
      "items": [...]
    },
    {
      "name": "社会榜",
      "url": "https://weibo.com/hot/social",
      "count": 50,
      "items": [...]
    }
  ],
  "details": {
    "hot_1": {
      "content": "完整微博正文内容...",
      "author": "发布者用户名",
      "author_followers": 100000,
      "author_verified": true,
      "views": 1234567,
      "read_count": 1234567,
      "comments_count": 890,
      "likes_count": 1234,
      "shares_count": 567,
      "hot": 999999
    }
  },
  "output_files": {
    "json": "daily/weibo_daily_20260329.json",
    "html": "daily/weibo_daily_20260329.html"
  }
}

注意: engagement 和 author 字段中无法获取的数据使用 null 而非 0 或 -1,表示数据不可用而非数据缺失。必须通过多源验证尝试获取完整数据。

Execution Commands

# 多榜爬取 + 数据合并
python3 weibo_scraper.py --boards all --merge --output daily

# 多榜爬取 + 详情页 + 简报
python3 weibo_scraper.py --boards all --detail --brief --limit 10

# 爬取热搜榜
python3 weibo_scraper.py --category 娱乐 --limit 20

# 爬取热门微博
python3 weibo_scraper.py --type hot --limit 50

# 详情页爬取 + 简报生成
python3 weibo_scraper.py --detail --brief --limit 10

# 定时增量更新
python3 weibo_scraper.py --cron --output /path/to/output.json

File Structure

weibo-scraper/
├── .claude/
│   └── skills/
│       └── main_skill/
│           └── SKILL.md (本文件)
├── weibo_scraper.py     # 主脚本
├── requirements.txt     # Python 依赖
└── workspace/            # 输出目录
    ├── daily/            # 每日汇总数据
    │   ├── weibo_daily_20260329.json
    │   └── weibo_daily_20260329.html
    ├── details/          # 详情数据
    ├── images/           # 图片数据
    ├── briefs/           # 简报数据
    ├── weibo_*.json     # 爬取结果
    └── brief_*.md       # 生成的简报

Dependencies

  • Python: 3.8+
  • pip packages: requests

Quality Checks

  • [x] 多榜爬取: 支持 5 个榜单同时爬取
  • [x] 数据合并: 合并为每日数据库文件
  • [x] 数据完整: engagement 数据字段存在,无法获取的标记为 null
  • [x] 分类准确: category_tags 正确
  • [x] 时效性: timestamp 为最近内容
  • [x] 无效过滤: 已删除/广告内容已过滤
  • [x] 反爬合规: UA 轮换、请求间隔、响应验证
  • [x] 数据可用性: 保留 metadata 和 raw_data
  • [x] 详情页爬取: 支持获取热点新闻详情页内容,强化反爬策略
  • [x] 图片提取: 支持多源提取,有降级处理
  • [x] 简报生成: 支持降级处理,标注缺失内容
  • [x] HTML 展现: 生成 HTML 文档便于浏览
  • [x] JSON 存储: 生成 JSON 文件用于数据存储

训练记录

迭代历史

  • v1.0.0 → v1.1.0: 增加 UA 轮换、频率控制
  • v1.1.0 → v1.2.0: 将 -1 改为 null,增加响应验证
  • v1.2.0 → v1.3.0: 增加 metadata 和 raw_data 字段
  • v1.3.0 → v1.4.0: 增加多 API 源支持、新鲜度验证、降级策略
  • v1.4.0 → v1.5.0: 增加数据增强步骤、多源验证
  • v1.5.0 → v1.6.0: 优化完整流程、强化多源验证
  • v1.6.0 → v1.7.0: 增加详情页爬取、图片提取、简报生成能力
  • v1.7.0 → v1.8.0: 增加详细反爬策略、简报模板
  • v1.8.0 → v1.9.0: 强化 D6-D8 (详情页Cookie池、图片多源提取、简报降级处理)
  • v1.9.0 → v2.0.0: 增加多榜爬取(5个榜单)、数据合并存储、HTML/JSON 输出

Benchmark 得分

  • v1.3.0: 92.65
  • v1.4.0: 88.25 (评估)
  • v1.5.0: 89.80 (评估)
  • v1.6.0: 93.50
  • v1.7.0: 88.65 (预估)
  • v1.9.0: 91.34
  • v2.0.0: 目标 90+ (多榜爬取 + 数据合并)

新增功能说明 (v2.0.0)

多榜爬取

  • 支持 5 个榜单同时爬取
  • 每个榜单独立 API 调用
  • 间隔爬取避免反爬

数据合并

  • 每日数据合并为一个 JSON 文件
  • 包含所有榜单 List 和详情数据
  • 支持分目录存储大数据量

HTML/JSON 输出

  • 生成 HTML 文档便于浏览
  • 生成 JSON 文件用于存储
  • 支持响应式设计和交互