# table-spider-plugin
**Repository Path**: xfc03/table-spider-plugin
## Basic Information
- **Project Name**: table-spider-plugin
- **Description**: 表格数据爬虫,chorme插件
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2026-03-12
- **Last Updated**: 2026-03-13
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# 表格采集扩展 - 功能说明
Chrome 扩展:在指定页面(含 iframe)自动采集表格数据,支持分页翻页,并将结果以 JSON 形式输出到控制台。
---
## 一、功能概述
- **注入范围**:仅在 **iframe** 内执行采集逻辑(`window.top !== window`),顶层页只做注入日志。
- **采集流程**:页面 `load` 后延迟约 800ms 开始采集第 1 页 → 解析当前页所有 `
` → 点击 Ant Design 分页「下一页」→ 等待 1–3 秒随机时间 → 采集下一页,循环直到无下一页或达到页数上限。
- **输出**:在浏览器开发者工具 Console 中打印 `[content-script] 收集到的数据(JSON):` 及完整 JSON。
---
## 二、表格解析规则
### 2.1 表头识别
- **优先**:使用 `` 内第一行的 `| `(或若无 `th` 则用 `th, td`)作为表头。
- **无 thead 时**:仅当存在「包含 ` | ` 的 ` | `」时,将该行的 `th` 作为表头。
- **无任何表头**:不猜测第一行为表头,表头名使用 `col1`、`col2`、…,且所有 `tbody` 的 `tr` 均视为数据行。
### 2.2 单元格取值(多行拆分)
- **Ant Design 多行结构**:单元格内为 `标签: 值
` 时,解析为**对象**,例如:
- `"商品信息"` → `{ "商品名称": "华为 WATCH GT 2", "编号": "2030959704919393280", ... }`
- **纯文本多行**:单元格内容含换行时,按行拆成**字符串数组**,如 `["第一行", "第二行"]`。
- **单行或空**:返回单个字符串或空字符串。
### 2.3 数据行
- 只处理 `tbody` 内带至少一个 `` 的 ` |
`,无 `td` 的行(如分组行、展开行)会被跳过。
---
## 三、分页与采集控制
- **分页按钮**:通过选择器 `.ant-pagination-next` 查找「下一页」,且 `aria-disabled !== "true"` 时才点击。
- **页数上限**:脚本内常量 `MAX_PAGES`(当前为 `3`)。
- **`MAX_PAGES > 0`**:仅采集前 N 页,采满后直接输出并结束。
- **`MAX_PAGES === 0`**:不设上限,一直翻页直到「下一页」不可点,再输出。
- **重试**:当前页未找到任何 `` 时,每隔 1 秒重试,最多重试 10 次(首次进入)或 5 次(翻页后),仍无表格则输出已采集数据并结束。
- **随机延迟**:点击「下一页」后等待 **1–3 秒**(随机)再采集下一页,减轻请求节奏固定带来的风险。
---
## 四、输出 JSON 结构
```json
{
"url": "当前页地址",
"pages": [
{
"page": 1,
"tables": [
{
"tableIndex": 1,
"headers": ["商品信息", "支付金额", ...],
"rowCount": 20,
"data": [
{
"商品信息": { "商品名称": "xxx", "编号": "xxx" },
"支付金额": "¥ 167.12",
...
}
]
}
]
}
],
"totalRows": 60
}
```
- `url`:采集所在 frame 的 `location.href`。
- `pages`:按页顺序,每页包含 `page` 页码和 `tables`(该页所有表格的解析结果)。
- 每个表格含 `tableIndex`、`headers`、`rowCount`、`data`(行对象数组)。
- `totalRows`:累计采集到的数据行总数。
---
## 五、配置与运行环境
- **manifest**:`content_scripts` 含 (1) `messenger.js` 注入 ``,用于 A 页 postMessage 接收参数并写 storage 后跳转;(2) `content.js` 注入 `youpinoffice.zhuanzhuan.com/*`、`zzdzsys.zhuanzhuan.com/*`,`all_frames: true` 以便在 iframe 内执行采集。
- **权限**:`storage` 用于 A→B 跨页传参(写入/读取 `collectParams`)。
- **运行时机**:`run_at: "document_start"`,页面 `load` 后在 iframe 内延迟约 800ms 开始采集。
- **查看结果**:打开目标页面 → F12 打开开发者工具 → 切到 **Console**,在 iframe 对应上下文下查看 `[content-script]` 开头的日志及最终 JSON。
---
## 六、可调参数(脚本内)
| 位置 | 常量/逻辑 | 说明 |
|------|-----------|------|
| `effectiveMaxPages` | 默认 `3`,可由 A 页 `params.maxPages` 覆盖 | 采集页数上限,`0` 表示采到最后一页。 |
| 首次采集延迟 | `setTimeout(..., 800)` | 页面 load 后等待 800ms 再开始第 1 页采集。 |
| 翻页后等待 | 1–3 秒随机 | 点击「下一页」后等待再采下一页。 |
| 无表格重试 | 10 / 5 次,间隔 1s | 当前页无 table 时的重试次数(首次 10,翻页后 5)。 |
修改后需在 `chrome://extensions` 中重新加载扩展并刷新目标页面后生效。
---
## 七、跨标签页通信(A 页传参 → B 页采集)
从 **A 页面(任意你自己的页面)** 点击按钮传入参数,跳转到 **B 页面(采集页,即 matches 中的 youpinoffice / zzdzsys)** 后,B 页会从扩展存储中读取 A 页传入的参数并用于采集。
### 7.1 A 页面:通过 postMessage 传参并跳转
在 A 页面中,给按钮绑定点击逻辑,发送约定好的消息即可(需已安装并启用本扩展):
```javascript
window.postMessage(
{
type: "COLLECT_PARAMS",
targetUrl: "https://youpinoffice.zhuanzhuan.com/hunter-public-system/ledger/payDetail",
params: {
maxPages: 5, // 仅采集前 5 页;传 0 表示采到最后一页
// 可在此扩展更多参数,B 页 content.js 中按需读取
},
},
"*"
);
```
- **type**:必须为 `"COLLECT_PARAMS"`,由扩展的 `messenger.js` 识别。
- **targetUrl**:跳转目标,应为 B 页地址(如 youpinoffice 或 zzdzsys 下的具体路径)。
- **params**:传给 B 页的对象;当前 B 页会读取 **params.maxPages** 作为采集页数上限(数字,0 表示不设上限)。
发送后,扩展会将 `params` 写入 storage,并在**新标签页**打开 `targetUrl`(A 页保持不关闭)。
### 7.2 B 页面:读取参数并采集
- B 页(iframe 内的 content 脚本)在 `load` 时从 `chrome.storage.local` 读取 `collectParams`。
- 若存在且含有 **maxPages**,则用其覆盖默认页数上限(脚本中的 `effectiveMaxPages`),然后开始采集。
- 读完后会删除该存储项,避免下次进入 B 页误用旧参数。
控制台会打印 `[content-script] 使用参数:{ maxPages: N, fromA: true/false }` 便于确认是否使用了 A 页参数。
### 7.3 B 页采集完成后回传给 A 页
- B 页在采集结束(无表格、达到页数上限或无下一页)时,会通过 `chrome.runtime.sendMessage({ action: "collectDone", data })` 把结果发给 background;background 再转发给发起请求的 A 页 tab。
- **A 页接收结果**:在 A 页面中监听 `message`,当 `event.data.type === "COLLECT_RESULT"` 时,`event.data.data` 即为完整采集结果(与 B 页控制台输出的 JSON 结构一致)。
```javascript
window.addEventListener("message", function (event) {
if (event.data?.type === "COLLECT_RESULT") {
const result = event.data.data; // { url, pages: [...], totalRows }
console.log("收到 B 页采集结果:", result);
// 可在此处理 result,如展示、上传等
}
});
```