Auto Scraping to CSV

通过自然语言指令自动抓取网页数据并导出为CSV,支持复杂页面结构处理。

已扫描
适合谁
需要快速获取网页数据的研究人员、从事电商或市场分析的运营人员
不适合谁
需要长期自动化爬虫任务的开发者、对数据隐私和合规性要求极高的企业
国内可用性
需网络配置。可能需要网络配置或第三方服务可访问。
安装难度
新手友好(★☆☆)。基于终端操作、依赖、API Key 和本地环境要求的初步判断。

安装与下载

openclaw skills install @science-prof-robot/auto-scraping-to-csv

Skill 说明

命令、参数、文件名以原文为准

Auto Scraping to CSV — 代理驱动的网页抓取

使用基于文本的 DOM 操作抓取任意网页,并将结构化数据导出为 CSV。该代理能够处理复杂的页面特性——无限滚动、分页、弹窗、懒加载等,并在数据不明确时提出澄清问题。无需外部大语言模型。

哲学:让代理自己解决问题

传统抓取需要你手动检查 HTML,编写 CSS 选择器,处理边缘情况,并在网站变更时调试。本技能颠覆这一流程:

你说你想要什么,代理负责实现方式。

你: "抓取产品目录"
代理: "我看到共有 50 个产品分布在 5 页中,且支持无限滚动。
        还发现 '价格'、'促销价' 和 '会员价' 三个字段。
        应该提取哪个价格?"
你: "促销价"
代理: [自动滚动、分页,提取 50 行] → products.csv

代理将执行以下操作:

  1. 探索 页面结构,通过基于文本的 DOM 分析
  2. 识别复杂性 —— 滚动、分页、标签页、筛选条件
  3. 在数据模糊时提问(多个价格字段、缺失数据、格式选择)
  4. 处理边缘情况 —— 关闭弹窗、等待懒加载、出错时重试
  5. 导出 CSV —— 清理后的结构化数据,可直接使用

适用场景

  • 产品目录: "抓取所有带价格和评分的笔记本电脑"
  • 新闻/文章: "获取最新的博客文章,包含标题、日期、作者"
  • 名录列表: "提取所有公司名称、邮箱和网址"
  • 表格数据: "从这个 SaaS 页面获取定价表"
  • 房地产信息: "抓取房源信息,包含价格、卧室数、卫生间数、面积"
  • 招聘网站: "获取职位名称、公司、地点和薪资范围"
  • 社交动态: "提取帖子及其互动数据(点赞、评论、分享)"
  • 研究数据: "从索引页获取引用次数、作者、发表日期"

工作原理

Claude (主机模型)
    ↕  HTTP
桥接服务器 (Node.js + Playwright)
    ↕  page.evaluate()
浏览器 (Chromium) ← 注入页面代理
  1. 桥接服务 通过 Playwright 启动本地 Chromium 浏览器
  2. 页面代理 作为 IIFE 脚本从 CDN 注入目标页面
  3. 页面代理 索引 DOM 并生成简化的文本表示:
   [5]<a >Widget Pro Laptop /></a>
   [12]<div >$1,299.99 /></div>
   [18]<div >4.5 星 (128 条评价) /></div>
  1. Claude 接收文本状态,理解页面结构并决定下一步操作
  2. 代理在数据模糊或复杂时提问
  3. 循环执行,直到完成全部数据提取或用户停止
  4. CSV 导出 将结构化 JSON 转换为 CSV 格式

首次设置

1. 安装 Playwright

npm install -D playwright
npx playwright install chromium

2. 放置桥接脚本

# 从本技能文件夹复制到你的 agents 目录
cp .claude/skills/auto-scraping-to-csv/page-agent-bridge.mjs .claude/agents/

3. 启动桥接服务

node .claude/agents/page-agent-bridge.mjs

默认端口:9876

4. 验证健康状态

curl http://localhost:9876/health

代理驱动抓取工作流

步骤 1:提出你的需求

/scrape-to-csv https://example.com/products
  "提取所有产品,包括名称、价格、评分和评价数量"

步骤 2:代理探索并提出问题

代理会获取 DOM 状态,可能提出如下问题:

代理: "当前页面发现 24 个产品。该网站支持无限滚动,
        滚动后会加载更多内容。
        你需要多少条数据?(输入 'all' 表示全部)"
你: "50"

