OpenAdapter:免费桥接Claude网页版为OpenAI API的浏览器自动化方案
1. 项目概述:一个将Claude.ai网页版桥接为OpenAI API的开源工具
如果你和我一样,既想享受Anthropic Claude模型强大的推理能力,又不想为官方API付费,或者你的项目(比如OpenClaw)已经深度依赖OpenAI的API格式,那么今天聊的这个项目——OpenAdapter,绝对值得你花时间研究一下。简单来说,它就是一个“中间人”,一个跑在你本地的服务器。它通过浏览器自动化技术(Playwright),模拟你在claude.ai网站上的操作:你向它发送一个符合OpenAI API格式的请求,它就在后台打开一个真实的浏览器,登录你的Claude账号,把问题“敲”进去,等Claude生成回答后,再把网页上的HTML响应抓取下来,转换成干净的Markdown,最后包装成OpenAI API的格式返回给你。
整个过程,你用的就是自己Claude账号的免费额度,完全绕开了官方API。这对于想用Claude来驱动OpenClaw这类需要OpenAI API的AI助手,或者任何习惯用OpenAI SDK(比如openai这个Python库)来写脚本、开发工具的人来说,是个非常巧妙的解决方案。它把“网页操作”这个黑盒,标准化成了一个可编程的HTTP服务。
2. 核心原理与架构拆解:浏览器自动化如何变身标准API
这个项目的核心思路并不复杂,但实现细节很见功力。它不是去破解Claude的后端接口,而是选择了一条更“笨”但更稳健的路:完全模拟人类用户在浏览器上的操作。这样做的好处是,只要Claude的网页还能正常访问和交互,这个桥接器就大概率能用,避免了因后端接口变动而频繁失效的问题。
2.1 整体工作流:从HTTP请求到网页响应
整个数据流可以清晰地分为三个阶段:
请求接收与解析阶段:你在本地启动了一个Express.js服务器(默认在3000端口)。当你的应用(比如配置好的OpenClaw)向
http://127.0.0.1:3000/v1/chat/completions发送一个POST请求时,server.js会接手。它首先会校验请求体是否符合OpenAI的聊天补全格式,然后核心模块lib/extractPayload.js开始工作。这个模块的任务是把OpenAI格式的消息(可能包含多模态内容,比如文本和图片的base64数据)解析出来,转换成Claude网页聊天框能接受的形式。比如,它会将Base64格式的图片暂存为临时文件,以备后续上传。浏览器自动化执行阶段:这是
lib/sessionManager.js的舞台。它管理着一个Playwright驱动的Chromium浏览器实例。这个浏览器使用一个持久化的用户数据目录(.browser-profile/),所以你只需要在第一次运行时手动登录一次Claude,之后的会话都会保持登录状态。sessionManager拿到解析好的提示词和文件后,会控制浏览器:- 确保页面处于
claude.ai或一个新的聊天界面。 - 找到内容可编辑的输入框(通过一系列备选CSS选择器),将提示词“输入”进去。
- 如果有文件,找到文件上传输入框并附加文件。
- 点击“发送”按钮。
- 确保页面处于
响应监控与格式转换阶段:发送后,系统进入等待状态。
server.js会以固定的间隔(POLL_MS,默认500毫秒)轮询页面DOM,寻找代表Claude回复的HTML元素。这里有个关键逻辑:它不会在收到第一个字符时就返回,而是会持续监控,直到回复内容在连续一段时间(STABLE_INTERVAL_MS,默认30秒)内不再变化,才判定Claude“思考完毕”。接着,lib/htmlToMd.js模块被调用(在浏览器上下文内执行),将抓取到的复杂HTML结构,智能地转换为易于阅读和处理的Markdown文本。同时,lib/rateLimiter.js模块会全程监控页面,一旦检测到Claude网页弹出的“速率限制”或“免费额度已用尽”等提示,就会立即中止流程,并返回一个标准的OpenAI 429(过多请求)错误,包含Retry-After头,让调用方能够优雅地处理。
2.2 关键设计:会话管理与错误恢复
我认为sessionManager.js中的多级恢复策略是项目稳健性的关键。浏览器环境很不稳定,页面可能崩溃、元素可能加载失败。它设计了一个从轻到重的四级恢复阶梯:
- L0(存活探测):最简单,执行一个简单的JavaScript检查,看页面是否还响应。
- L1(页面重载):如果页面卡住,尝试刷新当前页面。
- L2(新建聊天):如果当前聊天上下文有问题,直接导航到
claude.ai/new开始一个全新的对话。 - L3(重启浏览器):关闭整个浏览器上下文,然后用Playwright重新启动一个全新的浏览器实例。
- L4(致命错误):如果以上所有步骤都失败,则向上游返回503服务不可用错误。
这种设计确保了单次请求的失败不会导致整个服务挂掉,大大提升了服务的可用性。此外,会话超时机制(默认1小时无活动则新建聊天)也避免了长期占用一个聊天上下文可能带来的内存泄漏或界面卡顿问题。
3. 从零开始的详细部署与配置指南
理论讲完了,我们上手把它跑起来。无论你用的是Windows、macOS还是Linux,步骤大同小异。
3.1 环境准备与项目初始化
首先,确保你的系统已经安装了Node.js 18或更高版本。你可以在终端输入node -v来检查。没有的话,去Node.js官网下载安装包,记得勾选添加到PATH的选项。
接下来,获取项目代码并安装依赖:
# 克隆仓库,这里用项目作者提供的仓库地址 git clone https://github.com/AviOfLagos/openAdapter.git open-adapter cd open-adapter # 安装项目所需的Node.js模块 npm install # 安装Playwright所需的Chromium浏览器。这一步会下载一个特定版本的Chromium,与你系统是否安装Chrome无关。 npx playwright install chromium针对不同系统的特别提示:
- Linux用户:执行
npx playwright install chromium后,可能会提示你缺少一些系统共享库(比如libnss3, libatk-bridge等)。此时,你需要运行sudo npx playwright install-deps chromium来安装这些依赖。如果你在无图形界面的服务器上,需要先安装X虚拟帧缓冲器(Xvfb),然后用xvfb-run node server.js来启动服务。 - macOS用户:首次运行Playwright的Chromium时,可能会被Gatekeeper拦截。去“系统设置”>“隐私与安全性”里,找到拦截提示,点击“允许”即可。
- Windows用户:建议使用PowerShell或Windows Terminal进行操作。如果遇到
npx命令无法识别,请检查Node.js安装时是否勾选了“添加到环境变量”,或者尝试重启终端。
3.2 首次运行与登录认证
这是最关键的一步,只需要做一次:
node server.js运行这个命令后,你会看到一个Chromium浏览器窗口自动打开,并跳转到claude.ai的登录页面。请在此使用你的Claude账号和密码完成登录。登录成功后,你的会话信息(Cookies等)会被保存在项目目录下的.browser-profile/文件夹里。以后每次启动服务,都会复用这个会话,无需再次登录。
登录完成后,你可以看到终端里服务器启动成功的日志,显示监听在http://127.0.0.1:3000。此时,这个浏览器窗口不要关闭,让它保持在后台运行。你可以最小化它。
3.3 服务启动与基础测试
项目提供了两个启动脚本:
npm start:推荐使用。它会先运行一遍单元测试,确保核心模块工作正常,然后再启动服务器。npm run dev:直接启动服务器,跳过测试步骤,启动速度更快。
启动后,我们来发个请求测试一下。打开另一个终端窗口,使用curl命令(或者用你熟悉的任何HTTP客户端,如Postman):
# 发送一个非流式请求 curl http://127.0.0.1:3000/v1/chat/completions \ -H "Content-Type: application/json" \ -d '{ "model": "claude-3-opus", # 模型名可以任意指定,这里只是用于标识,不影响实际调用 "messages": [{"role": "user", "content": "用中文介绍一下你自己"}], "stream": false }'如果一切正常,你会收到一个JSON格式的回复,结构几乎和OpenAI API一模一样,其中的content字段就是Claude生成的中文回答。同时,你也能看到浏览器窗口里,Claude正在接收问题并生成回答。
3.4 与OpenClaw的深度集成配置
对于OpenClaw用户来说,集成非常简单。你只需要修改OpenClaw的配置文件(通常是config.yaml或config.yml),将LLM提供商指向本地的OpenAdapter服务。
# 在你的OpenClaw配置文件中 llm: provider: openai # 指定使用OpenAI兼容的API api_base: "http://127.0.0.1:3000/v1" # 指向本地运行的OpenAdapter api_key: "dummy-key-not-used" # API密钥随便填一个非空字符串即可,OpenAdapter不验证这个 model: "claude-sonnet-4.5" # 模型名称可自定义,用于在日志中区分 streaming: true # 建议开启,获得更快的响应体验 temperature: 0.7 # 其他OpenAI支持的参数大多也可以传递配置完成后,重启你的OpenClaw。现在,OpenClaw发出的每一个AI请求,都会通过你本地的OpenAdapter,由你的Claude账号免费处理。这意味着你可以利用Claude强大的模型能力,来驱动OpenClaw的数百个技能,而无需支付任何API费用。
4. 高级功能使用与参数调优
基础功能跑通后,我们可以探索一些更高级的用法,并了解如何调整参数来适应自己的需求。
4.1 流式响应(Server-Sent Events)
流式响应能让你像使用ChatGPT网页版一样,看到答案逐字蹦出来的效果,对于长文本体验很好。OpenAdapter完美支持这一点。
# 发送一个流式请求 curl http://127.0.0.1:3000/v1/chat/completions \ -H "Content-Type: application/json" \ -d '{ "messages": [{"role": "user", "content": "写一篇关于量子计算的简短科普文章"}], "stream": true }'你会看到一系列以data:开头的行被实时推送出来。在编程中,你可以使用像openaiSDK这样的库,它天然支持流式响应,代码几乎不用改,只需将base_url指向你的OpenAdapter服务地址即可。
4.2 多模态输入:图片与文件上传
这是非常实用的功能。OpenAdapter支持OpenAI的多模态消息格式,可以将图片以Base64编码的形式发送给Claude进行识别。
# 假设你有一张图片的base64编码字符串(很长,这里用...代替) IMAGE_BASE64="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8/5+hHgAHggJ/PchI7wAAAABJRU5ErkJggg==" curl http://127.0.0.1:3000/v1/chat/completions \ -H "Content-Type: application/json" \ -d '{ "messages": [{ "role": "user", "content": [ {"type": "text", "text": "请描述这张图片的内容"}, { "type": "image_url", "image_url": { "url": "'"${IMAGE_BASE64}"'" } } ] }] }'在实际编程中,你可以用Python的base64库来编码本地图片。OpenAdapter收到请求后,会将Base64数据解码并保存为临时文件,然后通过Playwright自动点击Claude网页上的文件上传按钮,完成附件添加。
4.3 核心配置参数详解
你可以通过环境变量来调整服务器的行为,以适应不同的网络环境或硬件条件。修改方式是在启动命令前设置,或者创建.env文件。
| 环境变量 | 默认值 | 说明与调优建议 |
|---|---|---|
PORT | 3000 | 服务器监听的端口。如果3000被占用,可以设为其他值,如PORT=8080 npm start。 |
MAX_TIMEOUT_MS | 180000 (3分钟) | 等待Claude响应的最长时间。如果网络慢或问题复杂,Claude思考时间可能很长,可以适当调大此值,如MAX_TIMEOUT_MS=300000。 |
STABLE_INTERVAL_MS | 30000 (30秒) | 关键参数。判定Claude“回答完毕”的标准:当连续多少毫秒内回复内容没有变化,就认为生成结束。对于简单问题,可以调小(如10000)以更快返回;对于Claude正在“长考”的复杂问题,调大此值可以避免提前截断。 |
POLL_MS | 500 | 轮询DOM检查是否有新内容的间隔(毫秒)。调小可以更快捕获到新生成的文字,但会增加CPU负担。一般保持默认即可。 |
SESSION_TIMEOUT_MS | 3600000 (1小时) | 浏览器会话无操作后的超时时间。超时后,下一个请求会触发新建一个聊天。如果你希望长期保持一个对话上下文,可以设得非常大(如SESSION_TIMEOUT_MS=86400000代表1天)。 |
4.4 独立CLI工具的使用
除了作为常驻服务器,项目还提供了一个独立的命令行工具adapter.js。它适用于一次性查询,用完即退出,不保持服务器运行。
# 直接提问 node adapter.js "巴黎和柏林之间有多少公里?" # 输出会直接打印到控制台。状态信息(如“正在启动浏览器”)会输出到标准错误(stderr),所以你可以方便地过滤结果。 node adapter.js "列出当前目录下的文件" | grep -E "\.(js|json|md)$"这个CLI工具的参数可以通过环境变量调整,例如MAX_TIMEOUT_MS、CLAUDE_URL等,适合集成到Shell脚本中。
5. 实战问题排查与维护心得
在实际使用中,你肯定会遇到一些问题。下面是我在长期使用和测试中总结出的常见问题及解决方法,这可能是比官方文档更实用的部分。
5.1 常见错误与解决方案速查表
| 问题现象 | 可能原因 | 排查与解决步骤 | ||
|---|---|---|---|---|
启动时报错:Prompt input element not found或sendButton not found | Claude网页UI改版了。这是最常见的问题。OpenAdapter依靠CSS选择器来定位页面上的输入框、发送按钮等元素。 | 1. 手动打开claude.ai,登录后进入聊天界面。2. 按F12打开开发者工具,使用元素选择器(箭头图标)点击输入框。 3. 在开发者工具中查看该元素的高亮代码,寻找唯一且稳定的属性,如 >浏览器打开后,一直停留在Cloudflare验证页面 | Playwright被检测为无头浏览器。虽然OpenAdapter默认以“有头”模式运行,但某些环境下仍可能触发Cloudflare防护。 | 绝对不要在配置中设置headless: true。确保sessionManager.js中创建浏览器上下文时,headless选项为false。如果问题依旧,可以尝试在启动命令前设置DEBUG=pw:api查看Playwright的详细日志。 |
| 登录状态无法保持,每次都要重新登录 | 浏览器用户数据目录(.browser-profile/)权限问题或被意外清理。 | 1. 检查.browser-profile/目录是否存在且可写。2. 确保没有其他进程(如杀毒软件)在清理浏览器缓存。 3. 尝试删除 .browser-profile/目录,然后完全重启服务并重新登录一次。 | ||
| 请求长时间无响应,最终超时 | 1. Claude服务器响应慢或宕机。 2. 网络问题。 3. STABLE_INTERVAL_MS设置过小,Claude还在“打字”就被判定结束,但后续又检测到新内容,陷入循环。 | 1. 先手动访问claude.ai网页,看是否正常。2. 查看服务器日志 logs.txt,看请求是否已发出,卡在哪个阶段。3. 适当增加 MAX_TIMEOUT_MS和STABLE_INTERVAL_MS的值。对于复杂任务,我通常将STABLE_INTERVAL_MS设为60000(1分钟)。 | ||
收到429 Too Many Requests错误 | 触发了Claude网页端的速率限制。免费用户有每分钟/每小时的消息条数限制。 | 这是来自Claude官方的限制,OpenAdapter只是检测并转发。错误信息中通常会包含Retry-After头,指示需要等待多少秒。你的调用程序需要处理这个错误并等待。经验之谈:避免以脚本方式高频、自动化地发送请求,模拟人类的使用间隔更安全。 | ||
| 服务启动失败,提示无法启动浏览器 | 1. Playwright的Chromium未正确安装。 2. 系统缺少依赖(常见于Linux)。 3. 端口被占用。 | 1. 重新运行npx playwright install chromium。2. Linux系统运行 sudo npx playwright install-deps chromium。3. 换一个端口启动: PORT=3001 node server.js。 |
5.2 性能优化与稳定性提升技巧
会话管理策略:默认的1小时会话超时对于轻度使用是合适的。但如果你开发一个需要频繁调用的工具,可以考虑将
SESSION_TIMEOUT_MS设置得更长,甚至禁用自动超时(设为0或极大值),然后定期(比如每处理50个请求)在代码中主动调用sessionManager的newChat()方法来开启一个新对话,避免单个对话历史过长导致页面性能下降。监控与日志:项目会自动生成
logs.txt文件,记录所有请求和响应。建议定期清理,或者配置日志轮转,避免文件过大。你可以修改server.js中的日志逻辑,将其接入更专业的日志系统(如Winston),方便监控错误率和响应时间。选择器维护:Claude的UI并非一成不变。建议你将
SELECTOR_CHAINS提取到一个单独的配置文件(如selectors.json)中,这样更新时更方便。同时,可以编写一个简单的测试脚本,定期用这些选择器去尝试定位元素,一旦失败就发出告警,实现“防患于未然”。资源清理:OpenAdapter会将用户上传的图片等文件暂存在
temp_uploads/目录。虽然服务器会在响应后尝试清理,但异常情况下可能会有残留。可以写一个定时任务(Cron job)来定期清理该目录下超过一定时间(如1小时)的文件。
5.3 关于“无头模式”的深度探讨
项目明确强调“必须要有图形界面”(No headless mode due to Cloudflare)。这是因为Cloudflare等反机器人服务能通过一系列指纹(如WebGL、字体、屏幕分辨率等)检测出你是否在使用真正的浏览器。纯无头模式(Headless)很容易被识别并拦截。
那有没有办法在服务器上运行呢?有,但需要一点技巧:
- 使用Xvfb:这是一个在内存中创建虚拟显示器的服务。在Linux服务器上,你可以先安装Xvfb(
sudo apt install xvfb),然后用xvfb-run命令来启动OpenAdapter:xvfb-run --auto-servernum --server-args="-screen 0 1280x1024x24" node server.js。这样,Playwright就有一个“虚拟的”图形界面可以用了。 - 使用Docker:社区有贡献者提供了Docker方案,其原理也是在容器内运行Xvfb。这对于部署在云服务器上非常方便。
不过,即使使用了Xvfb,它依然是一种“有头”模式,只是这个“头”是虚拟的。其资源消耗和稳定性相比真正的无头模式还是要高一些。
6. 项目扩展与二次开发思路
OpenAdapter本身结构清晰,模块化做得很好,这为二次开发提供了便利。如果你有特定的需求,可以在此基础上进行改造。
6.1 支持更多模型或网站
目前的架构是专门为Claude.ai设计的。但其核心思想——用Playwright模拟操作,将网页响应转为API——可以复用到其他不提供API或API昂贵的AI服务上,比如某些国内的LLM网页版。
你需要修改的主要是以下几个部分:
- 目标网址与登录:修改
sessionManager.js中的初始导航URL和登录逻辑。 - UI选择器:重新分析目标网站的DOM结构,更新
SELECTOR_CHAINS,定位输入框、发送按钮、回复区域等。 - 响应解析器:重写或调整
htmlToMd.js,因为不同网站的回复HTML结构千差万别。 - 速率限制检测:修改
rateLimiter.js中的检测模式,以匹配目标网站的限制提示。
6.2 实现工具调用(Function Calling)支持
这是当前社区呼声最高的功能(在项目的Roadmap上标记为v1.2)。OpenAI的API支持工具调用,允许模型请求执行某个函数(如查询天气、搜索数据库)。Claude网页版也支持上传文件并执行代码解释等操作,但这与标准的工具调用协议不同。
要实现它,思路可以是:
- 在OpenAI格式的请求中解析
tools参数。 - 将工具的描述和参数,以特定的提示词格式(例如,用XML标签包裹)整合到发送给Claude的用户消息中。
- 在Claude的回复中,通过模式匹配(如正则表达式)来识别模型“想要调用工具”的意图和参数。
- 在本地执行对应的函数,并将执行结果再次作为上下文发送给Claude。
这需要设计一套精巧的提示词工程和结果解析机制,是进阶开发的一个绝佳方向。
6.3 构建更健壮的生产级服务
如果你想将OpenAdapter用于更严肃的生产环境,可以考虑以下增强:
- 并发队列:目前服务是单请求处理。可以引入一个队列系统(如Bull),将接收到的请求排队,按顺序处理,并给客户端返回一个任务ID,通过WebSocket或轮询告知结果。
- 多账号池:管理多个Claude账号的浏览器会话,通过轮询或负载均衡来分发请求,可以有效绕过单个账号的速率限制。
- 健康检查与自动重启:编写一个监控脚本,定期向服务的
/health端点(需要自己实现)发送请求,如果失败,则自动重启server.js进程。可以使用PM2等进程管理工具。 - 配置化管理:将所有的环境变量、选择器、超时参数都集中到一个配置文件(如
config.yaml)中,便于管理和部署。
这个项目就像一个精巧的“转换插头”,将开放的网页能力转换成了标准的编程接口。它的价值不仅在于“免费”,更在于提供了一种思路:当官方API路径受限时,前端自动化是一条值得探索的迂回之路。当然,这条路需要你付出维护成本,尤其是面对频繁的UI变更时。但考虑到它带来的灵活性和零成本优势,对于开发者、研究者和重度AI工具用户来说,这份投入无疑是值得的。
