关于 scrapewright
scrapewright 为开发者和 Agent 从电商目录及其他网页提取结构化数据。它可识别已知平台,也能为自定义页面编译一次提取器并缓存复用,避免每页重复调用大模型。
主要功能
- 01识别平台并提取商品目录
- 02缓存并复用页面提取器
- 03自定义字段模式
- 04命令行及 CSV、XLSX、JSONL 输出
- 05可选 JavaScript 渲染
适用场景
- 01采集 Shopify 或 WooCommerce 商品
- 02提取职位页面中的指定字段
- 03将商品目录抓取为电子表格
MCP 相关
其 MCP 服务将站点识别、商品抓取、页面提取、站点爬取和已学习站点列表作为工具提供。可在本地运行,也可连接托管服务。
配置
远程服务无需本地安装。选择你使用的客户端,复制配置或使用一键安装。
https://scrapewright.app/mcpclaude mcp add --transport http ozymandias-owens-2-scrapewright https://scrapewright.app/mcp{"mcpServers":{"ozymandias-owens-2-scrapewright":{"type":"http","url":"https://scrapewright.app/mcp"}}}在 Cursor 中打开{"servers":{"ozymandias-owens-2-scrapewright":{"type":"http","url":"https://scrapewright.app/mcp"}}}在 VS Code 中打开{"mcpServers":{"ozymandias-owens-2-scrapewright":{"type":"http","url":"https://scrapewright.app/mcp"}}}{"mcpServers":{"ozymandias-owens-2-scrapewright":{"serverUrl":"https://scrapewright.app/mcp"}}}命令在终端中运行;JSON 粘贴到对应客户端的 MCP 配置后重启。需要授权的服务会在首次连接时提示登录。
https://scrapewright.app/mcp需要授权工具
5| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| url | string | 是 |
详细介绍
scrapewright
给它一个 URL。它就能编写爬虫。
电商目录抓取大致分为两种情况:使用已知平台(Shopify、WooCommerce)的网站会公开整洁的 JSON 数据源;其他网站则使用定制 HTML,你得为每个网站手写解析器,并在标记结构每次变动时重新编写。scrapewright 将两者合并为一次调用:
- 检测 URL 背后使用的平台。
- 对于已知平台,使用其公开目录 API 确定性地提取数据——免费、稳定,无需大模型。
- 对于自定义 HTML,使用大模型合成可复用的提取器,缓存起来,然后永久确定性地重放。
大模型是编译器,而非运行时。它为每个网站运行一次,生成一份 CSS 选择器配方;此后所有页面都由纯 BeautifulSoup 解析,边际成本为零。这就是全部的成本控制方案——不会逐页调用模型,也不会产生随抓取量增长的 token 账单。
┌─────────────┐
store URL ───▶ │ detect │
└──────┬──────┘
┌──────────────────┼──────────────────┐
▼ ▼ ▼
shopify woocommerce generic HTML
products.json wc/store/products (page mode)
│ │ │
│ deterministic │ ▼
│ (free) │ cached recipe? ──yes──▶ replay (free)
└────────┬─────────┘ │ no
▼ ▼
Product{} ◀───── selectors ── JSON-LD? ──yes──▶ Product{} (free)
▲ │ no
│ ▼
└──────── replay ◀── LLM synthesizes recipe ONCE ──▶ cache
所有结果都会规范化为统一的 Product 结构,因此下游代码无需知道或关心记录来自哪条处理路径。
安装
pip install scrapewright # deterministic paths (Shopify, Woo, JSON-LD)
pip install "scrapewright[llm]" # + LLM recipe synthesis for custom HTML
pip install "scrapewright[llm,js,excel,mcp]" # + JS rendering, XLSX, MCP server
playwright install chromium # only needed for --js
使用方法
from scrapewright import Scrapewright
sw = Scrapewright()
# Catalog mode — a whole Shopify/WooCommerce store, deterministically
for product in sw.scrape_catalog("https://shop.example.com", max_items=200):
print(product.brand, product.title, product.price, product.currency)
# Page mode — one custom-HTML product page.
# First call: tries JSON-LD (free); if absent, the LLM writes a recipe once.
# Every later call on that domain: replayed from the cached recipe, no LLM.
item = sw.scrape_page("https://boutique.example.com/products/wool-coat")
print(item.model_dump(exclude={"raw"}))
# Crawl mode — walk a WHOLE custom store from one listing/category URL.
# The frontier discovers product pages (deterministic, free); the first page
# pays the single synthesis cost, every other page replays the recipe.
for product in sw.crawl("https://boutique.example.com/collection", max_items=100):
print(product.title, product.price)
CLI
scrapewright detect https://shop.example.com # platform + strategy
scrapewright run https://shop.example.com --max 50 # scrape a catalog → JSONL
scrapewright crawl https://boutique.example.com/collection -o products.xlsx
scrapewright run https://shop.example.com -o products.csv # Excel-ready CSV
scrapewright add https://boutique.example.com/products/coat # learn a site
scrapewright run https://boutique.example.com/products/coat --no-llm
scrapewright list # cached recipe domains
-o 可写入 .csv(适合 Excel,带 UTF-8 BOM)、.xlsx(pip install scrapewright[excel])或 .jsonl;不指定时,产品会以 JSONL 格式流式输出到 stdout。
了解你正在处理的对象
detect 会在任务开始前判断应采用哪种处理路径:
$ scrapewright detect https://some-store.com
https://some-store.com
platform: bigcommerce
catalog: -
strategy: crawl
note: BigCommerce (Stencil) markup
它可以识别 12 种平台:Shopify 和 WooCommerce 会公开免费的 JSON 目录,因此会采用 catalog 路径——确定性处理,无需大模型或浏览器。Magento、BigCommerce、Salesforce Commerce Cloud、Squarespace、Wix、Webflow、PrestaShop、Shopware、Ecwid 和 OpenCart 可通过特征识别,并采用 crawl 路径,由配方处理方式像处理其他自定义网站一样处理它们——列出这些平台的目的,是让你了解将要面对的情况,而不是为它们各自编写解析器。Wix 和 Ecwid 在客户端渲染,因此检测结果会直接标记为 crawl+js。
如果网站受到反机器人墙拦截,结果会报告带有 HTTP 状态码的 strategy: blocked,而不是假装没有找到任何内容。
使用自己的架构
内置默认架构只适用于产品。你可以声明所需字段,同样的编译一次、免费重放流程也适用于任何结构化页面——招聘信息、房源、登记记录:
scrapewright run https://jobs.example.com/p/123 -f title -f company -f salary:number -f tags:list --schema-name job
from scrapewright import Scrapewright, Schema
job = Schema.from_names(["title", "company", "salary:number", "tags:list"], name="job")
record = Scrapewright().extract("https://jobs.example.com/p/123", job)
print(record.data) # {'title': ..., 'company': ..., 'salary': ..., 'tags': [...]}
字段类型包括 text(默认)、number、url 和 list。number 字段会从页面写出的任何格式中解析数字——"£51.77"、"1.250,00"、"€72,000" 都会转换为数字;如果页面提供的内容不止数字,原始值也会作为 <field>_text 一并保留:
{ "price": 51.77, "price_text": "£51.77" }
如果某个值完全不包含数字(例如 “call us”),则会保留页面原文,而不会将其丢弃。配方会按网站和架构分别缓存,因此同一个域名可以针对多组字段进行编译,彼此不会覆盖。
在 AI Agent 中使用(MCP)
scrapewright 支持 MCP,因此 Agent 可以将其作为工具调用,而不必自己读取原始 HTML。有两种接入方式。
托管服务,无需安装。 使用从 scrapewright.app 获取的密钥,让客户端连接到服务(每月提供 1,000 条免费记录;从未充值过的账户每天可编译一个新站点并渲染 20 个页面):
{
"mcpServers": {
"scrapewright": {
"url": "https://scrapewright.app/mcp",
"headers": { "X-API-Key": "sw_..." }
}
}
}
工具:detect_site、extract_page、crawl_site、crawl_status、account。付费费用从与 REST API 共用的信用额度中扣除;无需提供自己的模型密钥。
本地运行,使用自己的模型密钥。 在你的计算机上运行服务:
pip install "scrapewright[mcp,llm]"
scrapewright mcp
让任意 MCP 客户端连接到此命令,Agent 就能使用五个工具:detect_site、scrape_catalog、extract_page、crawl_site 和 list_learned_sites。
将以下内容添加到客户端配置中——Claude Desktop、Cursor,或其他任何支持 MCP 的客户端:
{
"mcpServers": {
"scrapewright": {
"command": "uvx",
"args": ["--from", "scrapewright[mcp,llm]", "scrapewright", "mcp"],
"env": { "ANTHROPIC_API_KEY": "sk-ant-..." }
}
}
}
只有在没有已知平台、需要编写一次抓取方案的网站上才需要密钥。Shopify 和 WooCommerce 商店无需密钥即可使用。
这正是其经济优势所在。由 Agent 自行读取页面,每读一个页面都要支付模型 Token,且每次都要付费。这些工具的费用是每个站点只需支付一次——Agent 抓取 500 个页面,只需进行一次综合处理,而不是 500 次;平台商店(Shopify、WooCommerce)则完全免费。
作为服务运行
同一套核心功能也可通过 HTTP API 提供,支持密钥、配额、计量和后台任务:
pip install "scrapewright[service,llm]"
scrapewright keys create --label alice --plan free
scrapewright serve --port 8000
curl -X POST localhost:8000/v1/extract -H "X-API-Key: sw_..." -H "Content-Type: application/json" -d '{"url": "https://shop.example.com/products/coat"}'
| 端点 | 用途 |
|---|---|
POST /v1/detect | 平台 + 策略(低成本) |
POST /v1/extract | 单个页面 -> 结构化记录 |
POST /v1/crawl | 整个站点 -> 任务 ID(抓取任务的运行时间可能超过单个请求) |
... mode | links 从列表页跟进到商品页 · rows 读取列表页自身的卡片 · like 提供一个商品页,抓取所有与其结构相同的页面 |
GET /v1/jobs/{id} | 轮询抓取任务 |
GET /v1/jobs/{id}/download?format=csv|xlsx|jsonl | 将已完成的抓取结果作为文件下载 |
GET /v1/usage | 查看此密钥已消耗的额度及其所属套餐 |
也可以不使用 API:scrapewright.app/account 接收列表页 URL 和字段列表,执行抓取并返回电子表格。
预付费信用额度,无需订阅
只有一项操作会产生实际成本:编译一个新站点,即对一个页面进行一次 LLM 处理;简单的商品页成本约为 $0.02,复杂的渲染页面则为 $0.15。此后的所有操作都由 BeautifulSoup 完成——已编译站点的第一万条记录也可免费提供。因此,信用额度按这项操作的成本定价,其他操作的价格都以此为基准:
| 操作 | 信用额度 |
|---|---|
| 提供 1 条记录 | 1 |
| 浏览器渲染 1 次 | 5 |
| 编译 1 个新站点 | 300 |
获取页面、detect | 免费 |
$ scrapewright plans
pack credits price $/credit margin
starter 10,000 $10 0.00100 80.0%
growth 50,000 $40 0.00080 75.0%
scale 250,000 $150 0.00060 66.7%
Free: 1,000 credits a month, resetting.
利润率按编译站点的成本衡量,因为只有这一步会产生费用;如果调整价格后任何套餐的利润率低于 60%,测试就会失败。即使免费账户将所有免费额度都用于最昂贵的操作,每月给我们造成的成本也不会超过 $0.20。
信用额度采用账本,而非计数器——每笔赠送和扣费都会记录为一行,因此有争议的账单可以逐行还原;重放支付 Webhook 也不会重复充值(赠送额度使用幂等键)。额度用尽时会返回 402,并显示余额及处理方法;抓取任务受现有额度限制,因此会在调用方能够支付的范围内停止,而不会超额扣费。
scrapewright credits grant <key_id> --pack starter --idempotency <payment_id>
scrapewright credits balance <key_id>
收款
Stripe 已接入,通过环境配置启用,无需更改代码:
pip install "scrapewright[service,stripe]"
export STRIPE_SECRET_KEY=sk_test_... # absent -> nothing is for sale
export STRIPE_WEBHOOK_SECRET=whsec_... # absent -> webhooks are refused
scrapewright serve
| 端点 | 用途 |
|---|---|
GET /v1/credits/packs | 价格列表——公开访问,无需密钥 |
POST /v1/credits/checkout | 发起购买,返回 Stripe Checkout URL |
POST /v1/webhooks/stripe | 来自 Stripe 的付款通知 |
Webhook 端点不需要 API 密钥——调用方是 Stripe,因此签名就是凭证;未经验证的端点会成为任何猜到 URL 的人都能免费打印额度的工具。以下三条规则保障了集成的安全:
- 验证每个签名。 未配置签名密钥时,会直接拒绝 Webhook,而不是接受未经验证的请求。
- 绝不信任请求中传来的金额。 事件会指定一个套餐;该套餐对应的额度数量由我们自己的价格列表查询,因此被篡改的负载只能买到实际付款对应的内容,否则什么也买不到。
- 以 Checkout 会话为键,幂等地发放额度。 Stripe 会重试投递,而且一次付款可能产生多个事件类型——会话 ID 才能标识实际发生的资金交易。
examples/stripe_smoke_test.py 使用 4242 测试卡,在 Stripe 的测试模式下跑通整个流程。其他任何支付服务商都可以接入 scrapewright.service.billing 中相同的双方法 BillingProvider 协议;如果没有支付服务商,服务就会以免费模式运行,这也是演示或可自托管实例的合适默认设置。
Docker:
docker build -t scrapewright . # static paths
docker build -t scrapewright --build-arg WITH_JS=1 . # + headless Chromium
docker run -p 8000:8000 -v sw-data:/data scrapewright
客户端渲染的商店
添加 --js(或 Scrapewright(js=True)),即可提取在浏览器中渲染商品目录的页面:
scrapewright run https://spa-store.example.com/products/x --page --js
scrapewright crawl https://spa-store.example.com/shop --js -o products.xlsx
渲染在设计上很少发生:先执行静态抓取,只有当静态 HTML 是空的客户端外壳,或无法从中提取内容时,才会启动 Chromium。根据渲染后的 HTML 学到的规则会标记为 needs_js,因此之后运行时会跳过该网站上无用的静态抓取步骤。每次运行最多启动一次浏览器,并在处理每个页面时重复使用。
Product 的结构
url: str # canonical product URL
title: str
brand: str | None
price: Decimal | None # parsed from "1,250.00" / "1.250,00" / "€1290" alike
currency: str | None
available: bool | None
images: list[str] # absolute URLs
sizes: list[str]
description: str | None
sku: str | None
source_platform: str # shopify | woocommerce | json-ld | selector
记录包含标题、价格和 URL 时,即为可用。验证器(scrapewright.coverage)会报告一批记录中的可用比例——在缓存配方之前,用于判断配方可信度的数值。
各部分如何协作
| 模块 | 作用 |
|---|---|
detect | 平台注册表:先进行免费目录探测,再匹配 12 个平台的指纹;返回要使用的策略 |
extract/shopify、extract/woocommerce | 确定性的目录提取器 |
extract/jsonld | 从 <script type="application/ld+json"> 提取 schema.org/Product——免费,覆盖率约为常见水平 |
extract/llm | 根据 HTML 合成 SelectorRecipe——一次性编译步骤 |
extract/selectors | 使用 BeautifulSoup 重放配方——确定性的运行时 |
schema | Schema/Field——声明要提取的内容;PRODUCT_SCHEMA 是内置默认值 |
service/ | FastAPI 应用:API 密钥(以哈希形式存储)、基于记录的配额、成本计量、后台抓取任务、可插拔支付 |
service/credits | 额度价格、套餐和免费额度 |
service/stripe_billing | Stripe Checkout + 经过签名验证的 Webhook |
service/pricing | 实测单位成本及各套餐的利润空间 |
mcp_server | 五个 MCP 工具,供 AI Agent 直接调用 scrapewright |
fetch | StaticFetcher(普通 HTTP)和 BrowserFetcher(无头 Chromium),以及用于判断渲染是否值得付费的外壳启发式方法 |
crawl | Frontier:将一个商品列表 URL 转换为商品 URL(模式匹配 + 卡片模板回退 + 分页)——确定性,无需大模型 |
cache | 按域名持久化配方,让编译只需进行一次 |
validate | 字段覆盖率评分 |
export | 批量导出为 .csv / .xlsx / .jsonl |
pipeline | 编排 detect → extract → validate → cache → heal |
设计说明
- 先运行确定性路径。 Shopify JSON、WooCommerce Store API 和 JSON-LD 可免费覆盖大量真实商店。只有遇到真正自定义的 HTML 时,才会调用大模型。
- 自我修复。 当缓存的配方无法再提取出可用商品时(即网站的 DOM 已更改),页面会回退到免费的 JSON-LD 路径;若仍失败,则会通过重新合成替换过时的配方。网站出现故障后,会在下次运行时自行修复,而不是悄然返回空字段。
- 限定模型开销。 批量和爬取任务会将大模型调用次数限制在
max_synth_per_run(默认值为 3)以内——无法通过合成提取的网站不会导致每个页面都消耗一次模型调用。无论爬取规模多大,费用都有上限。 - 可配置提供商。 大模型提取器接受
model参数,可与任何注入的客户端配合使用;默认通过官方 SDK 调用 Anthropic 的 Claude。
测试
确定性路径已通过离线测试样例全面覆盖——无需网络,也不会调用模型——因此 CI 无需 API 密钥也能通过:
pip install "scrapewright[dev]"
pytest
状态
v0.9(alpha)。已实现并测试:带 API 密钥的 HTTP 服务、预付费额度(按唯一需要付费的操作定价,账目可审计)和 带签名验证 Webhook 的 Stripe 结账、费用计量和后台任务;支持 12 个电商平台的检测 并为每个网站推荐策略、目录提取(Shopify、WooCommerce)、页面提取(JSON-LD、大模型合成的选择器)、配方缓存、 通过重新合成实现自我修复,并限制每次运行的模型预算、爬取队列(从一个商品列表 URL 爬取整个网站)、通过可选的 Playwright 抓取器实现 JS 渲染并自动升级、与架构无关的提取 (自带字段)、面向 AI Agent 的 MCP 服务、覆盖率验证,以及 CSV / XLSX / JSONL 导出。141 项离线测试。
已知限制,直言不讳:不会绕过反机器人墙——这是有意排除的范围。遇到 Akamai/Fastly 式验证的网站时,会如实返回未命中。
路线图:针对无限滚动列表的分页策略,以及部署后的服务实例。
许可证
MIT — 参见 LICENSE。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。