某爬虫策略的基础skills

用 Trae Skill 驯化 AI 爬虫:从 6 个省份实战中提炼的标准化流程

1. 引言

Skill 是 Trae IDE 中的 AI 标准操作流程,存储在 .trae/skills/ 目录下,当用户触发特定场景时自动加载。

本文重点分享:我如何用一个 Skill 文件,让 AI 按标准流程采集 6 个省份的饮用水水源水质数据。

省份 记录数 时间范围 复杂度
上海 - -
湖南 - - ★★★
天津 - - ★★★
陕西 - - ★★★★
黑龙江 3271 2016~2026 ★★★★★
广东 3759 2021~2026 ★★

2. 核心:5 步标准流程

步骤 1:反爬测试 + 列表页分析

设计思路

  • 先测试连通性,确定最低 headers 要求
  • 再判断列表页类型(静态 HTML / JSON API / 动态渲染)
  • 设置止损点,避免在无解问题上浪费 token

应用场景

  • 广东:静态 HTML,仅需 UA
  • 黑龙江:JSON API,需要完整 headers + XHR

关键代码

python 复制代码
# 三级 headers 递进测试
L1_裸请求 = {}
L2_UA = {"User-Agent": "Mozilla/5.0 ..."}
L3_完整 = {"User-Agent": ..., "Accept": ..., "Referer": ...}

步骤 2:链接筛选 + 年月提取

设计思路

  • 标题关键词筛选(INCLUDE_KW / EXCLUDE_KW)
  • 年月正则提取
  • URL 去重 + 标题去重

应用场景

  • 广东:包含季度报告,需要排除
  • 湖南:包含年度报告,需要排除

关键代码

python 复制代码
INCLUDE_KW = ["饮用水", "水源水质"]
EXCLUDE_KW = ["季度", "年度", "全年", "清理整治", "排名"]
RE_YEAR_MONTH = re.compile(r"(\d{4})\s*年\s*(\d{1,2})\s*月")

步骤 3:详情页格式分析

设计思路

  • 必须逐条检查,不能假设所有年份统一
  • 抽样分析(首、中、尾各 3 条)
  • 归纳格式变体

应用场景

  • 黑龙江:3 种列结构(7 列含省份、7 列含供水人口、6 列标准)
  • 陕西:3 种 Era 时代

关键发现

  • 负索引 row[-2] / row[-1] 可以兼容所有列结构
  • 表头关键词匹配比硬编码索引更可靠

步骤 4:数据解析 + xlsx 导出

设计思路

  • 选择解析架构(纯 HTML / 纯 PDF / 双路由)
  • 表头关键词动态映射
  • 16 字段统一格式输出

应用场景

  • 黑龙江:PDF + HTML 双数据源
  • 上海:纯 HTML

关键代码

python 复制代码
# 双路由
if row["pdf_url"]:
    records = parse_from_pdf(row["pdf_url"], ...)
else:
    records = parse_from_html(url, ...)

步骤 5:输出策略文档

设计思路

  • 记录数据源概况、列表页结构、筛选策略、格式分析、已知的坑
  • 为后续维护提供参考

应用场景

  • 每个省份都有独立的策略文档
  • 新增省份时可以参考已有文档

3. 关键设计点

设计点 1:止损机制

问题:AI 容易在无解问题上浪费 token

解决方案:在每个步骤设置止损点

python 复制代码
# 步骤 1 止损
- 列表页需要验证码 / Cookie 认证流程
- JSON API 返回加密数据
- 页面为 JS 动态渲染且找不到底层数据 API

# 步骤 3 止损
- PDF 表格无法被正确提取
- 详情页同时存在 3 种以上完全不兼容的格式变体
- 关键字段无法可靠定位

价值:遇到无解问题时及时停止,等待人工介入

设计点 2:代码压缩

问题:大量代码模板塞进上下文,浪费 token

解决方案:核心流程 + 附录分离

markdown 复制代码
本文档结构:
- 步骤 1~5:核心流程(必读)
- 附录 A~F:代码模板 + 已踩坑参考(按需查阅)

价值:用什么读什么,节省上下文

设计点 3:负索引兼容多列结构

问题:不同年份列数不同,硬编码索引会失效

解决方案:用负索引定位最后两列

python 复制代码
# 2016 年:7 列含省份
# 2017-2018 年:7 列含供水人口
# 2019-2026 年:6 列标准
# 一行代码兼容所有格式
compliance = row[-2]  # 倒数第二列
exceedance = row[-1]  # 最后一列

价值:避免硬编码列索引导致的格式失效

设计点 4:rowspan 展开

