Insurance Case Collector v7
架构概览
| 配置 | 值 |
|------|------|
| 飞书 app_token | YPjebnqTuadYCqskvl9clYTsnbg |
| 飞书 table_id | tblL6uSDR0NzJ6N7 |
| CLI 路径 | F:\OPENCLAW\skills\tencent-news\tencent-news-cli.exe |
| 主脚本 | F:\OPENCLAW\scripts\insurance-case-collect.js (v5.7, Node.js) |
| 截图目录 | F:\OPENCLAW\screenshots\ |
| 输出目录 | F:\OPENCLAW\scripts\output\ |
| 浏览器 CDP | http://127.0.0.1:18800/json/version |
必填字段
| 字段名 | 字段ID | 类型 | 说明 |
|--------|--------|------|------|
| 序号 | fldPfd7WXr | Number | 递增序号 |
| 保险案例收集-2026-04-13_v2 | fldautXSA2 | Text | "Case X" 格式 |
| 案例标题 | fldjRW409U | Text | 案例标题 |
| 来源链接 | fldwO9nEir | URL | {text, link} 格式 |
| 案件经过 | fldqgJhPMJ | Text | 标题 + 摘要拼接 |
| 事故类型 | fld2xWjXWG | Text | 自动推断 |
| 保险类型 | fldpTe3gSB | Text | 自动推断 |
| 拒赔理由 | fldcreqhV4 | Text | 从摘要/标题推断 |
| 判决理由 | fld9SabTrh | Text | 判决要点 |
| 法律依据 | fldOudZwNW | Text | 默认 "《保险法》相关规定" |
| 关键要点 | fldApPvBZP | Text | 案例核心教训 |
| 争议焦点 | fldcreqhV4 | Text | 从摘要推断争议点 |
| 法院判决 | fldfepHFp9 | Text | 法院判决结果 |
| 截图路径 | fldQR8Xfvn | Text | 截图文件路径字符串 |
| 截图附件 | fldY66Rzpk | Attachment | 截图附件(可选) |
核心原则
- 纯 CLI + 规则提取 — 零大模型参与信息提取
- 端到端脚本化 — Node.js 脚本直调 Bitable HTTP API + Puppeteer 截图,零 Agent 中转
- 自动化率 95%+ — 搜索 → 去重 → 提取 → 写入 → 截图 → 回填 全自动
- 双字段去重 — 链接精确匹配 + 标题编辑距离相似度 > 95%
- 三字段分离 — 拒赔理由、判决理由、争议焦点 分别独立推断
- 截图优先 PDF — 长页面用 PDF 截图,PNG 为备选,防止像素限制截断
- 写前校验截图可执行 — 写入 Bitable 前验证浏览器可连接,失败则标记待截图而非跳过
关键教训:为什么会出现截图缺失 (2026-05-07/08)
问题根因分析
事件回顾: Case 57-68 共 12 个案例需要补截图,实际是之前采集脚本运行时的截图流程未能覆盖到。
根因 1: PNG fullPage 截图受像素上限限制
- 问题: Puppeteer
screenshot({ fullPage: true, type: 'png' })有 25,000,000 像素上限 - 影响: 腾讯新闻长页面 (如 Case 65, 68) 页面高度可达 20,000px+,1907x20769 = 39M 像素超限
- 结果: 截图静默失败,但脚本继续(
critical: false),导致记录写入但无截图 - 证据:
Error: Image dimensions exceed the 25,000,000 pixel input limit: 1907x20769 (39606483 pixels)
根因 2: 截图失败后未回滚 Bitable 写入
- 问题: 当前脚本流程是"先写入记录,再截图回填"
- 影响: 写入成功后截图失败,记录已存在于飞书但无截图
- 结果: 产生"有记录无截图"的半成品数据,后续需要人工补截图
根因 3: 脚本运行后未自动校验截图完整率
- 问题: 脚本运行结束只输出统计数字,不做端到端完整性校验
- 影响: 截图缺失在运行结束后很久才被发现
根因 4: 脚本只处理搜索到的新案例,不处理历史记录
- 问题:
insurance-case-collect.js只搜索 + 写入新案例 - 影响: 已有的历史记录如果需要截图补充,需要额外的人工流程
修复方案
修复 1: 截图策略升级 — PDF 优先 + PNG 兜底
// 新增:先尝试 PDF 截图(无像素限制),失败则降级为 PNG
async function captureScreenshot(url) {
// 策略 A: PDF 截图(推荐,无像素上限)
const pdfPath = await capturePDF(url);
if (pdfPath && fs.statSync(pdfPath).size > 0) {
return { filePath: pdfPath, format: 'pdf' };
}
// 策略 B: PNG 截图(兜底)
// 先检查预估页面高度
await page.evaluate(() => document.body.scrollHeight);
if (width * height > 25000000) {
// 预估超限,强制 PDF
return capturePDF(url);
}
return capturePNG(url);
}
// PDF 截图(使用 page.pdf())
async function capturePDF(url) {
const page = await browser.newPage();
await page.goto(url, { waitUntil: 'domcontentloaded', timeout: 30000 });
await new Promise(r => setTimeout(r, 3000));
// 滚动加载内容
await page.evaluate(() => window.scrollBy(0, window.innerHeight));
await new Promise(r => setTimeout(r, 1000));
const pdfPath = path.join(screenshotDir, `case${num}_full.pdf`);
await page.pdf({ path: pdfPath, format: 'A4', printBackground: true });
await page.close();
return pdfPath;
}
修复 2: 截图失败回滚机制
// 流程调整:先截图,截图成功后再写入
// 旧流程: 写入记录 → 截图 → 回填路径
// 新流程: 截图 → 写入记录(含路径) → 失败则不写入
async function writeCaseWithScreenshot(caseItem) {
// 1. 先截图
const snapResult = await captureScreenshot(caseItem.url);
if (!snapResult) {
console.log(` ✗ 截图失败,跳过 Case ${caseItem.index} (不写入记录)`);
return { written: false, reason: 'screenshot_failed' };
}
// 2. 截图成功,写入记录
const result = await bitableCreateRecord({ ...fields, '截图路径': snapResult.filePath });
return { written: !!result, recordId: result?.recordId };
}
修复 3: 运行后自动校验
// 脚本结束前自动校验
async function validateScreenshotCoverage() {
const allRecords = await bitableListAllRecords();
const missing = allRecords.filter(r => !r.fields['截图路径']);
if (missing.length > 0) {
console.log(` ⚠ 警告: ${missing.length} 条记录缺少截图`);
missing.forEach(r => console.log(` - Case ${r.fields['保险案例收集-2026-04-13_v2']}`));
// 写入校验报告
fs.writeFileSync(
path.join(outputDir, 'screenshot-report.json'),
JSON.stringify({ missing, total: allRecords.length, rate: 1 - missing.length/allRecords.length })
);
}
}
修复 4: 历史记录截图补充专用脚本
- 新增
scripts/fill-missing-screenshots.js:扫描所有缺少截图的记录,自动补截图+回填 - 支持断点续跑,已完成的不重复处理
标准流程
运行脚本(推荐方式)
node F:\OPENCLAW\scripts\insurance-case-collect.js
脚本自动完成以下全流程:
- 飞书认证 — 使用 appId/appSecret 获取 tenant_access_token(7200s 有效,缓存 60min)
- 浏览器连接 — CDP 端口 18800 连接 Chromium 浏览器(自动启动兜底)
- 多渠道搜索 — 3 组关键词各搜索 10 条,共 30 条候选
- 读取现有记录 — 分页拉取所有 Bitable 记录用于去重
- 去重核查 — 链接清理后精确匹配 + 标题相似度 > 95%
- 规则提取 — 正则关键词匹配推断所有字段(三字段独立推断)
- 输出 JSON — 保存到
scripts/output/new-cases.json(调试用) - 批量写入 + 截图 + 回填 — 截图优先,成功后再写入
- 完整性校验 — 运行后自动检查截图覆盖率,生成报告
补充历史记录截图
node F:\OPENCLAW\scripts\fill-missing-screenshots.js
脚本配置项
// F:\OPENCLAW\scripts\insurance-case-collect.js 顶部 CONFIG
const CONFIG = {
cliPath: 'F:\\OPENCLAW\\skills\\tencent-news\\tencent-news-cli.exe',
// 搜索关键词优先级:非车险 > 车险 > 通用
searchQueries: [
// 非车险(优先收集,占比目标 60%+)
'企财险 理赔 法院 判决',
'企业财产保险 拒赔 纠纷',
'货运险 理赔 纠纷 法院',
'货物运输保险 拒赔',
'工程险 理赔 案例 判决',
'建筑工程一切险 拒赔',
'公众责任险 理赔 纠纷',
'产品责任险 拒赔 案例',
'雇主责任保险 理赔 判决',
'安全生产责任保险 纠纷',
'农业保险 理赔 案例',
'种植险 理赔 纠纷',
'信用保证保险 理赔',
'贷款保险 拒赔 纠纷',
'董责险 理赔 案例',
# OPC 个人公司(重点专栏 — 作为独立非车险险种)
'OPC 个人公司 案例',
'OPC 个人公司 理赔 纠纷',
'OPC 个人公司 拒赔 案例',
'个人公司 企财险 理赔',
'个人公司 货运险 理赔',
'个人公司 工程险 理赔',
'个人公司 责任险 理赔',
'个人公司 农险 理赔',
'个人公司 信用保险 理赔',
'个人公司 董责险 理赔',
'个人公司 保证保险 理赔',
// 车险(补充)
'车险 理赔 法院 判决',
'车险 拒赔 纠纷',
// 通用(兜底)
'保险 理赔 法院',
'保险 拒赔 纠纷',
'保险 理赔 案例 判决',
],
// 非车险关键词权重(匹配优先级)
nonAutoPriority: [
'企财', '企业财产', '货运', '货物', '运输保险', '工程',
'建筑', '建工', '公责', '公众责任', '产品责任', '雇主责任',
'安全生产', '农险', '农业', '种植', '养殖', '信保',
'信用保证', '贷款', '董责', '董事监事', '环境污染',
'机器损坏', '利润损失', '营业中断', '承运人责任',
# OPC 个人公司关键词
'个人公司',
],
retryCount: 2, // CLI 调用失败重试次数
retryDelay: 1000, // 重试间隔 (ms)
writeDelay: 500, // 写入间隔 (ms),防限流
screenshotDir: 'F:\\OPENCLAW\\screenshots',
cdpPort: 18800,
screenshotFormat: 'pdf', // 'pdf' (推荐) 或 'png'
screenshotOnFail: 'skip' // 'skip'=跳过不写入, 'mark'=写入但标记待截图
};
辅助脚本(scripts/ 目录)
| 脚本 | 用途 |
|------|------|
| insurance-case-collect.js | 主脚本:搜索 → 去重 → 写入 → 截图 → 回填 → 校验 |
| fill-missing-screenshots.js | 补充所有缺少截图的记录 |
| check-screenshots.js | 检查截图完整率,生成报告 |
| batch-screenshot.js | 批量截图特定 Case(遗留,已被 fill-missing-screenshots 替代) |
| fix-missing-screenshots.js | 修复特定 Case 的截图(遗留) |
| check-cases.js | 检查 Bitable 记录完整性 |
| final-screenshot.js | 最终截图回填(遗留) |
所有历史/调试脚本已归档至
scripts/legacy/
规则提取引擎(正则匹配)
事故类型 & 保险类型推断
优先级:非车险 > 车险/人身险。非车险是核心收集目标,搜索关键词和关键词匹配均优先匹配非车险。
非车险(高优先级 — 核心收集目标)
| 关键词 | 事故类型 | 保险类型 | |--------|---------|---------| | 企财/企业财产/厂房/仓库/办公楼/营业场所 | 企财险理赔纠纷 | 企业财产保险 | | 火灾/爆炸/水浸/暴风/暴雨(企业财产) | 企财险理赔纠纷 | 企业财产保险 | | 机器损坏/营业中断/利润损失 | 企财险理赔纠纷 | 企财险(附加险) | | 货运/货物运输/货损/货差/海运/陆运/空运/快递 | 货运险理赔纠纷 | 货物运输保险 | | 集装箱/冷链/散装货/危险品运输 | 货运险理赔纠纷 | 货物运输保险 | | 建筑工程/安装工程/施工/工地/脚手架/塔吊 | 工程险理赔纠纷 | 建筑工程一切险/安装工程一切险 | | 工期延误/工程延误/第三者责任(工程) | 工程险理赔纠纷 | 工程保险 | | 机器损坏/设备损坏(工业) | 工程险理赔纠纷 | 机器损坏保险 | | 公众责任/公共场所/商场/酒店/学校/体育场馆 | 责任险理赔纠纷 | 公众责任保险 | | 产品责任/产品缺陷/产品召回/缺陷产品 | 责任险理赔纠纷 | 产品责任保险 | | 雇主责任/工伤/雇员/超龄/劳务派遣 | 责任险理赔纠纷 | 雇主责任保险 | | 安全生产/特种作业/高处作业/危化品 | 责任险理赔纠纷 | 安全生产责任保险 | | 环境污染/排污/泄漏/生态破坏/土壤污染 | 责任险理赔纠纷 | 环境污染责任保险 | | 承运人责任/船东/租船/物流 | 责任险理赔纠纷 | 承运人责任保险 | | 农业/种植/养殖/气象/农作物/林木/牲畜 | 农险理赔纠纷 | 农业保险 | | 贷款保证/信用保险/贸易信用/赊销 | 信保理赔纠纷 | 信用保证保险 | | 董责/董事监事/高管/信息披露/证券虚假陈述 | 董责险理赔纠纷 | 董监事及高级管理人员责任保险 | | 保证保险/履约保证/合同保证/投标保证 | 保证保险理赔纠纷 | 保证保险 |
车险 & 意外险(中优先级 — 已有数据充足)
| 关键词 | 事故类型 | 保险类型 | |--------|---------|---------| | 车险/车辆/撞车/自燃/电动车/网约车/营运车辆 | 车险理赔纠纷 | 财产险/车险 | | 骑手/外卖/猝死/意外险/众包 | 意外险理赔纠纷 | 意外险 |
人身险(低优先级 — 已有数据充足)
| 关键词 | 事故类型 | 保险类型 | |--------|---------|---------| | 重疾/癌症/确诊/肿瘤/甲状腺/白血病/基因检测 | 重疾险/健康险理赔纠纷 | 健康险/重疾险 | | 医疗险/住院/医疗/特药/门诊 | 医疗险理赔纠纷 | 医疗保险 | | 寿险/身故/死亡/年金/定期寿险 | 寿险理赔纠纷 | 人身险/寿险 |
OPC 个人公司(重点 — 作为独立非车险险种)
OPC(个人公司) 是一个独立的非车险险种类别,指由个人(而非企业)投保的非车险业务。投保主体是个人,保险标的多为个人财产或个人责任,理赔逻辑与标准企财险/责任险不同。所有个人公司案例标记为「OPC案例」,优先收集。
| 关键词 | 事故类型 | 保险类型 | |--------|---------|---------| | 个人公司 + 任何险种 | OPC个人公司案例 | OPC(个人公司险) | | 个人公司 + 火灾/爆炸/水浸 | OPC案例(企财) | OPC(个人公司险-企财方向) | | 个人公司 + 货运/货损 | OPC案例(货运) | OPC(个人公司险-货运方向) | | 个人公司 + 工程/施工 | OPC案例(工程) | OPC(个人公司险-工程方向) | | 个人公司 + 公众/产品责任 | OPC案例(责任) | OPC(个人公司险-责任方向) | | 个人公司 + 雇主责任 | OPC案例(雇主) | OPC(个人公司险-雇主方向) | | 个人公司 + 农业/种植 | OPC案例(农业) | OPC(个人公司险-农险方向) | | 个人公司 + 信用/贷款 | OPC案例(信保) | OPC(个人公司险-信保方向) | | 个人公司 + 董责/信息披露 | OPC案例(董责) | OPC(个人公司险-董责方向) |
其他
| 关键词 | 事故类型 | 保险类型 | |--------|---------|---------| | 欺诈/骗保/伪造/虚假材料 | 保险欺诈案 | 不限 | | 处罚/罚款/违规/监管/罚单/通报 | 行政处罚案例 | 不限 |
拒赔理由推断
| 关键词 | 拒赔理由 | |--------|---------| | 欺诈/骗保/伪造/虚假材料 | 涉嫌保险欺诈/骗保,提交虚假材料 | | 处罚/罚款/违规/监管/罚单 | 保险公司因经营违规行为被监管处罚 | | 身份证号/笔误/误载 | 投保信息记载有误,保险公司以此为由拒赔 | | 既往症/新发/未如实告知 | 保险公司以"既往症"/"未如实告知"为由拒赔 | | 免责/免责条款/除外责任 | 保险公司以免责条款为由拒绝赔付 | | 车险/车辆/自燃/超速/酒驾/无证 | 保险公司以超出保险责任范围/驾驶人违法为由拒赔 | | 猝死/工作时间/众包/骑手 | 保险公司以不属于保险责任范围/非工作时间为由拒赔 | | 重疾/癌症/基因检测/检测手段 | 保险公司以未达到合同约定的疾病诊断标准为由拒赔 | | 雇主责任/超龄/劳务派遣/临时工 | 保险公司以员工超龄/不在雇佣关系内/劳务派遣为由拒赔 | | 火灾/爆炸/水浸(企业财产)/施救不足 | 保险公司以未采取合理施救措施/损失扩大为由拒赔 | | 货损/货差/包装不良/自然损耗/固有缺陷 | 保险公司以包装不良/货物固有缺陷/自然损耗为由拒赔 | | 工程延误/停工/不可抗力/地震/暴雨 | 保险公司以不可抗力/地震除外/工程延误为由拒赔 | | 环境污染/排污许可/未达标排放 | 保险公司以未取得排污许可/未达标排放为由拒赔 | | 产品缺陷/使用超期/未按说明使用 | 保险公司以产品使用超期/未按说明使用为由拒赔 | | 种植/养殖/干旱/洪涝/病虫害 | 保险公司以灾害不属于保险责任范围/未达到起赔标准为由拒赔 | | 董责/信息披露/证券欺诈/内幕交易 | 保险公司以不属于保险责任范围/故意行为除外为由拒赔 | | 个人公司 + 任何险种 | OPC个人公司案例专属标记,记录个人公司投保和理赔过程 |
判决理由 & 争议焦点推断
- 每个案件独立推断,不共享逻辑
- 基于关键词 + 上下文组合判断
- 确保三字段内容不重复
数据质量保障
| 校验项 | 规则 | |--------|------| | 标题长度 | ≥ 5 字符 | | 案件经过 | ≥ 10 字符 | | 来源链接 | 必须存在且非空 | | 三字段一致性 | 拒绝拒赔理由 = 判决理由 = 争议焦点 的记录 | | 去重 | 链接精确匹配 + 标题相似度 > 95% | | 截图覆盖率 | 写入完成后自动校验,缺失率 > 0% 时输出警告并生成报告 |
错误处理
| 阶段 | 错误类型 | 处理方式 | |------|---------|----------| | 搜索 | CLI 超时/失败 | 重试 2 次,间隔 1s | | 搜索 | 返回空 | 记录,继续下一关键词 | | 认证 | token 获取失败 | 终止,报错 | | 去重 | API 失败 | 终止,报错(无法去重) | | 写入 | 单条失败 | 跳过,继续写入后续 | | 写入 | API 限流 | 写入间隔 500ms 防限流 | | 截图 | 页面过长 (像素超限) | 降级为 PDF 截图,不跳过 | | 截图 | CDP 连接失败 | 标记待截图,不写入记录(或标记待处理) | | 截图 | 页面加载超时 | 重试 1 次,仍失败则标记待截图 | | 校验 | 运行后截图缺失 | 生成 screenshot-report.json,输出警告 |
截图说明
- 优先格式: PDF(
browser(action="pdf", profile="openclaw")或page.pdf()),无像素上限,适合长页面(如腾讯新闻、微信公众号等) - 备选格式: PNG(
browser(action="screenshot", fullPage=false, type="png", profile="openclaw")),适用于短页面,必须使用fullPage=false避免像素超限 - 像素超限检测: 页面宽度 × 高度 > 25,000,000 时自动切换 PDF
- 存储路径:
F:\OPENCLAW\screenshots/case_YYYYMMDD_序号.pdf或case_YYYYMMDD_序号.png - 回填: 文件路径字符串写入 Bitable
截图路径字段 - URL 清理: 写入 Bitable 前自动去除 query params
browser 工具截图最佳实践
当使用 browser 工具进行截图时:
- 长页面(新闻、文章、公众号等):使用
browser(action="pdf", profile="openclaw", fullPage=true)生成 PDF 截图,无像素上限限制。 - 短页面(短文章、简单页面):使用
browser(action="screenshot", fullPage=false, type="png", profile="openclaw"),避免fullPage=true导致的像素超限。 - 必须指定 profile="openclaw",使用默认的 isolated OpenClaw-managed browser
openclaw。
Bitable API 说明
脚本通过 Node.js native fetch() 直接调用,无需 Agent 中转:
- 认证:
tenant_access_token通过 appId/appSecret 获取,自动缓存 60min - 读取:
GET /open-apis/bitable/v1/apps/{app_token}/tables/{table_id}/records - 写入:
POST /open-apis/bitable/v1/apps/{app_token}/tables/{table_id}/records - 更新:
PUT /open-apis/bitable/v1/apps/{app_token}/tables/{table_id}/records/{record_id} - Header:
Authorization: Bearer {token}+Content-Type: application/json
注意事项
- Node.js 24+ 是必需运行时(使用 native
fetch()和AbortSignal.timeout()) - Chromium 浏览器必须通过 CDP 端口 18800 暴露调试端口
- 脚本输出 JSON 文件可作为失败恢复的数据源
- 如需修改搜索关键词,编辑脚本顶部
CONFIG.searchQueries - 如需调整写入频率,修改
CONFIG.writeDelay - 长页面优先 PDF 截图,PNG 仅在页面较短时使用
- 截图失败时不回写 Bitable,避免产生半成品数据
版本历史
| 版本 | 日期 | 变更 | |------|------|------| | v2 | 2026-04-27 | 原始 Agent 编排版本,PowerShell 脚本 | | v3 | 2026-04-27 | 引入 Node.js 脚本,Agent 中转写入 | | v4 | 2026-04-28 | 直调 Bitable API,HTTP 请求封装 | | v5.0 | 2026-04-28 | 端到端自动化,90%+ 自动化率 | | v5.2 | 2026-04-28 | 三字段分离修复 + 数据质量校验 | | v5.3 | 2026-04-28 | 截图集成 + 自动回填 + 95%+ 自动化率 | | v5.7 | 2026-04-28 | 自动启动浏览器 + 重复函数清理 + 步骤校验 | | v6.0 | 2026-05-08 | 新增历史记录截图补充脚本 + 运行后校验 | | v7.0 | 2026-05-08 | PDF 优先截图策略 + 截图失败回滚 + 完整性校验报告 | | v8.0 | 2026-05-23 | 非车险优先策略:搜索关键词扩充至 28 个(非车险 17 个),事故类型/拒赔理由匹配规则扩展至 50+ 条目,目标非车险占比 60%+ | | v9.0 | 2026-05-23 | 新增 OPC 个人公司(Personal Company)重点专栏:OPC 作为独立非车险险种管理,14 个搜索关键词 + OPC 事故类型分类 + OPC 拒赔标记 + 飞书新增 OPC 标签字段 |
数据状态(2026-05-23 11:00 CST)
- 总记录数: 68 条
- 截图完整率: 68/68 = 100%
- 截图格式: PDF + PNG
- 三字段分离: 0 条记录三字段内容相同
- 数据质量: ✅ 全部达标(已修复 30 条记录的字段错误)
- 非车险占比: ~15%(企财险 5 条 + 货运险 3 条 + 责任险 12 条 + 农险 2 条 + 工程险 1 条),目标提升至 60%+
- OPC 专栏: ⏳ 尚未收集(新增),目标首次采集
- 待补充: 企财险(大量)、货运险(大量)、工程险(大量)、农险(大量)、董责险、信保、保证保险、OPC 个人公司案例
微信扫一扫