aardio 官方社区

 找回密码
 注册会员

QQ登录

只需一步,快速开始

搜索
查看: 23430|回复: 14

chrome.driver, chrome.app 系列范例

[复制链接]

170

主题

2187

回帖

1万

积分

管理员

积分
13251
发表于 2018-6-7 23:56:50 | 显示全部楼层 |阅读模式
参考帖子:aardio几句代码实现 WebDriver 协议客户端
http://bbs.aardio.com/forum.php?mod=viewthread&tid=22543

现在我又进一步封装了一个库,
大家知道Chrome每个版本的适用ChromeDriver版本都不一样,
安装不同的Chrome就要去下载不同的ChromeDriver.exe,而且还要命令行启动,绑定固定端口一搞不好还会跟别的进程冲突了。

现在用aardio 最新版中提供的 chrome.driver 所有麻烦都可以解决了,
chrome.driver 会自动查找Chrome的安装位置、版本号,自动匹配最合适的ChromeDriver版本,并且负责自动下载安装,自动分配空闲端口,所有事情全自动准备好,只要运行下面的代码就可以了。

现在看代码,用法非常简单:
//WebDriver自动化

import chrome.driver;

//创建chromeDriver对象,协议文档 https://github.com/SeleniumHQ/selenium/wiki/JsonWireProtocol
var driver = chrome.driver();

//创建会话,打开chrome浏览器,Chrome新版会强制显示控制台
var browser = driver.startBrowser();

//打开网页
browser.go("http://www.so.com")

//查找文本输入框
var ele = browser.querySelector("#input");

//在网页输入框输入内容
ele.setValue( "ChromeDriver" )

//模拟点击按钮
browser.querySelector("#search-button").click();

下面的问题在新版中已解决,可忽略:
注意 Chrome新版会强制显示控制台( 隐藏也会强行弹出黑窗口,旧版可以隐藏这个黑窗口  ),
如果想隐藏黑窗口,那么可以用旧版Chrome,在创建 chrome.driver对象时可以在参数中自定义chrome.exe的路径。



170

主题

2187

回帖

1万

积分

管理员

积分
13251
 楼主| 发表于 2018-6-8 10:59:49 | 显示全部楼层
在electron.app中调用ChromeDriver:
import win.ui;
/*DSG{{*/
var winform = win.form(text="在electron.app中调用ChromeDriver";right=1276;bottom=767;clipch=1)
winform.add()
/*}}*/

import electron.app;  
var theApp = electron.app(winform);
theApp.jsMain =
/**
    const aardio = require('aardio');
    const app = require('electron').app;
   
    app.on('window-all-closed', () => {
        app.quit();
    })
**/


// 打开调试端口,这样chromeDriver才能连接
theApp.remoteDebuggingPort = 0;
theApp.start()  
winform.show()  

// 这里一定要用多线程,chrome.driver会阻塞当前线程
thread.invoke(
   
function(chromePath,remoteDebuggingPort){
        
import chrome.driver;
        
var driver = chrome.driver(chromePath)
        
var browser = driver.attach(remoteDebuggingPort)
        
        
// 打开网页
        browser.go("http://www.so.com")
        
        
// 查找文本输入框
        var ele = browser.querySelector("#input");
        
        
// 在网页输入框输入内容
        ele.setValue( "ChromeDriver" )
        
        
// 模拟点击按钮
        browser.querySelector("#search-button").click();
    },theApp.chromePath,theApp.remoteDebuggingPort
)

win.loopMessage();


170

主题

2187

回帖

1万

积分

管理员

积分
13251
 楼主| 发表于 2018-6-8 16:05:13 | 显示全部楼层
import chrome.driver;

var driver = chrome.driver();

driver.addArguments(
"--user-agent=mychrome")

//打开网页
driver.startBrowser().go("http://www.ip138.com/useragent/")


chrome启动参数大全:
https://peter.sh/experiments/chromium-command-line-switches/

170

主题

2187

回帖

1万

积分

管理员

积分
13251
 楼主| 发表于 2018-6-8 16:06:21 | 显示全部楼层
import chrome.driver;

var driver = chrome.driver();

driver.setProxy(
    proxyType =
"manual";
    httpProxy =
"127.0.0.1:12043"
)

也可以下面这样写
import chrome.driver;

var driver = chrome.driver();

var browser = driver.startBrowser(
    proxy ={
        proxyType =
"manual";
        httpProxy =
"127.0.0.1:12043"
    }
);


170

主题

2187

回帖

1万

积分

管理员

积分
13251
 楼主| 发表于 2018-6-8 16:08:39 | 显示全部楼层

import chrome.driver;

var driver = chrome.driver();

//启动浏览器
browser = driver.startBrowser();

//打开网页
browser.go("http://www.so.com")

//查询元素,并且使用元素的querySelector函数查询子元素
browser.querySelector("body").querySelector("#input").setValue( "ChromeDriver" )

