抓取
Yozh Scraper 会在真实的 Playwright 浏览器中渲染任何 URL,并精确返回您所需的内容——无论是提取的字段、原始 HTML 还是整页截图。 每次抓取都是一项异步任务:提交 URL、轮询任务状态、获取结果。代理、隐身模式、预设以及经过身份验证的会话均被原生支持。
- 真实的浏览器渲染——Playwright 渲染由 JavaScript 构建的页面;切换
render以禁用静态 HTML。 - 结构化提取——CSS 或 XPath 字段规则会返回一个格式规范的
data对象,这比自己下载并解析原始 HTML 要高效得多。 - 内置代理——CyberYozh 家庭/移动 LTE/数据中心代理,支持地理定位,且不会被追踪池 ID。
- 默认启用隐身模式——playwright-stealth 补丁(
navigator.webdriver,WebGL/Canvas 指纹、Chrome 运行时),以降低被机器人检测的概率。 - 预设 — 按名称抓取亚马逊/谷歌/eBay/沃尔玛/YouTube/领英的数据,可选配大语言模型(LLM)自愈功能。
- 会话——针对已登录目标由服务器管理的经过身份验证的会话,可在多次抓取中重复使用。
:8001)会从一个种子URL开始遍历网站,并通过此抓取工具获取每个页面——渲染、代理和会话功能同样适用于被爬取的页面。快速开始
抓取器从根节点 docker-compose.yml 启动(与爬虫并行):
cp .env.example .env # set CYBERYOZH_API_KEY if using proxies docker compose up --build # scraper → http://localhost:8000 # crawler → http://localhost:8001
确认它已上线:
curl http://localhost:8000/api/v1/health
# {"status":"ok","workers":2}
CYBERYOZH_API_KEY 在 .env (可在 app.cyberyozh.com/api-access处获取一个)。若未设置,仅 proxy_type: none 功能可用。基本用法
每个抓取端点都会创建一个后台任务,并返回一个 job_id。轮询该任务,然后获取其结果。
curl -X POST http://localhost:8000/api/v1/scrape/page
-H "Content-Type: application/json"
-d '{ "url": "https://example.com", "proxy_type": "none" }'
# → { "job_id": "req_abc123" }
curl http://localhost:8000/api/v1/scrape/req_abc123 # status
curl http://localhost:8000/api/v1/scrape/req_abc123/results # results
最终结果包含元数据以及您所请求的任何内容(data, raw_html, screenshot_base64):
{
"job_id": "req_abc123",
"status": "done",
"total": 1, "done": 1,
"results": [
{
"request_id": "req_abc123",
"took_ms": 1234,
"meta": { "url": "https://example.com", "final_url": "https://example.com/",
"status_code": 200, "device": "desktop", "proxy_type": "none", "retries": 0 },
"data": null, "raw_html": null, "screenshot_base64": null, "warnings": []
}
]
}
status 动作 queued → running → done (或 failed / cancelled)。结果可查阅 done, failed,以及 cancelled 工作。提取数据
通过一项 extract 规则,响应中将包含一个 data 以字段名称为键的对象——这比下载 raw_html 并自行解析该数据。规则是 css 或 xpath.
curl -X POST http://localhost:8000/api/v1/scrape/page
-H "Content-Type: application/json"
-d '{
"url": "https://example.com",
"extract": {
"type": "css",
"fields": {
"title": { "selector": "h1", "attr": "text", "required": true }
}
}
}'
# result → { "data": { "title": "Example Domain" } }
每个字段都是一条规则:
| 字段键 | 类型 | 默认值 | 说明 |
|---|---|---|---|
selector | string | 必填 | 该字段的 CSS 选择器或 XPath 表达式。 |
attr | string | text | 阅读指南 — text 或一个属性名称(例如 href, src). |
all | bool | false | 将所有匹配项作为列表返回,而不是只返回第一个。 |
required | bool | false | 当缺失时触发警报——驱动预设的LLM自愈机制。 |
使用 "type": "xpath" 配合 XPath 选择器(例如 //h1) 来表示相同的形状。
屏幕截图和原始 HTML 代码
点击此处 screenshot: true 为全屏 PNG(以 base64 格式 screenshot_base64),或 raw_html: true 获取渲染后的完整文章 HTML 代码 raw_html.
curl -X POST http://localhost:8000/api/v1/scrape/page
-H "Content-Type: application/json"
-d '{ "url": "https://example.com", "screenshot": true, "raw_html": true }'
block_assets,请将其在截图时关闭,以便图片正常渲染。代理
要实现可靠的网页抓取,代理是必不可少的——大多数现代网站都会屏蔽直接请求。Yozh 与 CyberYozh 代理服务集成;只需 proxy_type 在任何请求中启用。
| proxy_type | 什么是…… |
|---|---|
res_rotating | 住宅轮换——推荐的默认设置。 |
res_static | 住宅静态IP(专用IP)。 |
mobile | 移动网络/LTE,专用。 |
mobile_shared | 移动网络/LTE,共享资源池。 |
dc_static | 数据中心静态。 |
none | 直接连接,不经代理。 |
使用 proxy_geo (country_code / region / city)。无需费力查找池 ID,即可查看您已购买的内容:
curl "http://localhost:8000/api/v1/proxies/available?proxy_type=res_rotating" curl "http://localhost:8000/api/v1/proxies/countries"
CYBERYOZH_API_KEY 在爬虫的 .env。请在 app.cyberyozh.com/api-access,然后重启容器。预设
一个预设包含请求配置文件、URL 模板和解析规则,因此您可以直接通过网站名称进行抓取,而无需手动组装请求。系统内置了适用于亚马逊、谷歌、eBay、沃尔玛、YouTube 和 LinkedIn 的预设;您也可以自行创建预设(确定性 CSS/XPath 或 AI 生成的)。
curl -X POST http://localhost:8000/api/v1/scrape/preset/page
-H "Content-Type: application/json"
-d '{
"source": "amazon_product",
"preset_params": { "asin": "B08N5WRWNW" },
"locale": "us",
"llm": { "model": "openai/gpt-5.4-mini" }
}'
# → { "job_id": "..." } then GET /api/v1/scrape/<job_id>/results
llm 该参数是可选的。如果不指定该参数,确定性解析器将独立运行;如果指定了该参数,当 required 字段返回为空时,选择器会自动修复。提供程序键(OPENAI_API_KEY / ANTHROPIC_API_KEY / GEMINI_API_KEY / OPENROUTER_API_KEY)位于服务器端,在 .env.通过 GET /api/v1/presets, GET /api/v1/presets/{name},以及 POST /api/v1/presets (用户预设名称必须以 user_).
会话
服务器管理的认证会话:创建一个会话,登录一次,然后将其 session_id 传递给任何抓取任务,从而使用存储的 Cookie 和存储状态来获取页面。对于已登录的目标(例如 linkedin_profile 预设。
POST /api/v1/sessions— 创建。引脚device/proxy_type/proxy_geo和一个 TTL。返回{ session_id, expires_at }.POST /api/v1/sessions/{id}/login— 重放一个声明式登录脚本,creds,其正文包含:{ script, creds }.POST /api/v1/scrape/page与session_idset — 已通过身份验证的抓取。DELETE /api/v1/sessions/{id}— 清理一下。
# 1. create → {"session_id":"sess_...","expires_at":...}
curl -X POST http://localhost:8000/api/v1/sessions
-H "Content-Type: application/json"
-d '{ "device": "desktop", "proxy_type": "res_rotating" }'
# 2. log in (declarative DSL + creds)
curl -X POST http://localhost:8000/api/v1/sessions/sess_.../login
-H "Content-Type: application/json"
-d '{ "script": { "steps": [ {"op":"goto","url":"https://site/login"} ] },
"creds": { "username": "...", "password": "..." } }'
# 3. scrape with the session
curl -X POST http://localhost:8000/api/v1/scrape/page
-H "Content-Type: application/json"
-d '{ "url": "https://site/secure", "session_id": "sess_...", "raw_html": true }'
session_id 和 cookies 组合起来 → 422。抓取结果 device / proxy_type / proxy_pool_id / proxy_geo 必须与会话的固定值相匹配。对于登录 DSL 无法解决的 CAPTCHA / 2FA 情况,请跳过脚本,转而将会话cookie注入到会话中。批量抓取
使用以下方式在单个任务中提交多页: POST /api/v1/scrape/pages — 每个条目都代表一个完整的抓取请求。通过同一任务端点查询状态并获取结果。
curl -X POST http://localhost:8000/api/v1/scrape/pages
-H "Content-Type: application/json"
-d '{
"pages": [
{ "url": "https://example.com", "proxy_type": "none" },
{ "url": "https://example.org", "proxy_type": "none" }
]
}'
session_id 适用于批次中的每一页(如果某页已固定了另一个,则会返回 422 状态码拒绝该请求)。MCP
该抓取工具在 /mcp (可流式传输的 HTTP) 处部署了一个模型上下文协议(Model Context Protocol)端点。将 Claude 或 Cursor 指向它,相关工具便会自动显示:
run_scrape_pagerun_scrape_pagesget_job_statusget_job_resultcancel_scrape_jobhealth
"yozh-scraper": {
"type": "http",
"url": "http://localhost:8000/mcp"
}
然后只需询问:“抓取 https://example.com,并告诉我页面上有什么内容。”无论通过 LangChain 代理还是 n8n MCP 客户端工具节点,该端点均可正常工作。
配置参考
请求 — ScrapeRequest (已选中)
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
url | 字符串 (URL) | 必填 | 要渲染和抓取的页面。 |
render | bool | true | 使用浏览器渲染(JS构建的页面需要此操作)。 |
wait_until | domcontentloaded · networkidle | domcontentloaded | 当页面被视为准备就绪时。 |
wait_for_selector | 字符串 · null | null | 在捕获之前,先等待某个特定元素出现。 |
device | desktop · mobile | desktop | 视口 / 用户代理配置文件。 |
proxy_type | 参见“代理” | none | 代理池用于转发请求路由。 |
proxy_geo | ProxyGeo · null | null | 国家/地区/城市定向投放。 |
session_id | 字符串 · null | null | 使用经过身份验证的会话——请参阅“会话”。 |
stealth | bool | true | 应用反检测加固措施。 |
block_assets | bool · null | env | 为提高速度而屏蔽图片/字体/媒体(回退到 BLOCK_ASSETS). |
extract | ExtractRule · null | null | CSS/XPath 字段规则 → 结构化 data. |
raw_html | bool | false | 请包含渲染后的完整 HTML 代码。 |
screenshot | bool | false | 截取整页的 PNG 图片(base64 格式)。 |
API 参考
| 方法 | 路径 | 用途 |
|---|---|---|
| POST | /api/v1/scrape/page | 抓取一页。返回 {"job_id":"…"}. |
| POST | /api/v1/scrape/pages | 在一个任务中批量抓取多个页面。 |
| POST | /api/v1/scrape/preset/page | 按预设名称(Amazon、Google 等)进行抓取。 |
| GET | /api/v1/scrape/{id} | 任务状态(已排队/正在运行/已完成/……)。 |
| GET | /api/v1/scrape/{id}/results | 作业结果(pages + ScrapeResponse)。 |
| DELETE | /api/v1/scrape/{id} | 软取消——机上页面已结束。 |
| POST | /api/v1/sessions | 创建一个经过身份验证的会话。 |
| POST | /api/v1/sessions/{id}/login | 运行一个声明式登录脚本。 |
| DELETE | /api/v1/sessions/{id} | 删除一个会话。 |
| GET | /api/v1/proxies/available | 列出已购买的某类型代理。 |
| GET | /api/v1/presets | 列出内置和用户预设。 |
| GET | /api/v1/health | 健康状况 + 员工人数。 |
重要细节
CYBERYOZH_API_KEY 在爬虫的 .env。若未设置,则仅 proxy_type: none (直接) 方式才有效。session_id 和 cookies 都会返回 422 状态码,且抓取内容必须与会话的固定值相匹配 device / proxy_type / proxy_geo.OPENAI / ANTHROPIC / GEMINI / OPENROUTER)来自 .env ——客户端绝不会发送这些密钥。