2606,D版selenium

原文

快速入门

SeleniumSDK是一个基于WebDriver协议的浏览器自动化的D库.它与Selenium,Ruby绑定的使用模式类似,API一致,大部分``W3C表面映射为你期望的.

当库与W3C``有所不同时,相关注意事项会在文中记录并说明.

安装

DUB添加包:

cpp 复制代码
dub add selenium-sdk

还需要在路径,PATH上安装WebDriver服务器.库会自动检测你要求的浏览器正确版本.

Browser WebDriverbinary
Chrome chromedriver
Firefox geckodriver
Edge msedgedriver
Safari safaridriver

最快的启动方式,是让库选择路径第一个安装的驱动:

cpp 复制代码
import selenium;
Driver driver = Driver.start();
scope (exit) driver.stop();
driver.go("https://example.com");
writeln(driver.title);

浏览器

浏览器描述了想从会话中得到的能力.基础浏览器是常见的;具体子类增加了供应商能力.构建一个,设置字段,然后交给Driver.start.

类型 浏览器名 额外
浏览器 常见 仅限标准W3C功能.
Chrome chrome 二进制binary,includeSwitches,excludeSwitches,prefs,扩展,记录,extensions,logging.
Firefox Firefox 二进制binary,args,prefs,配置profile.
Edge 微软Edge Chrome选项加上mobileEmulation,WebView2(useWebView).
Safari safari automaticInspection,automaticProfiling,technologyPreview.

标准功能在基础上,适合所有浏览器:

字段 目的
平台platform 请求的主机平台(Platform.Windows,Platform.Linux等).
接受不安全证书acceptInsecureCerts 接受无效的TLS证书.
页加载策略pageLoadStrategy 正常,激进,或没有.
未处理提示行为unhandledPromptBehavior 如何处理突发提示.
超时timeouts 隐式等待,页加载和脚本超时.
cpp 复制代码
import selenium;
import core.time : seconds;
Chrome chrome = new Chrome();
chrome.binary = "/usr/bin/google-chrome";
chrome.includeSwitches = ["--headless=new", "--disable-gpu"];
chrome.timeouts.implicit = 5.seconds;
Driver driver = Driver.start(chrome);
scope (exit) driver.stop();

可按firstMatch列表传递替代,服务器会选择第一个它能满足的:

cpp 复制代码
Driver driver = Driver.start(new Chrome(), [new Firefox()]);

是拥有WebDriver进程或远程连接管理其所有会话低级主机.你一般不会直接触碰它:Driver.start会为你生成一个.

当你想在一个进程运行多个会话,限制并发连接到远程端点时,可选择.

大多数客户不同,驱动和会话在此并非严格一对一.单个桥可服务多个会话,每个驱动都是其中一个会话的句柄.

成员 目的
Bridge.start(binary,args) 空闲端口上生成本地驱动进程.
Bridge.connect(address) 连接到已运行的服务器(远程或栅).
容量capacity 最大并发会话数,或无限会话0.
会话sessions ID为键的活动会话.
stop() 干掉生成进程去掉所有会话.
cpp 复制代码
import selenium;
//在两个会话中共享一个驱动进程.
Bridge bridge = Bridge.start(new Chrome().resolveBinary());
bridge.capacity = 2;
Driver first = Driver.start(bridge, new Chrome(), null);
Driver second = Driver.start(bridge, new Chrome(), null);

Bridge.start创建的拥有其自己的进程,并在收集时析构.由Bridge.connect创建的则不会,因此停止不会干掉远程服务器.

驱动

驱动是使用SeleniumSDK主要方式.它封装单一会话,并在浏览器上面提供方便的API.调用力求与W3C规范和SeleniumRuby绑定保持高度一致.

停止驱动只会结束自己的驱动,则为保活其他驱动.

浏览

调用 动作
driver.go(url) 浏览到一个网址.
driver.back()/driver.forward() 通过历史移动.
driver.refresh() 重新加载文档.
driver.url 当前文档网址.
驱动.标题driver.title 当前文档标题.
driver.source 序化页资源.
driver.screenshot 视点的Base64PNG截图.

查找元素

使用By定位器,对单个元素使用找find,对每个匹配使用FindAll.

定位器 匹配
By.css(selector) CSS选择器.
By.xpath(expr) XPath表达式.
By.tagName(name) 标签名.
By.linkText(text) 精确可见文本锚点.
作者.部分链接文本(文本),By.partialLinkText(text) 包含文本的锚点.
cpp 复制代码
Element button = driver.find(By.css("#submit"));
Element[] items = driver.findAll(By.xpath("//li[@class='item']"));

脚本与窗口

cpp 复制代码
int sum = driver.execute!int("return arguments[0] + arguments[1];", JSONValue([2, 3]));
driver.window.maximize();
string[] handles = driver.window.handles();
string tab = driver.window.open("tab");
driver.window.switchTo(tab);
driver.frame.switchTo(0);
driver.frame.switchToParent();

小缓冲与记录日志

这些是每会话都可用,但不是快速入门的重点.简要说明:

cpp 复制代码
import selenium;
driver.cookies.add(Cookie("session", "abc123"));
Cookie[] all = driver.cookies.all();
driver.cookies.clear();
driver.logger.drain(LogType.Browser);
//拉取等待的远程日志

元素

元素是页中节点的句柄.只有该节点仍连接在DOM上时才有效;过时句柄抛StaleElementReferenceException.

成员 目的
文本text 已渲染可见的文本.
标签名tagName 小写标签名.
attribute(name) 标记属性值.
property(name) 活的DOM属性值.
cssValue(name) 计算出的CSS值.
大小/位置size/position 边框大小和偏移.
已选中/允许selected/enabled 元素状态.
点击()click() 点击元素.
sendKeys(text...) 输入进元素.
clear() 清理可编辑元素.
find(by)/findAll(by) 在该元素内搜索.
截图screenshot 元素的Base64PNG截图.
cpp 复制代码
Element form = driver.find(By.tagName("form"));
Element input = form.find(By.css("input[name='username']"));
input.sendKeys("alice");
writeln(input.attribute("placeholder"));
writeln(input.enabled);
form.find(By.css("button[type=submit']")).click();