代理: "我看到三个价格字段:
        - 原价:$1,299
        - 促销价:$999
        - 会员价:$899
        应该提取哪一个?"
你: "促销价"

代理: "部分产品缺货,价格显示为 'N/A'。
        你希望如何处理?
        A) 保留这些行,值为 'N/A'
        B) 跳过这些行
        C) 在单独列中标记为 '缺货'"
你: "C"

步骤 3:代理自动处理复杂情况

代理将自动完成:

  • 滚动以加载更多内容
  • 点击分页按钮
  • 等待懒加载的图片或数据
  • 关闭 Cookie 提示和弹窗
  • 出现元素加载缓慢时重试
  • 若网站阻止抓取则优雅停止

步骤 4:预览并确认

代理: "已提取 50 个产品。以下是预览:

| 名称 | 价格 | 评分 | 评价数 | 库存状态 |
|------|------|------|--------|----------|
| Widget Pro | $999 | 4.5 | 128 | 有货 |
| Gadget Mini | $499 | 4.2 | 89 | 有货 |
| ... | ... | ... | ... | ... |

是否保存为 'products.csv'?(yes/no/修改列名)"
你: "yes"

步骤 5:CSV 文件交付

代理: "已保存至 ./products.csv — 共 50 行,5 列"

复杂场景处理

无限滚动

你: "抓取此动态 feed 中的所有帖子"
代理: "该页面每滚动一次加载 10 条帖子。
        我已滚动 3 次,共发现 30 条帖子。
        是否继续滚动?(yes/no/再滚动 N 次)"
你: "再滚动 5 次"
代理: [滚动] → "共找到 80 条帖子。已保存至 feed.csv"

分页

你: "获取此目录中的所有产品"
代理: "我检测到分页:第 1 页,共 12 页。
        可以抓取全部 12 页(耗时约 2-3 分钟),或部分页面。
        需要多少页?"
你: "全部"
代理: [点击翻页 12 次] → "共 360 个产品,已保存至 catalog.csv"

需要登录

你: "抓取我的订单历史"
代理: "页面跳转至登录页。
        我需要凭据才能继续。
        请提供:
        - 用户名/邮箱
        - 密码
        或输入 'skip' 以取消。"
你: "skip"
代理: "已取消。未提取任何数据。"

多种数据格式共存

You: "从这个页面获取价格"
Agent: "我发现了多种格式的价格:
        - '$19.99'(美国格式)
        - '€17.99'(欧洲格式)
        - '¥2,980'(日本格式)
        应该统一成哪种格式?"
You: "保持原样,增加一个 'currency' 列"
Agent: [执行货币识别并提取] → prices.csv

---

### 缺失或不一致的数据

You: "从这个目录中提取员工数据"

Agent: "我看到共 100 张员工卡片。部分信息缺失:

- 12 个缺少电话号码

- 8 个缺少职位名称

- 3 个缺少照片

如何处理缺失字段?

A) 留空

B) 填写 'N/A'

C) 完全跳过这些行"

You: "B"

Agent: [提取 100 行数据,缺失字段用 'N/A' 填充] → employees.csv

---

## 自然语言指令

### `/scrape-to-csv <url> <描述>`

通用抓取并导出为 CSV。

/scrape-to-csv https://news.ycombinator.com

"获取前 30 条新闻:标题、URL、得分、评论数"

/scrape-to-csv https://www.anthropic.com/news

"最新博客文章:标题、日期、分类、URL"

/scrape-to-csv https://example.com/realestate

"房源列表:地址、价格、卧室数、卫生间数、面积、经纪人"

### `/scrape-table <url> <选择器或描述>`

提取特定表格。

/scrape-table https://example.com/pricing

"包含 Basic/Pro/Enterprise 列的对比表格"

/scrape-table https://example.com/sales

"2024 年第四季度营收分解表"

### `/scrape-news <url>`

专为新闻/博客抓取优化。

/scrape-news https://techcrunch.com

"最新 20 篇文章:标题、作者、日期、摘要、URL"

/scrape-news https://blog.openai.com

"2024 年所有文章:标题、日期、标签、URL"

### `/scrape-products <url>`

专为电商场景优化。

/scrape-products https://amazon.com/s?k=laptops

"笔记本电脑:名称、品牌、价格、评分、是否支持 Prime、URL"

/scrape-products https://shopify-store.com/collections/all