问题:HTML 表格中城市名跨行合并,导致城市名丢失

解决方案:pending 队列算法

python 复制代码
pending = {}  # col_idx -> [(value, remaining_rows)]
for row in rows:
    for cell in cells:
        while col in pending and pending[col]:
            val, remaining = pending[col].pop(0)
            expanded.append(val)

价值:正确处理合并单元格

设计点 5:城市名前向填充

问题:PDF 中 pdfplumber 对 rowspan 输出空字符串

解决方案:用 last_city 填充

python 复制代码
last_city = ""
for row in data_rows:
    city = row[city_col].strip()
    if city:
        last_city = city
    else:
        city = last_city

价值:处理 PDF 中的空值


4. 实战案例

案例 1:上海(★ 最简)

特点

  • 静态 HTML 列表页
  • 统一 7 列表格
  • 无特殊处理

价值:最简单的案例,适合入门

案例 2:湖南(★★★ 中等)

特点

  • 2 种报告类型
  • 表格位置变化(新表插入)
  • 城市名重复问题

踩坑

  • 硬编码表格索引 → 新表插入后取错表
  • 解决方案:表头关键词匹配

案例 3:黑龙江(★★★★★ 最复杂)

特点

  • JSON API 列表页
  • PDF + HTML 双数据源
  • 3 种列结构
  • rowspan 展开
  • ★/☆ 符号水源类型

踩坑

  • 列映射全部偏移(compliance 显示取水量数字)
  • 原因:2017-2018 年有 7 列(多了"供水人口"列)
  • 解决方案:负索引 row[-2] / row[-1]

数据

  • 总记录数:3271 条
  • 时间范围:2016~2026 年
  • 城市数量:13 个

案例 4:广东(★★ 较简单)

特点

  • 静态 HTML 列表页
  • 统一 7 列表格
  • 无 rowspan

数据

  • 总记录数:3759 条
  • 时间范围:2021~2026 年
  • 城市数量:21 个

5. 踩坑记录

省份 现象 解决方案
黑龙江 列映射偏移 compliance 显示取水量数字 负索引 row[-2] / row[-1]
黑龙江 rowspan 城市名丢失 pending 队列算法
黑龙江 PDF 空值 城市名为空字符串 前向填充
湖南 表格位置变化 新表插入后取错表 表头关键词匹配
陕西 3 种 Era 不同时代格式不同 时代分类
通用 硬编码索引 不同列数格式失效 负索引

6. 成果展示

数据统计

省份 记录数 时间范围 城市数 复杂度
上海 - - -
湖南 - - - ★★★
天津 - - - ★★★
陕西 - - - ★★★★
黑龙江 3271 2016~2026 13 ★★★★★
广东 3759 2021~2026 21 ★★

质量检查

  • 能直接 python fetch_{province}.py 运行
  • 16 字段完整且无空 city
  • 全部列表页都已遍历
  • 所有格式变体都已覆盖
  • compliance 只有合理值

7. 总结

Skill 系统的价值

  • 标准化流程,减少 AI 犯错
  • 止损机制,避免浪费 token
  • 代码压缩,节省上下文
  • 已踩坑记录,避免重复踩坑

适用场景

  • 需要采集多个省份/城市的数据
  • 每个省份网站结构不同
  • 需要标准化流程
  • 需要避免 AI 犯错

如若需要完整skills的,可关注私信我。

相关推荐
winlife_3 小时前
在 Unity 里用 AI 做游戏:funplay-unity-mcp 从安装到第一次让 AI 改场景
人工智能·游戏·unity·ai编程·claude·mcp
郑洁文3 小时前
基于网络爬虫的Web敏感信息泄露自动化检测工具
前端·爬虫·网络安全·自动化
摆烂工程师4 小时前
教你解决登录 Codex 需要 WhatsApp 电话号码验证,绕过 Codex 二次验证的教程
openai·ai编程·vibecoding
孟健5 小时前
一人公司别急着招人:先算清这 16 万
ai编程
咖啡星人k5 小时前
用MonkeyCode搭建云端开发环境:零配置开始你的第一个AI编程项目
ai编程·效率提升·monkeycode
kyriewen5 小时前
大厂面试新规:不会用AI编程,直接挂
前端·面试·ai编程
子昕5 小时前
Claude Code 新出的 Dynamic Workflows,到底该用来干什么?
ai编程
JavaGuide6 小时前
Codex 接入第三方模型 DeepSeek、GLM、Kimi 教程:CC-Switch 和 Codex++ 两种方案对比
后端·ai编程
宸一6 小时前
Day 2:Function Calling 到底是什么?跟着AI老师从笨办法开始写
ai编程