1. 了解Selenium
1.1 Selenium簡介
? Selenium是一個用于Web應用程序測試的工具。Selenium測試直接運行在瀏覽器中,就像真正的用戶在操作一樣。支持的瀏覽器包括IE(7, 8, 9, 10, 11),Mozilla Firefox,Safari,Google Chrome,Opera,Edge等。這個工具的主要功能包括:測試與瀏覽器的兼容性——測試應用程序看是否能夠很好得工作在不同瀏覽器和操作系統之上。測試系統功能——創建回歸測試檢驗軟件功能和用戶需求。支持自動錄制動作和自動生成.Net、Java、Perl等不同語言的測試腳本。
1.2 Selenium功能
- 框架底層使用JavaScript模擬真實用戶對瀏覽器進行操作。測試腳本執行時,瀏覽器自動按照腳本代碼做出點擊,輸入,打開,驗證等操作,就像真實用戶所做的一樣,從終端用戶的角度測試應用程序。
- 使瀏覽器兼容性測試自動化成為可能,盡管在不同的瀏覽器上依然有細微的差別。
- 使用簡單,可使用Java,Python等多種語言編寫用例腳本。
1.3 Selenium WebDriver簡介
? Selenium 是一個用于自動化瀏覽器操作的工具集合,它包括多個組件,其中最常用的是 Selenium WebDriver。Selenium WebDriver 是 Selenium 中的一個關鍵組件,它提供了一組用于操作瀏覽器的 API。WebDriver 可以直接與瀏覽器進行通信,并模擬用戶在瀏覽器中的行為,例如點擊、輸入文本、提交表單等。WebDriver 支持多種編程語言,如Java、Python、C#等。
常見瀏覽器的WebDriver下載地址:
- ChromeDriver(Chrome 瀏覽器): 官方下載地址:https://sites.google.com/chromium.org/driver/
- GeckoDriver(Firefox 瀏覽器): 官方下載地址:https://github.com/mozilla/geckodriver/releases
- Microsoft WebDriver(Edge 瀏覽器): 官方下載地址:https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/
- SafariDriver(Safari 瀏覽器): SafariDriver 默認已經包含在 Safari 瀏覽器中,無需額外下載。
2. Java整合Selenium
2.1 先下載瀏覽器對應的驅動WebDriver
這里我下載了ChromeDriver,下載時盡量選擇驅動的版本和瀏覽器版本一樣,我的谷歌瀏覽器版本是116,這里我選擇下載了116版本的ChromeDriver。


