# java_selenium **Repository Path**: johndriver/java_selenium ## Basic Information - **Project Name**: java_selenium - **Description**: java环境使用selenium - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 2 - **Created**: 2021-05-22 - **Last Updated**: 2025-04-14 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Selenium的java使用 ## 获取WebDriver ``` System.setProperty("webdriver.chrome.driver", "src\\main\\resources\\static\\chromedriver.exe"); WebDriver driver = new ChromeDriver(); ``` [第三方浏览器驱动下载](https://www.selenium.dev/documentation/en/webdriver/driver_requirements/) * 远程WebDriver客户端 ```text FirefoxOptions firefoxOptions = new FirefoxOptions(); WebDriver driver = new RemoteWebDriver(new URL("http://www.example.com"), firefoxOptions); driver.get("http://www.google.com"); driver.quit(); ``` ## 浏览器操作 ### 导航 ```text //Convenient driver.get("https://selenium.dev"); //Longer way driver.navigate().to("https://selenium.dev"); ``` * 获取当前URL 获取标题 ```text driver.getCurrentUrl(); driver.getTitle(); ``` * 前进 后退 刷新 ```text driver.navigate().back(); driver.navigate().forward(); driver.navigate().refresh(); ``` ### 视窗和分页 * 获取窗口句柄 ```text driver.getWindowHandle(); ``` * 切换视窗或标签 ```text //Store the ID of the original window String originalWindow = driver.getWindowHandle(); //Click the link which opens in a new window driver.findElement(By.linkText("new window")).click(); //Wait for the new window or tab wait.until(numberOfWindowsToBe(2)); //Loop through until we find a new window handle for (String windowHandle : driver.getWindowHandles()) { if(!originalWindow.contentEquals(windowHandle)) { driver.switchTo().window(windowHandle); break; } } //Wait for the new tab to finish loading content wait.until(titleIs("Selenium documentation")); ``` * 创建新窗口(或)新标签并切换(版本4) ```text driver.switchTo().newWindow(WindowType.TAB); driver.switchTo().newWindow(WindowType.WINDOW); ``` * 关闭窗口或标签 ```text driver.close(); driver.switchTo().window(originalWindow); ``` * 在会话结束时退出浏览器 ```text driver.quit(); ``` ## 定位元素 ### id ```text WebElement cheese = driver.findElement(By.id("cheese")); ``` ### css ```text driver.findElement(By.cssSelector("#cheese #cheddar")); 1.#:id 2. .:class 3.:nth-child(5) 第五个 driver.findElement(By.cssSelector("#container > div > div.hot-data > div:nth-child(5)")); // div class ="clearfix wrap980" 两个值 By.cssSelector("div.clearfix.wrap980") ``` [css选择器语法](https://www.runoob.com/cssref/css-selectors.html) ### 定位多个元素 `findElements` ```text List muchoCheese = driver.findElements(By.cssSelector("#cheese li")); ``` ### class name ```text WebElement element1 = driver.findElement(new By.ByClassName("fn-clear")); ``` ### tag name ```text List li = driver.findElements(new By.ByTagName("li")); ``` ### xpath ```text //id=container的div下,下标为2的div WebElement div2 = driver.findElement(By.xpath("//div[@id='container']/div[2]")); // 1.//:任意路径下 1.*:任意元素 3.[@id='container']:id=container 4.div:第一个div 5.div[@class='hot-data']:div class=hot-data 6.div[5]:第五个div driver.findElement(By.xpath("//*[@id='container']/div/div[@class='hot-data']/div[5]")) //可以多个class By.xpath("//*[@class='clearfix wrap980']" ``` [xpath语法](https://www.w3school.com.cn/xpath/xpath_syntax.asp) *** a标签的文字 ```text By.linkText("See a sample confirm") ``` ### 相对定位 * 上 ```text WebElement passwordField= driver.findElement(By.id("password")); WebElement emailAddressField = driver.findElement(with(By.tagName("input")) .above(passwordField)); ``` * 下 ```text WebElement emailAddressField= driver.findElement(By.id("email")); WebElement passwordField = driver.findElement(with(By.tagName("input")) .below(emailAddressField)); ``` * 左 ```text WebElement submitButton= driver.findElement(By.id("submit")); WebElement cancelButton= driver.findElement(with(By.tagName("button")) .toLeftOf(submitButton)); ``` * 右 ```text WebElement cancelButton= driver.findElement(By.id("cancel")); WebElement submitButton= driver.findElement(with(By.tagName("button")) .toRightOf(cancelButton)); ``` * 附近 返回WebElement,该WebElement最多与指定的元素相距50px。 ```text WebElement emailAddressLabel= driver.findElement(By.id("lbl-email")); WebElement emailAddressField = driver.findElement(with(By.tagName("input")) .near(emailAddressLabel)); ``` ## 获取信息 ### 文本 ```text element.getText() ``` ### 属性 ```text element.getAttribute("class"); element.getAttribute("href"); element..getAttribute("onerror") ``` ### css样式 ```text element.getCssValue("width") ``` ### 标签名 ```text element.getTagName() ``` ## 等待 根据经验,由于使用Selenium和WebDriver而引起的大多数间歇性问题都与浏览器和用户说明之间发生的争用情况有关。一个示例可能是用户指示浏览器导航到页面,然后在尝试查找元素时收到没有此类元素错误。 为了克服浏览器和WebDriver脚本之间的竞争条件问题,大多数Selenium客户端附带了一个等待包 ### 明确等待 ___ Selenium客户可以使用命令式,程序性语言进行显式等待。它们允许您的代码暂停程序执行或冻结线程,直到传递给它的条件解决为止。以一定的频率调用该条件,直到等待超时超时为止。这意味着只要条件返回虚假值,它就会一直尝试并等待。 ```text WebDriver driver = new ChromeDriver(); driver.get("https://google.com/ncr"); driver.findElement(By.name("q")).sendKeys("cheese" + Keys.ENTER); //10s内,等待By.xpath("//a/h3")这个元素可以点击的条件发生。返回可点击对象 WebElement firstResult = new WebDriverWait(driver, 10) .until(ExpectedConditions.elementToBeClickable(By.xpath("//a/h3"))); System.out.println(firstResult.getText()); ``` 由于wait实用程序默认情况下不会忽略任何此类元素错误,因此我们可以将指令重构为更加简洁 ```text //3秒钟内重复尝试,直到获取名字为q的元素并返回这个元素 WebElement foo = new WebDriverWait(driver, 3) .until(driver -> driver.findElement(By.name("q"))); ``` 超时得不到则抛出/引发一个错误/异常,称为超时错误 * 条件 ```text //元素可点击 ExpectedConditions.elementToBeClickable(By.id("element")); ExpectedConditions.elementToBeClickable(element); //元素存在 ExpectedConditions.presenceOfElementLocated(By.id("element")); //元素中存在文字 ExpectedConditions.textToBePresentInElement(element,"元素中的文字"); //元素可不可见 ExpectedConditions.visibilityOfElementLocated(By.id("element")); ExpectedConditions.invisibilityOfElementLocated(By.id("element")); ExpectedConditions.visibilityOf(element); ExpectedConditions.visibilityOfNestedElementsLocatedBy(By.id("parent"),By.id("child")); //元素的某个属性是不是这个值 ExpectedConditions.attributeToBe(element,"href","www.baidu.com"); //元素中是否有值为"www.baidu.com"的href属性 ExpectedConditions.attributeContains(element,"href","www.baidu.com"); //frame是否可用并转入 ExpectedConditions.frameToBeAvailableAndSwitchToIt(By.id("frame")); //标题条件 ExpectedConditions.titleIs("标题"); ``` [ExpectedConditions类的详情](https://www.selenium.dev/selenium/docs/api/java/org/openqa/selenium/support/ui/ExpectedConditions.html) ### 隐式等待 ___ 隐式等待是告诉WebDriver在尝试查找不立即可用的一个或多个元素时,在一定时间内轮询DOM。默认设置为0,表示已禁用。设置后,将在会话生命周期内设置隐式等待。 通过隐式等待,WebDriver在尝试查找**任何元素**时会轮询DOM一定时间。当网页上的某些元素无法立即使用并且需要一些时间来加载时,很有用。 * 警告: 请勿混合使用隐式和显式等待。这样做可能导致无法预测的等待时间。 ```text driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); ``` ### 流利的等待 FluentWait实例定义了等待条件的最长时间,以及检查条件的频率。 用户可以配置等待以在等待时忽略特定类型的异常,例如 NoSuchElementException 在页面上搜索元素时。 ```text Wait wait = new FluentWait(driver) .withTimeout(Duration.ofSeconds(30))//等待30s .pollingEvery(Duration.ofSeconds(5))//5秒尝试访问一次 .ignoring(NoSuchElementException.class);//忽略访问时找不到元素异常 WebElement foo = wait.until(new Function() { public WebElement apply(WebDriver driver) { return driver.findElement(By.id("foo")); } }); ``` ## 处理JavaScript警报,提示和确认框 ### alert WebDriver可以从弹出窗口中获取文本,并接受或关闭这些警报。 ```text //触发alert driver.findElement(By.linkText("See an example alert")).click(); //等待alert弹出并获取 Alert alert = wait.until(ExpectedConditions.alertIsPresent()); //获取alert文本 String text = alert.getText(); //点击alert ok按钮 alert.accept(); ``` ### Confirm 确认框类似于alert,不同之处在于用户还可以选择取消消息。 ```text //触发 driver.findElement(By.linkText("See a sample confirm")).click(); //获取 wait.until(ExpectedConditions.alertIsPresent()); //跳转方式获取Confirm Alert alert = driver.switchTo().alert(); //获取文字 String text = alert.getText(); //点击取消按钮 alert.dismiss(); ``` ### Prompt 提示与确认框相似,不同之处在于它们还包括文本输入。与处理表单元素类似,您可以使用WebDriver的send键来填充响应。这将完全替换占位符文本。按下取消按钮将不会提交任何文本。 ```text driver.findElement(By.linkText("See a sample prompt")).click(); Alert alert = wait.until(ExpectedConditions.alertIsPresent()); //设置值 alert.sendKeys("Selenium"); //ok按钮 alert.accept(); ``` ## http代理 ```java import org.openqa.selenium.Proxy; import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; import org.openqa.selenium.chrome.ChromeOptions; public class proxyTest { public static void main(String[] args) { //代理 Proxy proxy = new Proxy(); proxy.setHttpProxy(""); //driver配置选项 ChromeOptions options = new ChromeOptions(); options.setCapability("proxy", proxy); WebDriver driver = new ChromeDriver(options); driver.get("https://www.google.com/"); driver.manage().window().maximize(); driver.quit(); } } ``` ## 页面加载策略 ### normal (默认) 这将使Selenium WebDriver等待整个页面加载。设置为normal时,Selenium WebDriver会一直等到 加载 返回事件 ### eager 这将使Selenium WebDriver等待直到完全加载并解析了初始HTML文档,并放弃了样式表,图像和子帧的加载。 设置为eager时,Selenium WebDriver会一直等到 DOMContentLoaded 返回事件 ``` ChromeOptions chromeOptions = new ChromeOptions(); chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER); WebDriver driver = new ChromeDriver(chromeOptions); ``` ### none 设置为none时, Selenium WebDriver仅等待下载初始页面。 ``` chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE); ``` ## 网络元素 WebElement表示DOM元素。可以通过使用WebDriver实例从文档根目录进行搜索,或者在另一个WebElement下进行搜索来找到WebElement。 WebDriver API提供了内置方法来查找基于不同属性的WebElement,例如ID,Name,Class,XPath,CSS Selectors,链接Text等。 ### 查找元素 它用于查找元素并返回第一个匹配的单个WebElement引用,该引用可用于将来的元素操作 * 找元素 ```text WebElement searchBox = driver.findElement(By.name("q")); List elements = driver.findElements(By.tagName("p")); WebElement searchForm = driver.findElement(By.tagName("form")); WebElement searchBox = searchForm.findElement(By.name("q")); WebElement element = driver.findElement(By.tagName("div")); List elements = element.findElements(By.tagName("p")); ``` * 取值设值 ```text String text = element.getText(); //获取元素文本 String attr = element.getAttribute("title"); //属性 String value = element.getTagName(); //标签名 String cssValue = element.getCssValue("color");//css值 ``` * 设值 ```text element.sendKeys("webdriver");// input框 设值 ``` * 判断元素 ```text element.isEnabled(); //是否启用 element.isSelected(); //是否已选 ``` * 获取元素矩形位置 > 元素左上角的X轴位置 > 元素左上角的y轴位置 > 元素的高度 > 元素的宽度 ```text Rectangle rect = element.getRect(); rect.getX(); rect.getY(); rect.getWidth(); rect.getHeight(); ``` ## 键盘操作 ### sendKeys [支持的键盘的所有键](https://www.w3.org/TR/webdriver/#keyboard-actions) ```text driver.findElement(By.name("q")).sendKeys("q" + Keys.ENTER); ``` ### keyDown keyDown用于模拟按下修改键(CONTROL,SHIFT,ALT)的动作 ```text WebDriver driver = new ChromeDriver(); try { driver.get("https://google.com"); driver.findElement(By.name("q")).sendKeys("webdriver" + Keys.ENTER);//输入文本"webdriver"并按键ENTER Actions actionProvider = new Actions(driver); Action keydown = actionProvider.keyDown(Keys.CONTROL).sendKeys("a").build(); //crtl+a keydown.perform(); } finally { driver.quit(); } ``` ### keyUp keyUp用于模拟修改键(CONTROL,SHIFT,ALT)的向上(或)释放操作 ```java public class HelloSelenium { public static void main(String[] args) { WebDriver driver = new FirefoxDriver(); try { driver.get("https://google.com"); WebElement search = driver.findElement(By.name("q")); //按下SHIFT打qwerty得到大写QWERTY 松开SHIFT+qwerty得到qwerty Actions action = new Actions(driver); action.keyDown(Keys.SHIFT).sendKeys(search,"qwerty").keyUp(Keys.SHIFT).sendKeys("qwerty").perform(); } finally { driver.quit(); } } } ``` ### clear 清除可编辑元素的内容。这仅适用于可编辑和可交互的元素,否则Selenium返回错误(无效的元素状态(或)不可交互的元素) ```text searchInput.clear(); ``` ## 使用cookies 新增Cookie ```text driver.manage().addCookie(new Cookie("key", "value")); ``` 获取命名的获取所有 ```text Cookie cookie = driver.manage().getCookieNamed("foo"); ``` 获取所有获取所有 ```text Set cookies = driver.manage().getCookies(); ``` 删除Cookie ```text driver.manage().deleteCookieNamed("test1"); driver.manage().deleteCookie(cookie1); driver.manage().deleteAllCookies(); ``` ### 相同站点Cookie属性 * Strict 当sameSite属性设置为Strict时,cookie将不会与第三方网站发起的请求一起发送。 * Lax 当您将Cookie sameSite属性设置为Lax时,该Cookie将与第三方网站发起的GET请求一起发送。 ```text Cookie cookie = new Cookie.Builder("key", "value").sameSite("Strict").build(); Cookie cookie1 = new Cookie.Builder("key", "value").sameSite("Lax").build(); ``` ## 参考 [官方文档(英文)翻译观看](https://www.selenium.dev/documentation/en/)