如何使用Selenium和Java进行网页浏览器自动化?

在这个教程中,我们将探索最受欢迎的网页浏览器自动化工具之一 – Selenium。我们将了解它的功能、API 以及如何使用 Selenium 与 Java 来自动化任何网站。
什么是 Selenium?
Selenium 是一个包含 Selenium IDE、Selenium RC 和 Selenium WebDriver 的工具集合。
- Selenium IDE 是一个纯粹的录制回放工具,作为 Firefox 插件和 Chrome 扩展出现。
- Selenium RC 是遗留工具,现已不再使用。
- Selenium WebDriver 是最新且广泛使用的工具。
注意,Selenium 仅用于与网页组件交互。因此,如果大家遇到任何基于桌面的组件(例如 Windows 对话框),Selenium 本身无法与它们交互。但是有其他类型的工具,可以与 Selenium 集成以实现,例如 AutoIt 或 Automa。
为什么使用 Selenium?
Selenium 是最流行的浏览器自动化工具之一。它不依赖于特定的编程语言,我们可以使用 Java、Python、C#、Ruby、PHP、Perl 等语言和它一起使用。如果您使用的语言尚未被支持,您还可以为该语言编写自己的实现。
在这个教程中,我们将学习如何使用 Java 的 Selenium WebDriver 绑定。我们还将探讨 WebDriver API。
Selenium 的成功也归功于 WebDriver 规范已成为 W3C 推荐标准用于浏览器。
先决条件:
- Java 环境和你最喜欢的 Java 集成开发环境 (IDE)
- Selenium-java 客户端
- 谷歌浏览器驱动程序
WebDriver 可以为所有流行的语言提供了绑定,这里我们使用的是 Java 环境,因此需要下载并包含 Java 绑定在构建路径中。在这个教程中,我们将操作 Google Chrome。
网络驱动程序
在开始之前,需先来了解一些在初学者中引起混淆的概念。WebDriver 不是一个 类,它是一个 接口。
所有基于浏览器的驱动程序,如 ChromeDriver、FirefoxDriver、InternetExplorerDriver 都是 Java 类,它们实现了接口。如果你想要在不同的浏览器上运行你的程序,就不需要更改大量的代码使其工作,你只需要将 WebDriver 替换为你想要的浏览器即可。
首先,让我们指定浏览器驱动程序的路径。接下来,我们将为该浏览器实例化“正确的驱动程序”,在我们的例子中是ChromeDriver :
System.setProperty("webdriver.chrome.driver", "path/to/chromedriver");
WebDriver driver = new ChromeDriver();
driver 持有一个对ChromeDriver的引用,因此可以用来驱动浏览器。当执行上述语句时,就可以在系统中看到一个新的浏览器窗口打开。但是浏览器还没有打开任何网站,我们需要指定浏览器去做。
注意:要使用不同的WebDriver,需要在文件系统中指定驱动程序路径,然后实例化它。例如,如果我们想使用 IE,则需要执行以下操作:
System.setProperty("webdriver.ie.driver", "path/to/IEDriver");
WebDriver driver = new InternetExplorerDriver();
接下来,所有浏览器的代码都将完全相同。我将自动化到 mybj123.com。
导航到网站
首先,我们需要导航到我们的目标网站。为此,我们只需向网站的 URL 发送一个GET请求:
driver.get("https://mybj123.com");
网页元素
网页浏览器自动化的第一步是找到我们想要与其交互的网页元素,例如按钮、输入框、下拉列表等。
Selenium 对应的 HTML 元素是 WebElement。比如 WebDriver 和 WebElement 也是 Java 接口。如果我们获取到一个 WebElement,我们就可以对它们执行任何终端用户可以执行的操作,比如点击、输入、选择等。
很明显,尝试执行无效操作,例如尝试在按钮元素中输入文本,将会导致异常。
我们可以使用元素的 HTML 属性,例如 id、class 和 name 来定位元素。如果不存在这样的属性,我们可以使用一些高级定位技术,例如 CSS 选择器 和 XPath。
想要检查任何元素的 HTML 属性,我们可以在我们的 Chrome 浏览器中打开网站(其他浏览器也支持此操作),右键单击要选择的元素,然后点击检查元素。
比如一个<input>标签上可能有多个属性,例如id、class等。
WebDriver支持 8 种不同的定位器来定位元素:
idclassNamenametagNamelinkTextpartialLinkTextcssSelector*xpath
让我们通过自动化我们目标网站中的不同元素,逐个探索它们。
通过 id 定位元素
如果我们检查目标网站的输入框,我们会发现它有一个id属性:
<input type="email" id="email" value name="email" class="required email input-lg" placeholder="请输入你的邮箱">
我们就可以使用 id 定位器来定位这个元素:
WebElement newsletterEmail = driver.findElement(By.id("email"));
通过 className 位元素
如果我们检查相同的输入框,我们可以看到它也有一个class属性。
我们可以使用 className 定位器来定位这个元素:
WebElement newsletterEmail = driver.findElement(By.className("required email input-lg"));
注意:定位器名称是className,不是class。
通过 name 定位元素
记下来的例子中,让我们想象一个下拉列表,用户应该选择他们的年龄范围。下拉列表有一个name属性,我们可以搜索这个属性:
<select name="age">
<option value="Yet to born">未出生</option>
<option value="Under 20">20 岁以下</option>
<option value="20 to 29">30 岁以下</option>
<option value="30 to 39">40 岁以下</option>
<option value="40 to 50">50 岁以下</option>
<option value="Over 50">60 岁以上</option>
<option value="Ghost">未定义</option>
</select>
我们使用 name 定位器来定位这个元素:
WebElement age = driver.findElement(By.name("age"));
通过 xpath 定位元素
有时这些方法已经过时,因为存在多个具有相同属性的元素:
<p>
<input name="gender" type="Radio" value="Female">女性<br>
<input name="gender" type="Radio" value="Male">男性<br>
<input name="gender" type="Radio" value="donotknow">未定义
</p>
上面例子中,我们可以看到三个input元素都有相同的name属性“gender”,但它们的值并不一定相同。这个时候如果我们获取某个具体的元素,可以使用XPath 选择器。
通过下面示例让你了解如何构造一个XPath 用于上面的 HTML 片段:
WebElement gender = driver.findElement(By.xpath("//input[@value='Female']"));
通过 cssSelector 定位元素
假如,有一个复选框列表,用户从中选择他们喜欢的编程语言:
<p>
<input name="language_java" type="Checkbox" value="java">Java<br>
<input name="language_python" type="Checkbox" value="python">Python<br>
<input name="language_c#" type="Checkbox" value="c#">C#<br>
<input name="language_c" type="Checkbox" value="c">C<br>
<input name="language_vbs" type="Checkbox" value="vbscript">Vbscript
</p>
从技术上讲,对于这个 HTML 片段,我们可以轻松地使用name定位器,因为它们有不同的值。然而,在这个例子中,我们将使用cssSelectors来定位这个元素,这个元素在前端广泛使用,比如与 jQuery 库一起使用。
以下示例可以让你了解如何为前面的 HTML 片段构建 CSS 选择器:
WebElement languageC = driver.findElement(By.cssSelector("input[value=c]"));
WebElement languageJava = driver.findElement(By.cssSelector("input[value=java]"));
看出来没,cssSelectors与 XPath 方法非常相似。
通过 linkText 定位元素
如果元素是一个链接,即具有 <a> 标签,我们可以通过使用linkText来定位它。例如,链接 “码云笔记”
<a href="/">码云笔记</a>
我们通过 linkText 来定位链接:
WebElement homepageLink = driver.findElement(By.linkText("Stack Abuse"));
通过 partialLinkText 定位元素
现在假如有一个带有文本的链接“random-text-xyz-i-wont-change-random-digit-123”,我们可以使用linkText定位器来定位这个元素。
但是,WebDriver API 提供了另一种方法 partialLinkText。有时链接文本的一部分可能是动态的,每次重新加载页面时都会改变 ,比如订单,“订单号 #XYZ123”。
在这些情况下,我们可以 partialLinkText 定位器:
WebElement iWontChangeLink = driver.findElement(By.partialLinkText("i-wont-change"));
通过上面的代码将成功选择我们的链接 “random-text-xyz-i-wont-change-random-digit-123”,因为我们的选择器包含链接的子字符串。
通过 tagName 定位元素
我们也可以通过使用元素的标签名来定位一个元素,例如 <a>,<div>,<input>,<select>等等。但是要应该谨慎使用这个定位器,因为可能有多个具有相同标签名的元素,而且命令总是返回页面中的第一个匹配元素:
WebElement tagNameElem = driver.findElement(By.tagName("select"));
这种方式在查找元素时通常更有用,当你在调用另一个元素的方法时,而不是整个 HTML 文档。这个方法缩小了你的搜索范围,使你能够使用简单的定位器来查找元素。findElement这缩小了你的搜索范围,使你能够使用简单的定位器来查找元素。
与元素互动
到目前为止,我们已经在页面上定位了 HTML 元素,并且能够获取相应的WebElement。但是,我们还没有像最终用户那样与这些元素进行交互,例如点击、输入、选择等。我们将在接下来的内容中探讨这些简单操作方法。
点击元素
我们经常使用 click() 方法来执行点击操作。当然前提元素是可点击的,否则,它将抛出一个异常。
在这种情况下,让我们点击homepageLink:
homepageLink.click();
输入文本
让我们在newsletterEmail输入框中输入一些文本:
newsletterEmail.sendkeys("admin@mybj123.com");
选择单选按钮
由于单选按钮只需点击,我们使用click()方法来选择一个:
gender.click();
选择复选框
同样的,我们也可以选择复选框,不过在这种情况下,我们可以选择多个复选框。如果我们选择另一个单选按钮,之前的单选按钮将被取消选择:
languageC.click(); languageJava.click();
从下拉菜单中选择项目
要从下拉列表中选择一个项目,我们需要做两件事:
首先,我们需要实例化 Select 并将其传递到页面中的元素:
Select select = new Select(age);
这里需要指出的是Select是一个 Java 类,实现了ISelect接口。
接下来,我们可以使用其:选择一个项目
显示文本:
select.selectByVisibleText("Under 30");
值 (the value 属性):
select.selectByValue("20 to 30");
索引(从 0 开始):
select.selectByIndex(2);
如果应用程序支持多选,我们可以调用这些方法一次或多次来选择不同的项目。
为了检查应用程序是否允许多选,我们可以运行:
select.isMultiple();
我们可以对下拉列表执行许多其他有用的的操作:
- 获取选项列表:
java.util.List<WebElement> options = select.getOptions();
- 获取所选选项的列表:
java.util.List<WebElement> options = select.getAllSelectedOptions();
- 获取第一个选定的选项
java.util.List<WebElement> options = select.getFirstSelectedOption();
- 取消选择所有选项
select.deselectAll();
- 通过显示的文本取消选择:
select.deselectByVisibleText("Under 30"); - 通过值取消选择:
select.deselectByValue("20 to 30"); - 通过索引取消选择:
select.deselectByIndex(2);
注意:我们也可以通过链式调用将找到元素和与之交互的两个步骤合并为一个语句。例如,我们可以像这样找到并点击提交按钮:
driver.findElement(By.id("submit_htmlform")).click();
我们也可以用Select做这件事:
Select select = new Select(driver.findElement(By.name("age")));
获取属性值
要获取元素中特定属性的值:
driver.findElement(By.id("some-id")).getAttribute("class")
设置属性值
我们也可以设置元素中特定属性的值。当我们需要启用或禁用任何元素时,这可能会很有用:
driver.findElement(By.id("some-id")).setAttribute("class", "enabled")
与鼠标和键盘互动
WebDriver API 提供了 Actions 类来与鼠标和键盘进行交互。
首先,我们需要实例化 Actions 并将其传递给 WebDriver 实例:
Actions builder = new Actions(driver);
移动鼠标
有时我们可能需要悬停在一个菜单项上,以显示子菜单项:
WebElement elem = driver.findElement(By.id("some-id"));
builder.moveToElement(elem).build().perform();
拖放
将一个元素拖动到另一个元素上:
WebElement sourceElement = driver.findElement(By.id("some-id"));
WebElement targetElement = driver.findElement(By.id("some-other-id"));
builder.dragAndDrop(sourceElement, targetElement).build().perform();
拖动一个元素移动一些像素(例如,水平 200px,垂直 0px):
WebElement elem = driver.findElement(By.id("some-id"));
builder.dragAndDropBy(elem, 200, 0).build().perform();
按下键
按住某个特定的键,同时输入一些文本,例如 Shift 键:
WebElement elem = driver.findElement(By.id("some-id"));
builder.keyDown(Keys.SHIFT)
.sendKeys(elem,"some value")
.keyUp(Keys.SHIFT)
.build()
.perform();
执行操作如 Ctrl+a、Ctrl+c、Ctrl+v和 TAB:
// 全选并复制 builder.sendKeys(Keys.chord(Keys.CONTROL,"a"),Keys.chord(Keys.CONTROL,"c")).build().perform(); // 按选项卡以聚焦下一个字段 builder.sendKeys(Keys.TAB).build().perform(); // 粘贴到下一个字段 builder.sendKeys(Keys.chord(Keys.CONTROL,"v")).build().perform();
与浏览器交互
获取页面源代码
最有可能的是,您将为此用于网页抓取需求:
driver.getPageSource();
获取页面标题
driver.getPageTitle();
最大化浏览器
driver.manage().window().maximize();
退出驱动程序
在程序结束时,重要的是停止驱动程序:
driver.quit();
注意:WebDriver API 还提供了一个close()方法,有时这会让初学者感到困惑。这个close()方法只是关闭浏览器,并且可以随时重新打开。它不会销毁WebDriver对象。当您不再需要浏览器时,quit()方法更为合适。
截取屏幕图像
首先,我们需要将 WebDriver转换为 TakesScreenshot类型,这是一个 接口。接下来,我们可以调用 getScreenshotAs()并传递 OutputType.FILE。
最后,我们可以使用适当的扩展名(如*.jpg,*.png 等)将文件复制到本地文件系统中。
File fileScreenshot=((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
// 将屏幕截图复制到扩展名为*.png 的本地文件系统中
FileUtils.copyFile(fileScreenshot, new File("path/MyScreenshot.png"));
执行 JavaScript
我们能注入或执行任何有效的 JavaScript 通过 Selenium WebDriver。这非常有用,因为它允许你执行许多 Selenium 没有直接内置的功能。
首先,我们需要将 WebDriver 转换为类型 JavaScriptExecutor:
JavaScriptExecutor js = (JavaScriptExecutor)driver;
有几个用例与JavaScriptExecutor有关:
- 如果 WebDriver API 失败,以自然的方式进行操作 – 像一个
click()或sendKeys()。js.executeScript("driver.getElementById('some-id').click();");我们也可以首先通过使用 WebDriver 定位器找到元素,然后将该元素传递给
executeScript()作为第二个参数。这是使用JavaScriptExecutor的更自然的方法:// 首先使用定位器找到元素 WebElement element = driver.findElement(By.id("some-id")); // 将元素作为第二个参数传递给 js.executeScript js.executeScript("arguments[0].click();", element);要设置输入字段的值:
String value = "some value"; WebElement element = driver.findElement(By.id("some-id")); js.executeScript("arguments[0].value=arguments[1];", element, value); - 将页面滚动到底部:
js.executeScript("window.scrollTo(0, document.body.scrollHeight);"); - 滚动元素以将其带入视口:
WebElement element = driver.findElement(By.id("some-id")); // 如果元素位于底部,则传递 true,否则传递 false js.executeScript("arguments[0].scrollIntoView(true);", element); - 更改页面(添加或删除元素的某些属性):
WebElement element = driver.findElement(By.id("some-id")); js.executeScript("arguments[0].setAttribute('myattr','myvalue')", element);
访问 Cookies
由于许多网站使用 Cookies 来存储用户状态或其他数据,您可能需要使用 Selenium 编程访问这些数据。以下列出了常见的 Cookies 操作。
获取所有 Cookie:
driver.manage().getCookies();
获取特定的 Cookie:
driver.manage().getCookieNamed(targetCookie);
添加一个饼干:
driver.manage().addCookie(mySavedCookie);
删除一个 cookie:
driver.manage().deleteCookie(targetCookie);
结论
上面我们已经介绍了在自动化 web 浏览器时可能需要使用的 Selenium WebDriver 的所有主要功能。SeleniumWebDriver 有一个非常广泛的 API,涵盖的内容超出了本教程的范围。
不知道你有没有已经注意到,Selenium WebDriver 有很多有用的方法来模拟几乎所有的用户交互。现代 web 应用程序又很灵活,如果他们想限制他们的自动使用,有各种方法可以做到这一点,比如使用验证码。但是,Selenium 无法绕过验证码。最后,如使用此工具,请牢记目标网站的使用条款。
以上关于如何使用Selenium和Java进行网页浏览器自动化?的文章就介绍到这了,更多相关内容请搜索码云笔记以前的文章或继续浏览下面的相关文章,希望大家以后多多支持码云笔记。
如若内容造成侵权/违法违规/事实不符,请将相关资料发送至 admin@mybj123.com 进行投诉反馈,一经查实,立即处理!
重要:如软件存在付费、会员、充值等,均属软件开发者或所属公司行为,与本站无关,网友需自行判断
码云笔记 » 如何使用Selenium和Java进行网页浏览器自动化?
微信
支付宝