[aardio] 使用开发工具协议控制谷歌浏览器
本帖最后由 sas 于 2022-7-2 21:55 编辑本帖子的代码基于此扩展库 https://github.com/btx638/aaz-aardio,下载后把 aaz 目录放到 aardio 的 lib 目录,就可以运行帖子的代码
国内备份仓库 https://gitcode.net/vmax666/aaz-aardio
chrome 开发工具协议:https://chromedevtools.github.io/devtools-protocol/
范例1: 打开 360搜索 ,搜索 52pojie
import win.ui;
/*DSG{{*/
var winform = win.form(text="aardio form";right=385;bottom=140)
winform.add(
button={cls="button";text="运行";left=142;top=43;right=221;bottom=83;z=1}
)
/*}}*/
io.open()
import aaz.chrome.dp;
var cdp, err = aaz.chrome.dp()
if(!cdp){
winform.msgboxErr(err);
return ;
}
// 指定每个步骤的超时, 这里是2万毫秒,就是20秒
cdp.timeout = 20000;
// 定义任务函数
var task = function(){
// 打开浏览器
var ok, err = cdp.open()
if(!ok){
io.print("打开浏览器失败", err);
return ;
}
// 连接浏览器
var ok, err = cdp.connect();
if(!ok){
io.print("连接浏览器失败", err);
return ;
}
// 订阅 Page 事件
var ok, err = cdp.Page.enable();
if(!ok){
io.print("订阅 Page 事件失败", err);
return ;
}
// 打开网址
var ok, err = cdp.Page.navigate(
url = "https://www.so.com";
)
if(!ok){
io.print("打开网址失败", err)
return ;
}
// 等待页面加载完成
var ok, err = cdp.waitEvent( "Page.loadEventFired" );
if(!ok){
io.print("等待页面加载完成失败", err);
return ;
}
// 执行 js 脚本
var ok, err = cdp.Runtime.evaluate(
expression = /**
document.querySelector("#input").value = "52pojie";
document.querySelector("#search-button").click();
**/
)
}
// 点击运行任务函数
winform.button.oncommand = function(id,event){
cdp.run(task)
}
winform.show();
win.loopMessage();
范例2:定义一个等待函数, 可以在任务函数里面使用
// 定义 js 等待函数
var waitJs = /**
const userWait = (ms) => {
return new Promise(resolve => setTimeout(resolve, ms))
}
async function sleepAsync(ms) {
await userWait(ms)
}
**/
// 向网页载入 js 代码
var loadCode = function(js){
return cdp.Runtime.evaluate(
expression = js;
)
}
// 等待函数
var wait = function(ms){
return cdp.Runtime.evaluate(
awaitPromise = true; // 执行是否应该等待结果值,并在等待的承诺被解决后返回。
expression = string.format("sleepAsync(%s)", ms)
)
}
范例3:使用等待函数,用于截图任意网站的完整的首页, 先试试截图淘宝
import win.ui;
/*DSG{{*/
var winform = win.form(text="aardio form";right=623;bottom=103)
winform.add(
btnScreenshot={cls="button";text="截图";left=440;top=16;right=576;bottom=48;z=3};
edUrl={cls="edit";text="https://www.taobao.com/";left=72;top=16;right=424;bottom=48;edge=1;z=2};
static={cls="static";text="网址:";left=24;top=16;right=72;bottom=48;transparent=1;z=1};
static2={cls="static";text="日志:";left=80;top=72;right=288;bottom=88;transparent=1;z=4}
)
/*}}*/
// https://dschnurr.medium.com/usin ... t-tool-4b07dffba79a
// https://blog.csdn.net/z69183787/article/details/91984005
// https://dev.to/gdledsan/selenium ... age-screenthos-2j8d
// https://github.com/puppeteer/pup ... ommon/Page.ts#L2741
import crypt.bin
import process
import aaz.chrome.dp;
var cdp, err = aaz.chrome.dp()
// 定义 js 等待函数
var waitJs = /**
const userWait = (ms) => {
return new Promise(resolve => setTimeout(resolve, ms))
}
async function sleepAsync(ms) {
await userWait(ms)
}
**/
// 向网页载入 js 代码
var loadJsCode = function(js){
return cdp.Runtime.evaluate(
expression = js;
)
}
// 等待函数
var wait = function(ms){
return cdp.Runtime.evaluate(
awaitPromise = true; // 执行是否应该等待结果值,并在等待的承诺被解决后返回。
expression = string.format("sleepAsync(%s)", ms)
)
}
io.open()
var task = function(url){
// 以无头模式启动,就是不显示浏览器的界面
cdp.open(,true)
cdp.connect();
// 订阅 Page 事件,可用于等待页面加载完成
cdp.Page.enable();
// 打开网址
cdp.Page.navigate(
url = url;
)
// 等待页面加载完成
cdp.waitEvent( "Page.loadEventFired" );
// 载入等待js函数
loadJsCode(waitJs)
// 已滚动的总高度
var scrolledDistance = 0;
// 每次滚动高度
var distance = 100;
while(true){
// 滚动一次
cdp.Runtime.evaluate(
expression = string.format(" window.scrollBy(0, %s);", distance);
)
// 记录已滚动的高度
scrolledDistance += distance;
// 滚动条的实际高度
var ret = cdp.Runtime.evaluate(
expression = "document.body.scrollHeight";
returnByValue = true;
)
// 定义一个回调函数,用于输出日志
if(onSroll){
onSroll(scrolledDistance, ret.result.value)
}
// 滚动到底了
if (scrolledDistance >= ret.result.value) {
break;
}
// 等待100毫秒,让网页加载新的内容,如果网络慢可以加大等待时间
wait(100)
}
var rect = cdp.Page.getLayoutMetrics()
// 截图
var ret = cdp.Page.captureScreenshot(
format="jpeg";
captureBeyondViewport = true;
clip = {
x = 0;
y = 0;
scale = 1;
width = rect.cssContentSize.width;
height = rect.cssContentSize.height;
}
)
// 关闭浏览器
cdp.Browser.close();
if(ret){
// 输出解码后的图像数据
return crypt.bin.decodeBase64(ret.data);
}
}
onSroll = function(scrolledDistance, mian){
winform.static2.text = "已滚动距离:" ++ scrolledDistance ++ " 总高度:" ++ mian
}
winform.btnScreenshot.oncommand = function(id,event){
var url = winform.edUrl.text
if(!string.startWith(url, "http")){
winform.msgboxErr("请填写网址")
return ;
}
// 执行任务函数
cdp.run(
task,
// 执行前触发
function(){
winform.btnScreenshot.disabled = true
},
// 执行完毕触发,并收到执行函数的返回值
function(data){
winform.btnScreenshot.disabled = false
if(data){
string.save("\截图.jpg", data)
process.exploreSelect("\截图.jpg")
}
},
url
)
}
winform.show();
win.loopMessage();
return winform;
本帖最后由 wh201906 于 2022-12-16 22:40 编辑
sas 发表于 2022-7-2 16:32
selenium 应该是用开发工具协议封装的, 这个是直接用开发工具协议,没有什么封装
https://chromedevtoo ...
selenium支持的浏览器会更多一些,比如Chrome, IE, Safari, Opera, Firefox这些,所以想了解一下这个aardio是不是有什么其它的亮点 本帖最后由 sas 于 2022-7-2 16:40 编辑
XiaoZouYu 发表于 2022-7-2 16:22
我也是想问问这个问题
selenium 应该是用开发工具协议封装的, 这个是直接用开发工具协议,没有什么封装
https://chromedevtools.github.io/devtools-protocol/ 正好要学习这个技术,就看到楼主的贴子了 标记学习 这个和selenium相比如何呢? wh201906 发表于 2022-7-2 13:57
这个和selenium相比如何呢?
我也是想问问这个问题:Dweeqw 学习了。理解为是用aardio来做网页自动化。 高级的东西
页:
[1]
2