//模拟点击按钮
browser.querySelector("#search-button").click()

170

主题

2187

回帖

1万

积分

管理员

积分
13251
 楼主| 发表于 2018-6-8 23:48:47 | 显示全部楼层
网上一些讨论认为这个问题无解,WebDriver也没有找到相关参数,
直觉这个可能在启动参数里打开控制台,于是我写了一个假的 chrome.exe,再用 ChromeDriver.exe 调用他,代码如下:
import console;
import win.clip

win.clip.write(_CMDLINE)
console.log(_CMDLINE);

console.pause();
chrome.exe获得的启动参数如下:
--disable-background-networking --disable-client-side-phishing-detection --disable-default-apps --disable-hang-monitor --disable-popup-blocking --disable-prompt-on-repost --disable-sync --disable-web-resources --enable-automation --enable-logging --force-fieldtrials=SiteIsolationExtensions/Control --ignore-certificate-errors --load-extension="C:\Users\***\AppData\Local\Temp\***\internal" --log-level=0 --metrics-recording-only --no-first-run --password-store=basic --remote-debugging-port=0 --test-type=webdriver --use-mock-keychain --user-data-dir="C:\Users\***\AppData\Local\Temp\***" data:,
我们看到可疑参数--enable-logging,
进一步测试发现:排除这个参数就可以关闭新版chrome启动跳出来的控制台窗口了,示例代码:
import chrome.driver;

var driver = chrome.driver( );
driver.setOptions(
    excludeSwitches ={
"enable-logging"} //注意这里参数前千万不要加 --
)

driver.addArguments("--app=http://www.aardio.com")
var browser = driver.startBrowser();

已更新 chrome.driver 默认禁用控制台窗口,
但仍然可以使用 driver.addArguments("--enable-logging") 启用这个参数。

170

主题

2187

回帖

1万

积分

管理员

积分
13251
 楼主| 发表于 2018-6-9 05:52:38 | 显示全部楼层
aardio新版经过大力改进,
现在 chrome.app, chrome.driver 已经可以相互结合使用,chrome与aardio交互更加简单方便。
下面是一个简单的例子:
import chrome.app;
var app = chrome.app();

import chrome.driver;
var driver = chrome.driver();

//指定允许chrome中使用JS直接调用的函数
app.external = {
   
    test =
function(){
       app.msgbox(
"页面js调用了aardio函数");
    }
}

//正式的启动chrome进程
app.start("http://www.aardio.com",function(args){
   
   
//启动浏览器,加载aardio.js,并打开ChromeDriver自动化接口
    var browser = driver.startAppBrowser(app,args);
   
   
//执行JS脚本
    browser.doScript(`
        document.addEventListener("click", function(event) {
            aardio.test();
        });
    `
)
   
   
return browser;
});


win.loopMessage();


win.loopMessage();




170

主题

2187

回帖

1万

积分

管理员

积分
13251
 楼主| 发表于 2018-6-10 14:26:01 | 显示全部楼层
方法一:
import chrome.driver;
var driver = chrome.driver();
driver.removeArguments(
"--enable-automation")

虽然不显示上面的提示了,但是弹出一个更大的警告。

方法二:
import chrome.driver;
var driver = chrome.driver();
driver.addArguments(
"--disable-infobars");
不显示上面的提示,也没有警告了,但是可以看到提示框显示然后快速的关掉,会闪烁一下。

方法三:
import chrome.driver;
var driver = chrome.driver();
driver.addArguments(
"--app=http://www.so.com/index.html");
用--app模式的方法完美,地址栏、提示框、警告都去掉了,
但是有一个奇怪的事情是,启动网址要写成 http://www.so.com/index.html 这样,如果不写 index.html 有时候会白屏,但不是每个网站都这样。

170

主题

2187

回帖

1万

积分

管理员

积分
13251
 楼主| 发表于 2018-6-10 14:47:05 | 显示全部楼层
Chrome每个进程只能绑定单独的用户目录 - 才能创建单独的远程调试端口,
ChromeDriver 的办法是每次都创建一个临时的用户目录,然后每次都创建新的临时用户目录,而且又不负责删除(其实可以设置为重启系统自动删除,不知道Chrome为什么没有这么做),所以我们只好自己清理了,代码如下:
import console;
import fsys;
fsys.enum( fsys.getTempDir(),
"scoped_dir*_*",
   
function(dir,filename,fullpath,findData){
        
if(!filename){
            
if( ..io.exist( io.joinpath(fullpath,"DevToolsActivePort") ) ){
                fsys.delete(fullpath)
            }
            
if( ..io.exist( io.joinpath(fullpath,"internal.zip") ) ){
                fsys.delete(fullpath)
            }
        }
    },
false
);

console.pause(
true);


1

主题

4

回帖

1万

积分

八级会员