"所有商品:名称、价格、原价、库存状态"

---

## 输出格式

代理会生成结构化的 Markdown 报告:

抓取报告 — example.com/products

会话 ID: a1b2c3d4 | 耗时: 2分14秒 | 行数: 50

任务

提取所有产品,包含名称、价格、评分和评论数量

代理决策

  • 分页处理: 检测到无限滚动,已滚动 5 次
  • 价格字段: 根据用户请求选择“促销价”
  • 缺失数据: 根据用户请求,缺货价格填充为 "N/A"
  • 列名: name, sale_price, rating, review_count, stock_status

示例数据

namesale_priceratingreview_countstock_status
Widget Pro$9994.5128在售
Gadget Mini$4994.289在售
Super Gizmo$1,2994.8256无货

文件

./products.csv — 50 行,5 列

---

## CSV 转换选项

### 选项 A — Python(推荐)

import json, csv, re

桥接返回: "✅ 执行了 JavaScript。结果: [{...}, {...}]"

msg = """PASTE_BRIDGE_RESPONSE_HERE"""

match = re.search(r'Result: (\[.*\])', msg)

if match:

data = json.loads(match.group(1))

with open('output.csv', 'w', newline='') as f:

writer = csv.DictWriter(f, fieldnames=data[0].keys())

writer.writeheader()

writer.writerows(data)

print(f"已写入 {len(data)} 行到 output.csv")

### 选项 B — Node.js

const fs = require('fs');

const data = JSON.parse(fs.readFileSync('data.json', 'utf8'));

const headers = Object.keys(data[0]);

const csv = [

headers.join(','),

...data.map(row => headers.map(h => "${(row[h]||'').replace(/"/g,'""')}").join(','))

].join('\n');

fs.writeFileSync('output.csv', csv);

---

## 故障排除

### 桥接无法启动

Error: Cannot find module 'playwright'

**解决方法:** `npm install -D playwright && npx playwright install chromium`

### 网站阻止抓取

**代理检测到:** "网站返回 403 Forbidden。可能是反爬虫机制。"
**可选方案:**
- 尝试设置 `headless: false`(更像真实用户行为)
- 在请求之间添加延迟
- 更换不同的 User Agent

### 页面加载但未发现数据

**代理检测到:** "页面已加载,但主要显示导航元素。内容可能需要登录或动态加载。"
**代理询问:** "是否需要等待更长时间、向下滚动,或者您有登录凭证吗?"

### 数据看起来异常

**代理检测到:** "价格显示为 'NaN' 或为空。网站可能使用 JavaScript 渲染价格。"
**代理询问:** "是否尝试执行 JavaScript 以提取真实值,还是跳过此字段?"

---

## 与其他工具对比

| 工具 | 配置方式 | 选择器需求 | 复杂页面处理 | 代理提问 | 适用场景 |
|------|-------|-----------|---------------|-----------------|----------|
| **Auto Scraping to CSV** | npm install | 无需 | 自动处理 | 是,澄清模糊点 | 一次性提取、探索性抓取 |
| BeautifulSoup | pip install | 必需 | 手动处理 | 否 | 已知结构、重复抓取 |
| Scrapy | 项目配置 | 必需 | 需要中间件 | 否 | 大规模爬取、数据管道 |
| Playwright E2E | npm install | 必需 | 手动处理 | 否 | 测试、自动化 |
| Browser-Use | API key | 无需 | 部分支持 | 有限 | 多页面研究 |

**使用本技能的场景包括:**
- 不想编写选择器即可抓取
- 页面结构复杂或未知
- 需要代理处理边缘情况(滚动、弹窗、分页)
- 数据存在歧义时需要澄清问题
- 快速完成一次性 CSV 导出

技能:自动抓取至 CSV
版本:1.0.1
分块:3/3

**响应:** `{ url, title, header, content, footer }`

### `POST /sessions/:id/act`
执行操作。

**请求体:**

{ "action": "executeJavascript", "params": { "script": "return document.title;" } }

### `DELETE /sessions/:id`
关闭会话。

### `POST /shutdown`
停止桥接服务。

---

*技能:auto-scraping-to-csv v1.0.0 | 桥接:page-agent-bridge.mjs | 由 Alibaba Page-Agent + Playwright 驱动*
SP
@science-prof-robot

已收录 1 个 Skill

相关推荐