title: “Har Derived Api Client — Record a site’s XHR into a HAR, derive an HTTP client” sidebar_label: “Har Derived Api Client” description: “Record a site’s XHR into a HAR, derive an HTTP client”
{/* 本页面由 website/scripts/generate-skill-docs.py 根据技能对应的 SKILL.md 文件自动生成。请直接编辑源文件 SKILL.md,而非此页面。 */}
HAR 导出 API 客户端
通过真实浏览器访问网站并将其网络请求记录为 HAR 文件,进而提取出该网站的私有 JSON API,从而允许用户使用普通的 HTTP 请求直接调用该 API —— 这种方式比每次请求都由浏览器控制页面要更加高效且成本低廉。该技术源自 Jared Longster 的创意,后由 Dax (thdxr) 推广普及。此工具仅用于捕获和回放请求,无法绕过身份验证、破解验证码或规避机器人检测;如果网站需要登录会话,用户只需继续使用原有的请求头和 Cookie,而无需伪造它们。
该工具的脚本基于标准库及 Playwright:捕获请求时需要 Playwright,API 提取过程完全依赖标准库,而回放请求则仅需 requests/httpx(或 curl)即可。
该工具涵盖了所有Hermes浏览器捕获路径:默认的本地browser_navigate后端,以及云端/远程后端(Browserbase、Browser-Use、Firecrawl),还有任何通过 /browser connect 连接的CDP端点。由于两种情况下的HAR记录方式存在差异,因此提供了两种捕获脚本——一种用于直接启动浏览器,另一种用于通过CDP连接浏览器(具体操作请参见“如何运行”部分)。
适用场景
- 需要为“<网站>”构建CLI或客户端时——可直接提取该网站的API,而无需手动编写点击脚本。
- 某网站没有公开API,但页面明显会加载JSON数据时。
- 需要反复对同一查询执行
browser_navigate操作时——建议先停止操作,一次性提取目标端点。 - 需要对自动补全、搜索、内容源或结账相关的XHR请求进行逆向分析时。
- 已在云端后端(Browserbase / Browser-Use / Firecrawl)或通过
/browser connect方式捕获了会话,且希望在不重新租用浏览器的情况下获取对应API时。
前提条件
- Playwright及对应的浏览器二进制文件(仅用于捕获阶段):
- 先执行
pip install playwright,再运行playwright install chromium - (如果系统已通过
~/.cache/ms-playwright安装了Playwright浏览器,可直接复用。)
- 先执行
- 用于回放阶段的
requests或httpx库(标准库中的urllib也可使用)。 - 不需要API密钥。客户端所需的任何密钥或令牌均可从HAR文件中获取。
- 对于CDP路径(
har_capture_cdp.py):需有一个可访问的CDP端点。在Hermes中,可通过运行/browser connect查看当前活跃的端点,或直接读取配置文件中的BROWSER_CDP_URL/browser.cdp_url。云端后端则通过cdpUrl/connectUrl属性暴露该端点。
如何运行
该技能下的 scripts/ 目录中所存放的脚本,可通过 terminal 工具来调用。
按路径选择捕获工具——这是最容易让人困惑的部分:
| 浏览器路径 | Hermes 的访问方式 | 捕获工具 |
|---|---|---|
本地 browser_navigate(默认,agent-browser/Playwright) | 在本地启动浏览器 | har_capture.py |
Camofox(已设置 CAMOFOX_URL) | 本地 REST/CDP 接口 | 若该工具支持 CDP,则使用 har_capture_cdp.py,否则需自行实现捕获逻辑 |
| Browserbase / Browser-Use / Firecrawl(云端服务) | CDP(通过 cdpUrl 连接) | har_capture_cdp.py |
/browser connect <url> / BROWSER_CDP_URL | CDP | har_capture_cdp.py |
通用规则:如果是由 Hermes 直接启动浏览器,使用 har_capture.py;如果是通过 CDP 连接到已有浏览器,则使用 har_capture_cdp.py。 har_capture.py 依赖 Playwright 的 record_har_path 函数,而该函数仅能在本地运行的环境中使用。har_capture_cdp.py 则通过 connect_over_cdp() 方法建立连接,并从 page.on("request"/"response") 事件中收集 HAR 数据,因为已连接的浏览器上无法使用 record_har_path。
无论采用哪种路径,都需要使用以下工具:
har_to_client.py——用于筛选 HAR 数据中的 XHR/fetch/JSON 请求,按端点进行分组,并输出参数、请求头、请求体以及重放相关提示信息(如 User-Agent、Cookie、认证信息)。
所有路径的解析均基于该技能对应的目录结构。标准处理流程如下:
# 1a. Capture, LOCAL browser (Hermes launched it)
python3 scripts/har_capture.py "https://SITE/" out.har \
--action "fill:input[name=search]:my query" --action "sleep:3" --wait 2
# 1b. Capture, CDP browser (cloud backend or /browser connect)
# get the endpoint from /browser connect or BROWSER_CDP_URL
python3 scripts/har_capture_cdp.py "ws://HOST/devtools/browser/..." out.har \
--goto "https://SITE/" --action "fill:input[name=search]:my query" \
--action "sleep:3" --wait 2
# 2. Derive — read the endpoints out of the HAR
python3 scripts/har_to_client.py out.har --host SITE --max-body 400
# 3. Replay — write a tiny client from the printed endpoint (see Procedure)
快速参考指南
har_capture.py <url> <out.har> [--wait S] [--headed] [--action SPEC ...]
action SPEC: fill:SELECTOR:TEXT | press:SELECTOR:KEY | click:SELECTOR
goto:URL | sleep:SECONDS (run in order after page load)
use when Hermes LAUNCHED the browser (local browser_navigate default)
har_capture_cdp.py <cdp_url> <out.har> [--goto URL] [--wait S] [--action SPEC ...]
same action SPEC; attaches to an existing CDP browser and does NOT close it
use for cloud backends (Browserbase/Browser-Use/Firecrawl) & /browser connect
har_to_client.py <in.har> [--host SUBSTR] [--include-static] [--max-body N]
default: keeps only XHR/fetch/JSON; --host narrows to one domain
prints per endpoint: query params, non-boring req headers, req body sample,
response status/content-type + body sample
prints "### Replay hints": the browser User-Agent, cookie/auth presence
操作步骤
-
根据捕获方式选择对应的工具(详见“运行方式”表格)。在本地运行时使用
har_capture.py;通过 CDP 连接时则使用har_capture_cdp.py。在 Hermes 环境中,当启用云端/远程后端时,执行/browser connect命令即可获取 CDP 端点地址。 -
定位目标交互操作。使用
browser_navigate(或带--headed参数的捕获模式)打开目标网站,确定需要输入何种选择器或点击哪些元素,同时通过开发者工具的网络面板确认是否有 JSON XHR 请求被触发。 -
通过
terminal工具捕获 HAR 文件。首先指定--action参数以定位对应请求:先执行“填充表单”操作,随后设置足够的sleep时间以等待延迟处理的 XHR 请求完成,最后务必保留--wait参数以确保后续响应能够被完整输出。这两种捕获工具都会嵌入响应内容,因此生成的客户端代码能够呈现真实的请求数据结构。 -
使用
har_to_client.py --host <domain>进行转换。该命令可输出以下信息:请求方法、URL/路径模板(数字或 UUID 格式的部分会简化为{id})、查询参数、请求体中的 JSON 数据,以及### Replay hints部分的内容。 -
编写客户端代码。需完全复现原始请求的各个要素——包括请求方法、路径、查询参数及请求体内容。同时要使用网站实际所需的请求头信息:至少需复制“重放提示”中的 User-Agent 值;如果提示中提到了 Cookie 或认证/令牌相关的请求头,也需一并包含。
-
进行无浏览器测试。使用
terminal工具运行生成的客户端代码,确认其返回的数据与浏览器捕获的结果一致。这才是该流程的最终目标:整个处理过程无需依赖浏览器。 -
(可选)封装为 CLI 工具——可以为转换后的功能编写一个简单的
argparse脚本,例如search.py "frank herbert",以便更便捷地调用。 示例演示(维基百科搜索标题、数据衍生处理及实时回放):
import requests
r = requests.get(
"https://en.wikipedia.org/w/rest.php/v1/search/title",
params={"q": "frank herbert", "limit": 5},
headers={"accept": "application/json",
"User-Agent": "Mozilla/5.0 ... Chrome/131 Safari/537.36"}, # from HAR
timeout=15,
)
for p in r.json()["pages"]:
print(p["title"], "-", p.get("description"))
常见问题
- 默认的浏览器 User-Agent 会触发 403 错误。 许多网站(如 Wikipedia、由 Cloudflare 托管的 API)会拒绝
python-requests/x.y这类 User-Agent。务必使用重放提示中提供的浏览器 User-Agent。这也是在浏览器操作成功的情况下,衍生客户端却失败的首要原因。 - 当
--action操作失败时,HAR 文件尚未完成写入就会中断——此时你将无法获得任何文件。如果在某个选择器上捕获到错误,整个运行过程将一无所获;请修正该选择器(可使用--headed模式进行观察),然后重新运行。切勿试图调试缺失的 HAR 文件。 - 服务器端渲染的页面没有可用于提取的 XHR 请求——
har_to_client.py会输出“未检测到类似 API 的请求记录”。相关数据其实存在于 HTML 中,需通过抓取获取,或寻找那些会发送 JSON 数据的交互操作。 - 带有防抖功能或自动补全功能的 XHR 请求需要真正的暂停时间。 在
fill操作之后添加--action "sleep:3"参数;仅靠输入操作是无法在 HAR 文件关闭前触发请求的。 - 认证/会话相关接口需要使用已捕获的
Cookie/Authorization请求头,而这些头信息是有有效期的。 衍生客户端的稳定性完全取决于这些凭证的有效性;一旦出现 401 错误,就需要重新捕获凭证。HAR 文件中包含敏感信息——请将out.har视为机密文件,在完成衍生操作后立即删除。 - 设置
record_har_content="embed"会导致 HAR 文件体积过大。 可使用--max-body参数限制输出内容;对于内容包含大量媒体的页面,其 HAR 文件本身的体积也可能很大。 - 接口地址可能会发生变化。 网站可能会在未提前通知的情况下更改其私有 API 地址。当客户端出现故障时,应重新执行捕获→衍生操作的流程,而非手动修改 URL 地址。
- 使用错误的捕获工具 = 无 HAR 数据。 运行在云平台/CDP 后端上的
har_capture.py不会记录任何数据(因为它会启动自己的本地浏览器,而非您指定的浏览器)。而har_capture_cdp.py需要对应的端点地址;在 Hermes 环境中,该地址可从/browser connect或BROWSER_CDP_URL获取。请根据捕获工具选择相应的配置路径(参见“运行方式”表格)。 - “无头 Chrome”用户代理特征较不明显。 通过本地浏览器或代理浏览器进行捕获时,生成的 User-Agent 通常为
HeadlessChrome/...;部分网站会检测“无头”标识。而云平台后端(如 Browserbase/Browser-Use)会发送真实的桌面版 Chrome 用户代理,因此基于云平台捕获生成的客户端能更稳定地模拟真实请求。如果基于无头浏览器生成的客户端会出现 403 错误,而普通浏览器却正常,那么在判定端点地址发生变化之前,应先将“无头”用户代理字符串替换为普通的 Chrome 用户代理字符串。 - CDP 捕获方式不会关闭浏览器。
har_capture_cdp.py会连接到它并不控制的浏览器,并让其保持运行状态——这正是 Hermes 所管理的云端/远程会话的运作方式。无需额外添加关闭操作,应由对应的后端负责终止浏览器进程。
验证方法
在没有 API 密钥的情况下,对真实网站进行端到端测试以验证功能。
python3 scripts/har_capture.py "https://en.wikipedia.org/wiki/Main_Page" /tmp/wiki.har \
--action "fill:input[name=search]:dune messiah" --action "sleep:3" --wait 2
python3 scripts/har_to_client.py /tmp/wiki.har --host wikipedia.org --max-body 200
系统会输出类似 GET https://en.wikipedia.org/w/rest.php/v1/search/title 的请求内容,其中包含 q 和 limit 参数,同时返回一个 JSON 格式的 pages 响应。随后可利用相应的处理代码片段重新发送该请求,从而通过普通 HTTP 协议确认是否能获取到匹配的标题。