积分
11452
发表于 2018-6-11 15:47:46 | 显示全部楼层
最近在使用过程中,发现改动HTML文件后chrome或electron不会及时更新,搜索折腾了好几天,尝试加入启动参数也不起作用。后面发现在HTML文件页头加入如下几行就可以了。

  1. <meta http-equiv="Expires" content="0">
  2. <meta http-equiv="Pragma" content="no-cache">
  3. <meta http-equiv="Cache-control" content="no-cache">
  4. <meta http-equiv="Cache" content="no-cache">
复制代码

1

主题

4

回帖

1万

积分

八级会员

积分
11452
发表于 2018-6-12 16:03:02 | 显示全部楼层
hsyzxj520 发表于 2018-6-11 15:47
最近在使用过程中,发现改动HTML文件后chrome或electron不会及时更新,搜索折腾了好几天,尝试加入启动参数 ...

发现一个更简单的方法:
工程目录/electron.app目录下有个main-runtime.js。这个是主进程文件,在“const app = require('electron').app”下一行插入“app.commandLine.appendSwitch("--disable-http-cache")”就可以了。
当然也可以使用electron的“app.getPath('userData') + '/Cache'”方法手动清除页面缓存或者GPU缓存

170

主题

2187

回帖

1万

积分

管理员

积分
13251
 楼主| 发表于 2018-6-12 16:16:38 | 显示全部楼层
hsyzxj520 发表于 2018-6-12 16:03
发现一个更简单的方法:
工程目录/electron.app目录下有个main-runtime.js。这个是主进程文件,在“cons ...
app.start({
    indexUrl = "/res/index.aardio";
   
   
/*启动参数,可以不指定*/
    args = {
        [
"--disable-http-cache"] =""
    };
})
启动的时候就可以指定启动参数

0

主题

5

回帖

46

积分

新手入门

积分
46
发表于 2018-6-25 22:57:34 | 显示全部楼层
太好了,学习了好多东东

1

主题

1

回帖

16

积分

新手入门

积分
16
发表于 2018-6-29 08:25:29 | 显示全部楼层
import chrome.driver;
//创建chromeDriver对象,协议文档 https://github.com/SeleniumHQ/selenium/wiki/JsonWireProtocol
var driver = chrome.driver();
//创建会话,打开chrome浏览器,Chrome新版会强制显示控制台
var browser = driver.startBrowser();
//打开网页
browser.go("http://www.qq.com")

当浏览网页新开多个标签页,怎么来回切换页面窗口并控制呢?
试过下面代码不成功,
for(k in browser.window.handles.get().value){
        browser.window(browser.window.handles.get().value[k])
        browser.go("www.baidu.com")
}

关于chromedriver的提示代码就
window.get() = 获取当前窗口\nHTTP接口:GET /session/{session id}/window
window.delete() = 关闭当前窗口\nDELETE        /session/{session id}/window
window(__) = 切换窗口\nHTTP接口:POST /session/{session id}/window
window.handles.get() = 获取所有窗口句柄\nHTTP接口:GET /session/{session id}/window/handles

Jacen,请教下 window()切换窗口 怎么使用才是正确呢?

170

主题

2187

回帖

1万

积分

管理员

积分
13251
 楼主| 发表于 2018-8-5 16:25:15 | 显示全部楼层
hwd 发表于 2018-6-29 08:25
import chrome.driver;
//创建chromeDriver对象,协议文档 https://github.com/SeleniumHQ/selenium/wiki/J ...
关于这个问题,
其实WebDriver的文档里已经写的很清楚了
window.post() 就可以切换窗口( POST /session/:sessionId/window ) 。

因为我封装的第三方组件比较多,大多时候我只关注与aardio交互的部分,不关注这些第三方组件的具体用法,所以我建议大家以后遇到这类第三方组件的问题,先去看第三方组件的文档和例子,例如ChromeDriver的问题尽可能先找ChromeDriver的文档看看。

为了切换窗口可以更省事一些,新版  chrome.driver 我添加了几个辅助函数用法演示。
import chrome.driver;

//创建chromeDriver对象
var driver = chrome.driver();
var browser = driver.startBrowser();
browser.go(
"http://www.so.com")

//弹出新窗口
browser.doScript( `
    window.open("http://www.aardio.com");
`
)

//遍历所有窗口
for( index,window,title,url in browser.eachWindow() ){
   
   
//根据窗口标题查找窗口
    if( string.find(title,"aardio") ){
        
        
//因为当前已切换窗口,所以可以直接使用其他函数操作该窗口
        browser.go("http://www.baidu.com")
    }
};


您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

手机版|未经许可严禁引用或转载本站文章|aardio.com|aardio 官方社区 ( 皖ICP备09012014号 )

GMT+8, 2023-6-10 08:17 , Processed in 0.063958 second(s), 26 queries .

Powered by Discuz! X3.5

Copyright © 2001-2023 Tencent Cloud.

快速回复 返回顶部 返回列表