自动操作 lmarena 免费的 Claude 大模型 - React 前端自动化控制实例

boyanx4个月前技术教程14

大模型竞技场 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();

相关文章

OneCode设计器协议栈名词解析及标准概念适配

前言以下是基于 OneCode 技术体系,对标准协议内容进行适配性转换与解读(因 OneCode 有其自身生态规范,会结合其常见概念和流程调整表述,部分需结合 OneCode 实际框架灵活落地 ):一...

原生JS实现多标签页数据共享:优雅且高效

在现代Web开发中,多标签页之间的数据共享是一个常见的需求。无论是实现多页面之间的实时通信,还是同步用户状态,都能极大地提升用户体验。然而,传统的实现方式往往需要借助复杂的框架或第三方库。今天,我们将...

Lit简介:基于标准的反应库(反应标准的标杆是)

  Lit基于Mozilla的Web组件标准,以提供简单、合规的反应前端。在一个技术替代品庞大的世界里,它可能会提供一条明确的前进道路。  在用于被动编程的前端JavaScript框架中,Lit是一个...

使用uniapp开发小程序遇到的一些问题及解决方法

1、swiper组件自定义知识点swiper组件的指示点默认是圆圈,想要自己设置指示点,需要获得当前索引,然后赋给当前索引不同的样式,然后在做个动画就可以了。*关键点用change方法,然后通过e.d...

阿东编程系列:APP使用用户名、密码和图片验证码进行登录

本期内容登录过程较为常见和简单,不再以视频的方式呈现(如果确实有需要,小伙伴可以发私信告知,到时候再录制视频)。这里给大家贴出代码和图片,方便小伙伴们去完成。1.APP端基于uni-app的登录页代...

react native使用ant design表单相互嵌套的问题

在React Native中使用Ant Design的Form组件进行表单提交时,如果在一个Form表单内嵌套了另一个Form表单,并且这两个表单位于父子组件之间,并且第二个嵌套的表单有一个提交按钮,...

发表评论    

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。