摘要:大模型竞技场 lmarena.ai 最近发布了基于 React 的新版本、用户体验更友好了。lmarena 上几乎所有的前沿商业大模型都可以免费使用。有些大模型自己的网站一会是不让你用一会是封你号一会是你不在服务区,相比起来 lmarena 上几乎没有什么太大
大模型竞技场 lmarena.ai 最近发布了基于 React 的新版本、用户体验更友好了。lmarena 上几乎所有的前沿商业大模型都可以免费使用。有些大模型自己的网站一会是不让你用一会是封你号一会是你不在服务区,相比起来 lmarena 上几乎没有什么太大的限制。
现在 React 开发的网站越来越多,今天我们就将 lmarena.AI 作为一个实例,演示一下如何自动化操作这样的网页。
我们需要实现:
自动打开 lmarena.ai 并自动切换到对话界面。自动输入指定的大模型名称,并自动切换到该模型。自动输入一个或多个事先准备好的提示词。如果有好几个几万字的提示词,手动输入估计会很累的。最后自动滚动到底部等待提问。需要注意的,类似 Reat 这样的现代化前端框架,有着复杂的数据同步机制。用 JS 代码
document.querySelector(`input`).value = "输入值"这样直接修改值是没有反应的,当然,要解决这个问题也非常简单。下面请一步步跟我学,要不了几分钟你就能学会了。
首先我们讲一下如何判断网站是不是用 React 开发的,如果你不想安装 React 的扩展,一个简单的方法是打开浏览器的 devtools ,在 console 里里输入 document.body._ 前缀就可以看到 React 特有的一些属性:
document.body.__reactFiber$ ......如图:
如果是 React 控制的输入组件,还会有 _valueTracker 这个属性,要想改变输入框的值关键就是这个 _valueTracker 了。
为了快速创建立即可用的程序,减少部署与开发的过程,我们使用快速开发桌面应用的 aardio ,新建一个空白窗口程序,输入下面的代码:
import win.ui;/*DSG{{*/var winform = win.form(text="lmarena.ai")/*}}*/import web.view; var wb = web.view(winform);winform.show(3);//打开网页wb.go("https://lmarena.ai/?mode=direct");win.loopMessage;一个简单的程序就写好了,按 F5 可以就可以运行,我们使用操作系统自带的强大 WebView2 控件打开了 lmarena.ai ,并通过 URL 参数切换到了 AI 对话页面。
React 这种 JS 框架会使用 JS 动态创建页面内容,所以用传统的方法去等待页面加载完成了, React 组件可能还未创建。不过在 aardio 里做这种事很容易,我们在打开网页的 wb.go 调用后面添加代码如下:
wb.go("https://lmarena.ai/?mode=direct");//跨页面等待指定节点wb.waitEle2(`button[role="combobox"][data-sentry-source-file="select-model.tsx"]`);//稍等 1 秒thread.delay(1000)//找到节点并模拟点击之wb.waitEle(`button[role="combobox"][data-sentry-source-file="select-model.tsx"]`,`this.click`)我们首先等待网页创建好大模型下拉列表,要点:
wb.waitEle2 与 wb.waitEle 的第一个参数都是用于选择 HTML 元素的 CSS 选择器,打不到他就一直等,找到了就回调第 2 个参数里指定的 JS 代码或者 aardio 回调函数。回调 JS 时 this 对象就表示找到的 HTML 元素。
wb.waitEle2 可以跨 URL 等待,而 wb.waitEle 仅在当前 URL 下面等待。因为网页在打开前可能会跳转,所以第一次用 wb.waitEle2 ,后面就不需要了。
执行上面的代码以后,程序自动打开了网页,并点击展开了模型列表,只有展开模型列表才会出现输入框组件,不然代码是找不到输入框的。
下面继续添加代码自动选择 claude 4 这个模型:
//让网页获得输入焦点wb.focus//获取弹出的 React 下拉框,模拟输入并改变 React 状态值。wb.waitEle(`input[placeholder="Search models"]`,` var previousValue = this.value;this.value = "claude-sonnet-4-20250514";if(this._valueTracker)this._valueTracker.setValue(previousValue);//发送事件this.dispatchEvent(new Event('change', { bubbles: true })); //这个一直不关的提醒还是删掉吧document.querySelector('div[data-sentry-source-file="nag-bar.tsx"]').outerHTML = "";//调用本地代码发送回车aardio.sendEnter;`);我们可以看到上面的代码通过 _valueTracker 成功改变了 React 组件的值。
但是最后确认输入这一步,我用 aardio 直接给浏览器控件添加了一个本地函数如下:
wb.external = { sendEnter = function{ import key key.press("BACK") key.press("ENTER") } }用 aardio 干活要简单得多,不用去研究 React 的复杂机制了。
后续我们希望自动加载一些文件并填入 AI 提示词,原理跟上面一样,自动输入提示词的 aardio 代码如下:
wb.waitEle(`textarea[placeholder="Ask anything…"]`,`var previousValue = this.value;aardio.getSystemPrompt.then( prompt => { this.value = prompt; if(this._valueTracker)this._valueTracker.setValue(previousValue); this.dispatchEvent(new Event('click', { bubbles: true })); this.dispatchEvent(new Event('mouseup', { bubbles: true })); this.dispatchEvent(new Event('focus', { bubbles: true })); this.dispatchEvent(new Event('input', { bubbles: true })); this.dispatchEvent(new Event('change', { bubbles: true })); this.dispatchEvent(new Event('click', { bubbles: true })); this.dispatchEvent(new Event('mouseup', { bubbles: true })); this.dispatchEvent(new Event('blur', { bubbles: true })); this.scrollTop = this.scrollHeight; }) `);这里我又使用 aardio 为浏览器添加了一个本地函数 getSystemPrompt 用于加载本地文件到网页。
测试了一下,用这个小工具再去问 Claude 4 关于 aardio 的编程问题,技能立即暴升几十倍。你还可以再加上自动 AI 搜索(就几句代码的事,请查看 aardio 文档),那就更好用了。
不过要效果最好的还是使用 aardio 提供的专用接口,完整接入 aardio 知识库以后哪怕是一般的大模型 aardio 编程技能都会提升百倍。一个好的知识库是非常重要的。
不过要效果最好的还是使用 aardio 提供的专用接口,完整接入 aardio 知识库以后哪怕是一般的大模型 aardio 编程技能都会提升百倍。一个好的知识库是非常重要的。其实什么 AI 幻觉就是因为他缺乏相关领域的准确知识细节,知道一半所以只好虚构另一半。说实话我现在对大模型升级刷存在感已经不怎么关心了,升来升去就那样,已经很难突破瓶颈了,要想真正解决问题还是要自己整好知识库。
本文示例程序的完整源码如下(在 aardio 里粘贴下面的源码,可以一键发布为体积很小的独立 EXE 程序):
import win.ui;/*DSG{{*/var winform = win.form(text="lmarena.ai")/*}}*/import web.view; var wb = web.view(winform);winform.show(3/*_SW_SHOWMAXIMIZED*/);wb.external = { sendEnter = function{ import key key.press("BACK") key.press("ENTER") } getSystemPrompt = function{ return string.load("~\doc\guide\ide\system-prompt.md") +'\n\n------\n\n' + string.load("~\doc\guide\language\syntax-quick-ref.md") +'\n\n------\n\n' } }wb.go("https://lmarena.ai/?mode=direct");//跨页面等待指定节点wb.waitEle2(`button[role="combobox"][data-sentry-source-file="select-model.tsx"]`);//稍等 1 秒thread.delay(1000)//找到节点并模拟点击之wb.waitEle(`button[role="combobox"][data-sentry-source-file="select-model.tsx"]`,`this.click`) //让网页获得输入焦点wb.focus//获取弹出的 React 下拉框,模拟输入并改变 React 状态值。wb.waitEle(`input[placeholder="Search models"]`,` var previousValue = this.value;this.value = "claude-sonnet-4-20250514";if(this._valueTracker)this._valueTracker.setValue(previousValue);//发送事件this.dispatchEvent(new Event('change', { bubbles: true })); //这个一直不关的提醒还是删掉吧document.querySelector('div[data-sentry-source-file="nag-bar.tsx"]').outerHTML = "";//调用本地代码发送回车aardio.sendEnter;`); wb.waitEle(`textarea[placeholder="Ask anything…"]`,`var previousValue = this.value;aardio.getSystemPrompt.then( prompt => { this.value = prompt; if(this._valueTracker)this._valueTracker.setValue(previousValue); this.dispatchEvent(new Event('click', { bubbles: true })); this.dispatchEvent(new Event('mouseup', { bubbles: true })); this.dispatchEvent(new Event('focus', { bubbles: true })); this.dispatchEvent(new Event('input', { bubbles: true })); this.dispatchEvent(new Event('change', { bubbles: true })); this.dispatchEvent(new Event('click', { bubbles: true })); this.dispatchEvent(new Event('mouseup', { bubbles: true })); this.dispatchEvent(new Event('blur', { bubbles: true })); this.scrollTop = this.scrollHeight; }) `); win.loopMessage;来源:aardio