2.2 引入Pom文件
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>3.141.59</version>
</dependency>
2.3 Selenium簡單使用
利用谷歌瀏覽器在地址欄輸入百度網址,并且利用百度搜索 Hello world!
public class SeleniumCase {
public static void main(String[] args) {
// 將webdriver.chrome.driver 設置到系統屬性中
System.setProperty("webdriver.chrome.driver","D:\\test\\chromedriver.exe");
WebDriver webDriver = new ChromeDriver();
webDriver.get("https://www.baidu.com");
// 找到輸入框input
WebElement searchElement = webDriver.findElement(By.xpath("http://*[@id=\"kw\"]"));
// 模擬輸入文本 Hello world!
searchElement.sendKeys("Hello world!");
// 提交表單搜索
searchElement.submit();
}
}
3. Selenium元素定位
Selenium 元素定位是指在使用 Selenium WebDriver 進行自動化測試時,通過一定的策略來定位網頁中的元素,以便進行操作和獲取元素的屬性、文本等信息。
3.1 常見的定位方式
- ID 定位:使用元素的唯一標識符(ID)來定位元素,通過
driver.findElement(By.id("elementId"))方法實現。 - Name 定位:使用元素的名稱屬性(Name)來定位元素,通過
driver.findElement(By.name("elementName"))方法實現。 - Class Name 定位:使用元素的類名(Class Name)來定位元素,通過
driver.findElement(By.className("className"))方法實現。 - Tag Name 定位:使用元素的標簽名(Tag Name)來定位元素,通過
driver.findElement(By.tagName("tagName"))方法實現。 - Link Text 定位:使用鏈接文本(Link Text)來定位鏈接元素,通過
driver.findElement(By.linkText("linkText"))方法實現。 - Partial Link Text 定位:使用鏈接的部分文本(Partial Link Text)來定位鏈接元素,通過
driver.findElement(By.partialLinkText("partialLinkText"))方法實現。 - CSS Selector 定位:使用 CSS 選擇器來定位元素,通過
driver.findElement(By.cssSelector("cssSelector"))方法實現。 - XPath 定位:使用 XPath 表達式來定位元素,通過
driver.findElement(By.xpath("xpathExpression"))方法實現。
這8種定位方式在java selenium 中對應的方法為:
| 方法 | 描述 | 參數 | 示例 |
|---|---|---|---|
| findElement(By.id()) | 通過元素的 id 屬性值來定位元素 | 對應的id屬性值 | findElement(By.id("kw")) |
| findElement(By.name()) | 通過元素的 name 屬性值來定位元素 | 對應的name值 | findElement(By.name("user")) |
| findElement(By.className()) | 通過元素的 class 名來定位元素 | 對應的class類名 | findElement(By.className("passworld")) |
| findElement(By.tagName()) | 通過元素的 tag 標簽名來定位元素 | 對應的標簽名 | findElement(By.tagName("input")) |
| findElement(By.linkText()) | 通過元素標簽對之間的文本信息來定位元素 | 文本內容 | findElement(By.linkText("登錄")) |
| findElement(By.partialLinkText()) | 通過元素標簽對之間的部分文本信息來定位元素 | 部分文本內容 | findElement(By.partialLinkText("百度")) |
| findElement(By.xpath()) | 通過xpath語法來定位元素 | xpath表達式 | findElement(By.xpath("http://input[@id='kw']")) |
| findElement(By.cssSelector()) | 通過css選擇器來定位元素 | css元素選擇器 | findElement(By.cssSelector("#kw")) |
同時這8種方法都對應有著返回復數元素的方法,分別在調用的方法findElements(By.id()) 加上一個s:
- findElements(By.id())
- findElements(By.name())
- findElements(By.className())
- findElements(By.tagName())
- findElements(By.linkText())
- findElements(By.partialLinkText())
- findElements(By.xpath())
- findElements(By.cssSelector())
3.2 定位方式使用示例
以下示例均以百度搜索(https://www.baidu.com/)頁面為例,圖片1-3紅框為演示區域,代碼片段1-1為百度首頁搜索表單html
代碼片段1-2為百度左上角友鏈html

<form id="form" name="f" action="/s" class="fm has-soutu">
<input type="hidden" name="ie" value="utf-8">
<input type="hidden" name="f" value="8">
<input type="hidden" name="rsv_bp" value="1">
<input type="hidden" name="rsv_idx" value="1">
<input type="hidden" name="ch" value="">
<input type="hidden" name="tn" value="15007414_12_dg">
<input type="hidden" name="bar" value="">
<span class="bg s_ipt_wr new-pmd quickdelete-wrap">
<span class="soutu-btn">
</span>
<input id="kw" name="wd" class="s_ipt" value="" maxlength="255" autocomplete="off">
<i class="c-icon quickdelete c-color-gray2" title="清空">
</i>
<i class="quickdelete-line">
</i>
<span class="soutu-hover-tip" style="display: none;">
按圖片搜索
</span>
</span>
<span class="bg s_btn_wr">
<input type="submit" id="su" value="百度一下" class="bg s_btn">
</span>
</form>
<a target="_blank" class="mnav c-font-normal c-color-t">
新聞
</a>
<a target="_blank" class="mnav c-font-normal c-color-t">
hao123
</a>
<a target="_blank" class="mnav c-font-normal c-color-t">
地圖
</a>
<a target="_blank" class="mnav c-font-normal c-color-t">
貼吧
</a>
<a target="_blank" class="mnav c-font-normal c-color-t">
視頻
</a>
<a target="_blank" class="mnav c-font-normal c-color-t">
圖片
</a>
<a target="_blank" class="mnav c-font-normal c-color-t">
網盤
</a>
3.2.1 id定位
需求定位到百度搜索輸入框
driver.findElement(By.id("kw"))
3.2.2 name定位
需求定位到百度搜索輸入框
driver.findElement(By.name("wd"))
3.2.3 class name定位
需求定位到百度搜索輸入框
driver.findElement(By.className("s_ipt"))
3.2.4 tag name定位
需求定位所有的Input 框
driver.findElements(By.tagName("input"))
3.2.5 Xpath定位
需求定位到百度搜索輸入框
driver.findElement(By.xpath("http://*[@id=\"kw\"]"))
注意:Xpath定位的方式有很多種,詳細可了解下Xpath語法。
3.2.6 css selector定位
需求定位到百度搜索輸入框
driver.findElement(By.cssSelector("#kw")
注意:css selector定位的方式有很多種,詳細可了解下css類選擇器用法。
3.2.7 Link Text 定位
定位到友鏈 貼吧
driver.findElement(By.linkText("貼吧")
3.2.8 Partial Link Text定位
定位到友鏈 貼吧
driver.findElement(By.partialLinkText("貼"))
driver.findElement(By.partialLinkText("吧"))
4. Selenium API
4.1.WebDriver 常用 API
WebDriver 提供了一系列的 API 來和瀏覽器進行交互,如下:
| 方法 | 描述 |
|---|---|
| get(String url) | 訪問目標 url 地址,打開網頁 |
| getCurrentUrl() | 獲取當前頁面 url 地址 |
| getTitle() | 獲取頁面標題 |
| getPageSource() | 獲取頁面源代碼 |
| close() | 關閉瀏覽器當前打開的窗口 |
| quit() | 關閉瀏覽器所有的窗口 |
| findElement(by) | 查找單個元素 |
| findElements(by) | 查到元素列表,返回一個集合 |
| getWindowHandle() | 獲取當前窗口句柄 |
| getWindowHandles() | 獲取所有窗口的句柄 |
4.2.WebElement 常用 API
通過 WebElement 實現與網站頁面上元素的交互,這些元素包含文本框、文本域、按鈕、單選框、div等,WebElement提供了一系列的方法對這些元素進行操作:
| 方法 | 描述 |
|---|---|
| click() | 對元素進行點擊 |
| clear() | 清空內容(如文本框內容) |
| sendKeys(...) | 寫入內容與模擬按鍵操作 |
| isDisplayed() | 元素是否可見(true:可見,false:不可見) |
| isEnabled() | 元素是否啟用 |
| isSelected() | 元素是否已選擇 |
| getTagName() | 獲取元素標簽名 |
| getAttribute(attributeName) | 獲取元素對應的屬性值 |
| getText() | 獲取元素文本值(元素可見狀態下才能獲取到) |
| submit() | 表單提交 |
4.2.1.代碼示例
public class BaiduSearch {
public static void main(String[] args) {
// 1.創建webdriver驅動
WebDriver driver = new ChromeDriver();
// 2.打開百度首頁
driver.get("https://www.baidu.com");
// 獲取搜索框元素
WebElement inputElem = driver.findElement(By.id("kw"));
// clear()方法,清空輸入框內容
inputElem.clear();
// sendKeys()方法,在搜索框中輸入搜索內容
inputElem.sendKeys("selenium");
// 元素是否顯示
boolean displayed = inputElem.isDisplayed();
System.out.println(displayed); // 輸出true
// 元素是否啟用
boolean enabled = inputElem.isEnabled();
System.out.println(enabled); // 輸出true
// 判斷元素是否被選中狀態,一般用在Radio(單選),Checkbox(多選),Select(下拉選)
// 在輸入框中使用無意義
boolean selected = inputElem.isSelected();
System.out.println(selected); // 輸出fasle
// 獲取標簽名
String tagName = inputElem.getTagName();
System.out.println(tagName); // 輸出input
// 獲取屬性名(name屬性)
String name = inputElem.getAttribute("name");
System.out.println(name); // 輸出wd
// 獲取文本值
String text = inputElem.getText();
System.out.println(text); // 輸出selenium
// 通過submit提交
driver.findElement(By.id("su")).submit();
// click()方法,點擊百度一下按鈕
driver.findElement(By.id("su")).click();
// 退出瀏覽器
driver.quit();
}
}
5. 元素等待機制
在對元素進行定位時,有時候網頁加載時間比較長,元素還沒有加載出來,這個時候去查找這個元素的話程序中就會拋出異常,所以我們在編寫代碼時需要考慮延時問題,在selenium中有幾種延時機制可以使用如下:
5.1.硬性等待
硬性等待就是不管你瀏覽器元素是否加載完成,都要進行等待設置好的時間,利用 java 語言中的線程類 Thread 中的 sleep 方法,進行強制等待。
Thread.sleep(long millis) 該方法會讓線程進行休眠。
如:Thread.sleep(3000) 表示程序執行的線程暫停 3 秒鐘。
這種方法在一定的程度上是可以解決元素加載過慢的情況,但是不建議使用該方法,因為一般情況下我們無法判斷網頁到底需要多長時間加載完成,如果我們設置的時間過長,非常影響效率。
5.2.隱式等待
隱式等待的理解,就是我們通過代碼設置一個等待時間,如果在這個等待時間內,網頁加載完成后就執行下一步,否則一直等待到時間截止。
代碼表示:
driver.manage.timeouts.implicitlyWait(long time, TimeUtil unit);
這種方法相對于硬性等待顯的會靈活一點,但是隱式等待也有個弊端,因為這個設置是全局的,程序需要等待整個頁面加載完成,直到超時,有時候我需要找的那個元素早就加載完成了,只是頁面上有個別其他元素加載比較慢,程序還是會一直等待下去。直到所有的元素加載完成在執行下一步。
5.3.顯式等待
顯示等待是等待指定元素設置的等待時間,在設置時間內,默認每隔0.5s檢測一次當前的頁面這個元素是否存在,如果在規定的時間內找到了元素則執行相關操作,如果超過設置時間檢測不到則拋出異常。默認拋出異常為:NoSuchElementException。推薦使用顯示等待。
代碼表示:
WebDriberWait wait = new WebDriverWait(dirver, timeOutInSeconds);
wait.nutil(expectCondition);
具體使用案例:
1.查找元素是否已經加載出來
WebDriverWait wait = new WebDriverWait(driver, 5);
// 查找id為“kw"的元素是否加載出來了(已經在頁面DOM中存在)
wait.until(ExpectedConditions.presenceOfElementLocated(By.id("kw")));
// 在設定時間內找到后就返回,超時直接拋異常
2.查找元素是否可見
WebDriverWait wait = new WebDriverWait(driver, 5);
// 查找id為"kw"的元素是否可見
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("kw")));
3.查找元素是否可點擊
WebDriverWait wait = new WebDriverWait(driver, 5);
// 查找id為"kw"的元素是否可以點擊
wait.until(ExpectedConditions.elementToBeClickable(By.id("kw")));
4.自定義方法,重寫ExpectedCondition中的apply方法
/*
自定義查找元素的方法,對元素查找方法進行二次封裝,更加的靈活,可以加上自己邏輯。
*/
public WebElement getElement(long timeOutInSecond, By by) {
WebDriverWait wait = new WebDriverWait(driver, timeOutInSecond);
WebElement element = wait.until(new ExpectedCondition<WebElement>() {
@NullableDecl
@Override
public WebElement apply(@NullableDecl WebDriver webDriver) {
return webDriver.findElement(by);
}
});
return element;
}
5.3.1.ExpectedConditions類中常用方法
| 方法 | 描述 |
|---|---|
| presenceOfElementLocated(By locator) | 判斷某個元素是否被加到了dom樹里,并不代表該元素一定可見; |
| visibilityOfElementLocated(By locator) | 判斷某個元素是否可見(代表元素非隱藏,元素的寬和高都不等于0); |
| elementToBeClickable(By locator) | 判斷某個元素中是否可見并且是enable的且可點擊; |
| elementToBeSelected(By locator) | 判斷某個元素是否被選中了,一般用在下拉列表; |
| alertIsPresent() | 判斷頁面上是否存在alert; |
| titleIs(String title) | 判斷當前頁面的title是否精確等于預期; |
| titleContains(String title) | 判斷當前頁面的title是否包含預期字符串; |
| textToBePresentInElement(By locator, String text) | 判斷某個元素中的text是否包含了預期的字符串; |
| textToBePresentInElementValue(By locator, String text) | 判斷某個元素中的value屬性是否包含了預期的字符串; |
| invisibilityOfElementLocated(By locator) | 判斷某個元素中是否不存在于dom樹或不可見; |
| frameToBeAvailableAndSwitchToIt(By) | 判斷iframe可用,并且切換到iframe中 |
5.4.頁面加載超時設置
通過TimeOuts 對象進行全局頁面加載超時的設置,該設置必須放置get 方法之前。如下代碼:
driver.manage().timeouts().pageLoadTimeout(5, TimeUnit.SECONDS);
driver.get("https://www.baidu.com");
如果百度首頁在超過5秒鐘沒有加載完畢,程序就會拋出異常,如果在 2秒就加載完了,就直接往下執行,如果需要對頁面加載時間有要求的,可以用這個設置進行檢驗。
6.特殊操作
6.1.彈出框處理(alert、confirm)
操作alert、confirm彈出框,可以通過Alert 對象來進行操作,Alert類包含了確認、取消、輸入和獲取彈出窗內容。
Alert對應屬性和方法:
| 方法 | 描述 |
|---|---|
| Alert.getText() | 獲取彈出框內容。 |
| Alert.accept() | 接受彈窗的提示,相當于點擊確認按鈕。 |
| Alert.dismiss() | 取消提示窗。 |
| Alert.sendKeys(String s) | 給彈窗輸入內容。 |
簡單使用示例:
// 首先需要切換到彈出框中,獲取Alert對象。
Alert alert = driver.switchTo().alert();
// 獲取彈窗文本內容
alert.getText();
// 點擊確定按鈕
alert.accept();
// 點擊取消按鈕
alert.dismiss();
注:如果彈出框不是 js 原生的 alert 彈窗,我們還是按照原來的獲取元素的方法。
6.2.iframe 切換
有時候我們定位元素的時候,發現怎么都定位不了。 這時候你需要查一查你要定位的元素是否在iframe里面。
什么是iframe?
iframe 就是HTML 中,用于網頁嵌套網頁的。 一個網頁可以嵌套到另一個網頁中,可以嵌套很多層。
例如:
main.html
<html>
<head>
<title>FrameTest</title>
</head>
<body>
<div id="id1">this is main page's div!</div>
<input type="text" id="maininput" />
<br/>
<iframe id="frameA" frameborder="0" scrolling="no" style="left:0;position:absolute;" src="frame.html"></iframe>
</body>
</html>
frame.html
<html>
<head>
<title>this is a frame!</title>
</head>
<body>
<div id="div1">this is iframes div,</div>
<input id="iframeinput"></input>
</body>
</html>
使用selenium 操作瀏覽器時,如果需要操作iframe中的元素,首先需要切換到對應的內聯框架中。
selenium 給我們提供了三個重載的方法,進行操作iframe;
切換方法:
// 方法一:通過 iframe的索引值,在頁面中的位置
driver.switchTo().frame(index);
// 方法二:通過 iframe 的name 或者id
driver.switchTo().frame(nameOrId);
// 方法三:通過iframe 對應的webElement
driver.switchTo().frame(frameElement);
selenium 代碼:
public static void testIframe(WebDriver driver){
// 在 主窗口的時候
driver.findElement(By.id("maininput")).sendKeys("main input");
// 此時 沒有進入到iframe, 以下語句會報錯
//driver.findElement(By.id("iframeinput")).sendKeys("iframe input");
driver.switchTo().frame("frameA");
driver.findElement(By.id("iframeinput")).sendKeys("iframe input");
// 此時沒有在主窗口,下面語句會報錯
//driver.findElement(By.id("maininput")).sendKeys("main input");
// 回到主窗口
driver.switchTo().defaultContent();
driver.findElement(By.id("maininput")).sendKeys("main input");
}
注:如果已經切換進入了其中的一個 iframe 中,再想對 iframe 外的元素進行操作,需要切換回到默認的頁面中,否則會找不到元素。
// 切換到默認內容頁面
driver.switchTo().defaultContent();
6.3.瀏覽器窗口的切換
有時候后在操作瀏覽器,可能打開了一個新的窗口,這個時候如果要對新窗口的元素進行操作,需要切換到新窗口中去,怎么去切換呢?在 selenium 中有個叫句柄的概念。
什么是句柄,簡單理解就是瀏覽器窗口的一個標識,瀏覽器打開的每個窗口都有唯一的一個標識,也就是句柄,我們可以通過句柄來進行窗口之間的切換,從而來達到我們操作不同窗口的元素。
WebDriver 中提供了兩個 API 來獲取窗口的相關句柄:
// 獲取當前窗口的句柄
String handle = driver.getWindowHandle();
// 獲取所有窗口的句柄,返回一個集合
Set<String> handles = driver.getWindowHandles();
獲取到句柄后,通過對應的方法進行切換:
// 切換到窗口
driver.switchTo.windwo(String handle);
多窗口之間的切換方法:
/**
* 切換窗口的方法
* 通過傳入一個標題來找到我們需要的窗口。
* @param title 窗口的標題
*/
public void switchWindow(String title){
Set<String> handles = driver.getWindowHandles();
// 切換窗口的方式--循環遍歷handles集合
for (String handle : handles) {
//判斷是哪一個頁面的句柄??--根據什么來判斷???title
if(driver.getTitle().equals(title)){
break;
}else{
//切換窗口--根據窗口標識來切換
driver.switchTo().window(handle);
}
}
6.4.select 下拉框處理
如果一個頁面元素是一個下拉框(select),對應下拉框的操作,selenium有專門的類 Select 進行處理。其中包含了單選和多選下拉框的各種操作,如獲得所有的選項、選擇某一項、取消選中某一項、是否是多選下拉框等。
Select類常用的一些方法:
| 方法 | 說明 |
|---|---|
| void deselectAll() | 取消所有選擇項,僅對下拉框的多選模式有效,若下拉不支持多選模式,則會拋出異常 UnsupportedOperationException(不支持的操作) |
| void deselectByIndex(int index) | 取消指定index的選擇,index從零開始,僅對多選模式有效,否則拋出異常 UnsupportedOperationException(不支持的操作) |
| void deselectByValue(String value) | 取消Select標簽中,value為指定值的選擇,僅對多選模式有效,否則拋出異常 UnsupportedOperationException(不支持的操作) |
| void deselectByVisibleText(String Text) | 取消項的文字為指定值的項,例如指定值為Bar,項的html為,僅對多選模式有效,單選模式無效,但不會拋出異常 |
ListgetAllSelectedOptions() |
獲得所有選中項,單選多選模式均有效,但沒有一個被選中時,返回空列表,不會拋出異常 |
WebElement getFirstSelectedOption() |
獲得第一個被選中的項,單選多選模式均有效,當多選模式下,沒有一個被選中時,會拋出NoSuchElementException異常 |
ListgetOptions() |
獲得下拉框的所有項,單選多選模式均有效,當下拉框沒有任何項時,返回空列表,不會拋出異常 |
boolean isMultiple() |
判斷下拉框是否多選模式 |
| void selectByIndex(int index) | 選中指定index的項,單選多選均有效,當index超出范圍時,拋出NoSuchElementException異常 |
| void selectByValue(String value) | 選中所有Select標簽中,value為指定值的所有項,單選多選均有效,當沒有適合的項時,拋出NoSuchElementException異常 |
| void selectByVisibleText(String text) | 選中所有項的文字為指定值的項,與deselectByValue相反,但單選多選模式均有效,當沒有適合的項時,拋出NoSuchElementException異常 |
示例:2345網址導航首頁的城市省份切換。
1.進入2345.com首頁,點擊頭部【切換】進行城市切換,我們切換省份為北京。

2.HTML頁面DOM結構。

3.代碼編寫,這里需要注意下拉選是在一個iframe中,需要先切換到這個iframe后再操作。
// 創建驅動
WebDriver driver = new ChromeDriver();
// 打開2345網站
driver.get("https://www.2345.com");
// 切換城市
driver.findElement(By.linkText("切換")).click();
// 切換到iframe內聯框架中
driver.switchTo().frame("city_set_ifr");
// 定位到省份下拉框
WebElement province = driver.findElement(By.id("province"));
province.click();
// 創建Select對象
Select select = new Select(province);
// 根據文本來獲取下拉值
select.selectByVisibleText("B 北京");
driver.quit();
6.5 帶 readonly 屬性的元素操作
標簽元素如果帶有 readonly 屬性,表示只讀不能進行編輯,如果我們需要操作這樣的元素,需要把這個 readonly 屬性進行移除后,再進行操作。刪除標簽屬性的話,webdriver 沒有對應的 API,我們使用 JavaScript 腳本來進行操作。
示例:12306 網站購票頁面日期。

selenium 代碼實現:
// 創建驅動
WebDriver driver = new ChromeDriver();
// 打開12306網站
driver.get("https://www.12306.cn/index/");
// 通過js來移除readonly屬性
String removeAttr = "document.getElementById('train_date').removeAttribute('readonly');";
// 執行js
((JavascriptExecutor)driver).executeScript(removeAttr);
// 獲取日期日歷輸入框
WebElement train_date = driver.findElement(By.id("train_date"));
// 清除原來的值
train_date.clear();
// 輸入內容
train_date.sendKeys("2020-03-30");
driver.quit();
6.6.日期控件操作
對于頁面中出現時間控件選擇時,一般分為兩種:
(1)控件沒有限制手動填寫的,我們直接使用 sendKeys() 方法進行賦值即可。
driver.findElement(By).sendKeys("2020-03-30");
(2)控件限制了手動輸入的,只能通過點擊控件時間進行輸入的,我們就需要使用 js 腳本進行操作了。
// 獲取js執行器
JavaScriptExecutor js = (JavaScriptExecutor)driver;
// 對時間輸入框進入賦值
String script = "document.getElementById('xxx').value='2020-03-30';";
// 執行
js.executeScript(script);
注:需要注意的是,不管使用哪種方式進行時間的賦值,一點要注意輸入時間的格式是否符合系統的要求;
6.7.文件上傳
對于通過input標簽實現的上傳功能,可以將其看作是一個輸入框,即通過sendKeys()指定本地文件路徑的方式實現文件上傳。
創建upfile.html文件,代碼如下:
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8" />
<title>upload_file</title>
<link rel="stylesheet" />
</head>
<body>
<div class="row-fluid">
<div class="span6 well">
<h3>upload_file</h3>
<input type="file" name="file" />
</div>
</div>
</body>
<script src="http://cdn.bootcss.com/bootstrap/3.3.0/css/bootstrap.min.js"></scrip>
</html>
接下來通過sendKeys()方法來實現文件上傳。
import java.io.File;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
public class UpFileDemo {
public static void main(String[] args) throws InterruptedException {
WebDriver driver = new ChromeDriver();
File file = new File("./HTMLFile/upfile.html");
String filePath = file.getAbsolutePath();
driver.get(filePath);
//定位上傳按鈕, 添加本地文件
driver.findElement(By.name("file")).sendKeys("D:\\upload_file.txt");
Thread.sleep(5000);
driver.quit();
}
}
注:sendKeys 參數為文件的絕對路徑,并且上傳的文件一點要存在,否則會拋異常。
6.8控制瀏覽器操作
6.8.1.瀏覽器窗口操作
WebDriver 給我們提供了一個 Window 對象,專門用于對窗口的設置。
對象獲取方法:
CopyWindow window = driver.manage().window();
Window 對象的方法有:
| 方法 | 描述 |
|---|---|
| window.maximize() | 將瀏覽器窗口最大化。 |
| window.getPosition() | 獲取窗口的位置,返回 Point 對象,包含瀏覽器左上角的坐標位置。通過point.x 和point.y 來獲取到。 |
| window.setPosition(Point) | 指定瀏覽器窗口左上角的坐標位置,創建一個Point 對象,設置對象的 x 和 y 坐標即可。 |
| window.getSize() | 獲取窗口尺寸(寬和高),返回一個 Dimension 對象,通過該對象調用 getHeight() 和 getWidth() 來獲取 高度和寬度。 |
| window.setSize(Dimension) | 設置窗口大小,創建一個 Dimension 對象,設置對象的高度和寬度。 |
6.8.2.瀏覽器導航操作
WebDriver 提供了 Navigation 對象來對瀏覽器進行導航操作,如:前進、后退、刷新等。
Navigation 對象獲取:
CopyNavigation navigate = driver.navigate();
Navigation 對象提供的方法:
| 方法 | 描述 |
|---|---|
| navigate.to(url) | 跳轉到指定url,和 webdriver 使用 get 方法是一樣的。 |
| navigate.refresh() | 刷新當前頁面。 |
| navigate.back() | 瀏覽器回退操作。 |
| navigate.forward() | 瀏覽器前進操作。 |
6.9 模擬鼠標鍵盤操作
6.9.1.模擬鼠標
在WebDriver中,關于鼠標的操作我們可以通過 Actions 類來模擬鼠標右擊、雙擊、懸停、拖動等操作。
Actions 類中鼠標操作常用方法:
| 方法 | 描述 |
|---|---|
| contextClick() | 鼠標右擊 |
| clickAndHold(WebElement) | 點擊并控制(模擬懸停) |
| doubleClick(WebElement) | 鼠標雙擊 |
| dragAndDrop(webElement1,webElement2) | 鼠標拖動 |
| moveToElement(WebElement) | 鼠標移動到某個元素上 |
| perform() | 執行所有Actions中存儲的行為 |
| click() | 鼠標單擊(左擊) |
示例:百度首頁設置懸停下拉菜單
Copyimport org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.interactions.Actions;
public class MouseDemo {
public static void main(String[] args) {
WebDriver driver = new ChromeDriver();
driver.get("https://www.baidu.com/");
// 定位元素
WebElement search_setting = driver.findElement(By.linkText("設置"));
// 創建actions對象
Actions action = new Actions(driver);
// 模擬鼠標懸停
action.clickAndHold(search_setting).perform();
driver.quit();
}
}
其他方法使用:
CopyActions action = new Actions(driver);
// 鼠標右鍵點擊指定的元素
action.contextClick(driver.findElement(By.id("element"))).perform();
// 鼠標雙擊指定的元素
action.doubleClick(driver.findElement(By.id("element"))).perform();
// 鼠標移到到指定元素上
action.moveToElement(driver.findElement(By.id("element"))).perform();
// 鼠標拖拽動作, 將 source 元素拖放到 target 元素的位置。
WebElement source = driver.findElement(By.name("element"));
WebElement target = driver.findElement(By.name("element"));
action.dragAndDrop(source,target).perform();
// 釋放鼠標
action.release().perform();
6.9.2.模擬鍵盤
在 selenium 中有個 Keys() 類(枚舉類),提供了幾乎鍵盤上所有按鍵的方法,在使用的過程中,我們可以通過 sendKeys() 方法來模擬鍵盤的輸入,除此之外,我們還可以用它來輸入鍵盤上的按鍵, 甚至是組合鍵, 如 Ctrl+A、 Ctrl+C 等。
以下為常用的鍵盤操作:
-
sendKeys(Keys.BACK_SPACE) 回格鍵(BackSpace)
-
sendKeys(Keys.SPACE) 空格鍵 (Space)
-
sendKeys(Keys.TAB) 制表鍵 (Tab)
-
sendKeys(Keys.ESCAPE) 回退鍵(Esc)
-
sendKeys(Keys.ENTER) 回車鍵(Enter)
-
sendKeys(Keys.CONTROL,'a') 全選(Ctrl+A)
-
sendKeys(Keys.CONTROL,'c') 復制(Ctrl+C)
-
sendKeys(Keys.CONTROL,'x') 剪切(Ctrl+X)
-
sendKeys(Keys.CONTROL,'v') 粘貼(Ctrl+V)
-
sendKeys(Keys.F1) 鍵盤 F1
-
sendKeys(Keys.F12) 鍵盤 F12
在使用鍵盤按鍵方法前,我們需要先導入 keys 類。
Copyimport org.openqa.selenium.WebElement;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
public class Keyboard {
public static void main(String[] args)throws InterruptedException {
WebDriver driver = new ChromeDriver();
driver.get("https://www.baidu.com");
// 定位到對應的元素
WebElement input = driver.findElement(By.id("kw"));
//輸入框輸入內容
input.sendKeys("seleniumm");
Thread.sleep(2000);
//刪除多輸入的一個 m
input.sendKeys(Keys.BACK_SPACE);
Thread.sleep(2000);
//輸入空格鍵+“教程”
input.sendKeys(Keys.SPACE);
input.sendKeys("教程");
Thread.sleep(2000);
//ctrl+a 全選輸入框內容
input.sendKeys(Keys.CONTROL,"a");
Thread.sleep(2000);
//ctrl+x 剪切輸入框內容
input.sendKeys(Keys.CONTROL,"x");
Thread.sleep(2000);
//ctrl+v 粘貼內容到輸入框
input.sendKeys(Keys.CONTROL,"v");
Thread.sleep(2000);
//通過回車鍵盤來代替點擊操作
input.sendKeys(Keys.ENTER);
Thread.sleep(2000);
driver.quit();
}
}
記錄:在 Actions 類中也有對應操作鍵盤的方法,例如:keyUp()、keyDown()等,但是我在實際使用中,并沒有生效,不知道為何,從網上資料說是,不能直接對瀏覽器進行操作,只能對頁面的元素進行鍵盤的模擬操作。
6.10 操作javaScript代碼
雖然WebDriver提供了操作瀏覽器的前進和后退方法,但對于瀏覽器滾動條并沒有提供相應的操作方法。在這種情況下,就可以借助JavaScript來控制瀏覽器的滾動條。WebDriver提供了executeScript()方法來執行JavaScript代碼。
用于調整瀏覽器滾動條位置的JavaScript代碼如下:
Copy<!-- window.scrollTo(左邊距,上邊距); -->
window.scrollTo(0,450);
window.scrollTo() 方法用于設置瀏覽器窗口滾動條的水平和垂直位置。方法的第一個參數表示水平的左間距,第二個參數表示垂直的上邊距。其代碼如下:
Copyimport org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.Dimension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.JavascriptExecutor;
public class JSDemo {
public static void main(String[] args) throws InterruptedException{
WebDriver driver = new ChromeDriver();
//設置瀏覽器窗口大小
driver.manage().window().setSize(new Dimension(700, 600));
driver.get("https://www.baidu.com");
//進行百度搜索
driver.findElement(By.id("kw")).sendKeys("webdriver api");
driver.findElement(By.id("su")).click();
Thread.sleep(2000);
//將頁面滾動條拖到底部
((JavascriptExecutor)driver).executeScript("window.scrollTo(100,450);");
Thread.sleep(3000);
driver.quit();
}
}
通過瀏覽器打開百度進行搜索,并且提前通過 window().setSize() 方法將瀏覽器窗口設置為固定寬高顯示,目的是讓窗口出現水平和垂直滾動條。然后通過 executeScript() 方法執行JavaScripts代碼來移動滾動條的位置。
將滾動條滾動到某個區域后停止(頁面元素全部加載完成),如下:
//滾動到某一區域
//scrollIntoView(0); 讓元素滾動到可視區域的最下方
//scrollIntoView(); 讓元素滾動到可視區域的最上方
//JavascriptExecutor javascriptExecutor = (JavascriptExecutor)BrowserUtil.driver;
//javascriptExecutor.executeScript("document.getElementById('index_ads').scrollIntoView(0);");
//JavaScript的參數傳遞-selenium和js的交互
//1、先去找到這個元素
WebElement webElement = driver.findElement(By.xpath("element"));
//2、找到的元素作為參數傳入到Js代碼中
JavascriptExecutor javascriptExecutor = (JavascriptExecutor)driver;
javascriptExecutor.executeScript("arguments[0].scrollIntoView(0)",webElement);
頁面元素是通過懶加載方式,需要一直進行滾動的
/**
* 滑動列表找元素并且進行點擊(懶加載)
* @param selectedText 選中元素文本
* @param by 正在加載類似元素的定位表達式
*/
public static void clickElementInList(String selectedText, By by) {
// 滑動之前的頁面源代碼信息
String beforeSource = "";
// 滑動之后的頁面源代碼信息
String afterSource = "";
// 循環條件
// 1、找到了元素,跳出循環
// 2、如果沒有找到元素???怎么跳出循環
while (true) {
WebElement webElement = driver.findElement(by);
// 獲取頁面源代碼
beforeSource = driver.getPageSource();
// 獲取js執行器
JavascriptExecutor javascriptExecutor = (JavascriptExecutor)driver;
// 執行js
javascriptExecutor.executeScript("arguments[0].scrollIntoView(0);", webElement);
// 如果當前頁面有想要的元素,怎么判斷是否有??--getPageSource
if (driver.getPageSource().contains(selectedText)) {
driver.findElement(By.linkText(selectedText)).click();
// 找到元素退出循環,不再滾動。
break;
}
afterSource = driver.getPageSource();
// 頁面元素沒有變化---滑動到了最底部
if (afterSource.equals(beforeSource)) {
// 到達底部,退出。
break;
}
}
}
6.11 截圖操作
使用 WebDriver 的
getScreenshotAs()方法來進行截圖操作。這個方法可以將當前瀏覽器窗口的內容保存為一個文件,并返回一個File對象。
6.11.1 全屏截圖
public class SeleniumCase {
public static void main(String[] args) {
// 將webdriver.chrome.driver 設置到系統屬性中
System.setProperty("webdriver.chrome.driver","D:\\test\\chromedriver.exe");
WebDriver driver = new ChromeDriver();
// 瀏覽器全屏
driver.manage().window().maximize();
driver.get("https://www.baidu.com");
try {
// 進行截圖
File screenshotFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
// 將截圖保存到指定路徑
FileUtils.copyFile(screenshotFile, new File("D:\\test\\"+ UUID.randomUUID()+".png"));
System.out.println("截圖成功!");
} catch (Exception e) {
System.out.println("截圖失敗:" + e.getMessage());
}
// 關閉瀏覽器
driver.quit();
}
}
6.11.2 指定區域截圖
這里選擇截取”百度一下“這個圖片

public class SeleniumCase {
/**屏幕縮放1,5*/
private static float screenScaling = 1.5f;
public static void main(String[] args) {
// 將webdriver.chrome.driver 設置到系統屬性中
System.setProperty("webdriver.chrome.driver","D:\\test\\chromedriver.exe");
WebDriver driver = new ChromeDriver();
// 瀏覽器全屏
driver.manage().window().maximize();
driver.get("https://www.baidu.com");
try {
// 進行截圖
File screenshotFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
// 元素定位 百度一下圖片
WebElement element = driver.findElement(By.id("su"));
// 將截圖保存到指定路徑
FileUtils.copyFile(captureElement(screenshotFile, element), new File("D:\\test\\"+ UUID.randomUUID()+".png"));
System.out.println("截圖成功!");
} catch (Exception e) {
System.out.println("截圖失敗:" + e.getMessage());
}
// 關閉瀏覽器
driver.quit();
}
public static File captureElement(File screenshot, WebElement element){
try {
BufferedImage img = ImageIO.read(screenshot);
int width = element.getSize().getWidth();
int height = element.getSize().getHeight();
//獲取指定元素的坐標
Point point = element.getLocation();
//從元素左上角坐標開始,按照元素的高寬對img進行裁剪為符合需要的圖片
BufferedImage dest = img.getSubimage((int) (point.getX() * screenScaling), (int) (point.getY() * screenScaling), (int) (width * screenScaling), (int) (height * screenScaling));
ImageIO.write(dest, "png", screenshot);
} catch (IOException e) {
throw new RuntimeException("指定區域截圖失敗");
}
return screenshot;
}
}
特別注意這里定義了一個變量screenScaling,這是根據當前你電腦的屏幕縮放設置的,我電腦是150%。

浙公網安備 33010602011771號