Java/Kotlin 使用 Chrome 无头欣赏器

[复制链接]
发表于 2025-11-2 07:28:24 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
1. 概念

无头欣赏器在类似于盛行网络欣赏器的情况中提供对网页的主动控制,但是通过下令行界面或使用网络通讯来实验。 它们对于测试网页特别有效,由于它们可以或许像欣赏器一样出现和明白超文本标记语言,包罗页面结构、颜色、字体选择以及JavaScript和AJAX的实验等样式元素,这些元素在使用其他测试方法时通常是不可用的。[1][2]
无头欣赏器通常用来:


  • Web应用步调中的测试主动化。
  • 拍摄网页截图
  • 对JavaScript库运行主动化测试
  • 网络网站数据
  • 主动化网页交互
1.2 与传统的Http 库做爬虫对比

无头欣赏器与HTTP库都可以用于爬虫,但它们有一些区别和优劣势。无头欣赏器指的是使用脚原来模拟真实欣赏器的使用场景,它可以或许更好地处置惩罚JavaScript渲染、异步哀求等标题,而HTTP库则更得当处置惩罚静态页面、API等。
无头欣赏器:


  • JavaScript渲染和动态页面处置惩罚: 如果你须要爬取动态页面大概须要实验JavaScript代码,无头欣赏器是更好的选择。
  • JavaScript解密:无头欣赏器不能解密js脚本以此让你查阅,但是他能实验该脚本以此来得到效果。而HTTP库对于加密的JS须要举行JS逆向等利用之后在模拟加密过程才气与API举行访问,而无头欣赏器直接帮你举行模拟。无头模拟器通常用于有加密的js的网站
  • 隐私和安全:无头欣赏器可以模拟真实的用户活动,更可以或许克制被网站检测到并制止。别的,无头欣赏器可以自主的使用署理、设置cookies等方式来掩护隐私和安全因此可以做到处置惩罚反爬虫的效果
HTTP库:


  • 性能和速率:HTTP库通常比无头欣赏器更快。HTTP只须要思量API和静态页面的获取,不须要分析页面,获取CSS,渲染页面
  • 代码复杂度和维护本钱:获取某个数据可以通过少量代码直接调用API。使用无头欣赏器大概须要更复杂的代码,由于须要编写JavaScript代码来模拟用户活动和利用DOM
1.3 无头欣赏器一览



  • Headless Chrome: Google推出的无头欣赏器,可以模拟Chrome欣赏器的全部功能,包罗JavaScript分析、HTML分析、CSS分析等。
  • Selenium : 并不是一个无头欣赏器,而是一个欣赏器主动化测试工具,这个通常会被搞混,他可以通过驱动步调来主动化操尴尬刁难应的欣赏器。Selenium可以支持多款主流欣赏器,包罗Chrome、Firefox、Safari等。同时 Selenium还支持欣赏器的无头模式,好比Firefox、PhantomJS、Chrome的无头模式(Headless)等
  • Puppeteer: Google开发的一个Node.js库,用于控制Headless Chrome,可以模拟用户利用、截屏、天生PDF等。
  • Playwright: Microsoft开发的一个Node.js库,可以控制多个欣赏器,包罗Chrome、Firefox和Safari等,可以模拟用户利用、截屏、天生PDF等。
  • Splash:一个基于Python的无头欣赏器,可以分析JavaScript、渲染网页、截屏等,可以通过HTTP API举行控制。
  • HtmlUnit: 一款基于Java的开源无头欣赏器,它可以模拟欣赏器活动并实验JavaScript代码。它可以与JUnit和TestNG等测试框架集成,用于主动化测试和Web爬虫等使命。
  • JBrowserDriver: 一款基于Selenium WebDriver的无头欣赏器,它使用Java Swing库模拟欣赏器界面。它可以模拟用户活动,举行主动化测试和Web爬虫等使命。然而,由于它使用了Java Swing库,因此大概须要更多的资源。
  • Cobra: 一款Java HTML分析器和渲染引擎,可以模拟欣赏器活动并实验JavaScript代码。它可以用于主动化测试、Web爬虫和Web应用步调等使命。然而,由于它不是专门为主动化测试而计划的,因此大概须要更多的设置和代码。
1.4. 主动化设置情况

2.1 引入依靠:

ChromiumDownloader 是用于下载 Chromium 和对应的 ChromiumDriver。
同时ChromiumDownloader依靠了 selenium 以是仅须要引入这个一个依靠即可,如果须要更换 selenium 别的自行引入即可
  1. <dependency>
  2.     <groupId>io.github.zimoyin</groupId>
  3.     <artifactId>ChromiumDownloader</artifactId>
  4.     <version>1.3.1</version>
  5. </dependency>
复制代码
2.2 下载 Chromium/ChromiumDriver

使用 ChromiumLoader.downloadAndLoad 即可主动下载 Chromium/ChromiumDriver 如果在当地./chrome查找到了 Chromium/ChromiumDriver 则不会去下载了
  1. val proxy = Proxy(Proxy.Type.HTTP, InetSocketAddress("127.0.0.1", 8070))
  2. val options = ChromiumLoader.downloadAndLoad(proxy)
复制代码
由于须要到谷歌服务器去下载文件,以是对于须要一些特别的Proxy才气访问和下载。
如果须要手动下载到该构建网站下载最新的构建版本即可: 点击跳转
2.3 国内镜像下载

如果不想使用署理就可以使用该方法,他将访问华为云的镜像服务器下载须要的文件
  1. // 配置 Chrome 的加载器,并配置下载核心
  2. // ChromiumDownloader (默认下载核心需要使用代理国内才可访问)
  3. // HuaweicloudChromiumDownloader (华为云镜像)
  4. val loader = ChromiumLoader(HuaweicloudChromiumDownloader())
  5. // 从镜像服务器下载文件
  6. // HuaweicloudChromiumDownloader().downloadChrome()
  7. // HuaweicloudChromiumDownloader().downloadChromeDriver()
  8. // 加载 Chrome 如果没有则下载
  9. val options = loader.downloadAndLoad()
  10. println("Chrome 版本: " + loader.chromeVersion)
  11. println("ChromeDriver 版本: " + loader.chromeDriverVersion)
  12. println("Chrome 路径: " + loader.chromePath)
  13. println("ChromeDriver 路径: " + loader.chromeDriverPath)
  14. println("当前平台: "+loader.platform)
  15. // 注意 Root 运行需要关闭沙盒
  16. options.addArguments("--no-sandbox")
  17. options.addArguments("--disable-dev-shm-usage")
  18. options.addArguments("--ignore-ssl-errors=yes")
  19. options.addArguments("--ignore-certificate-errors")
  20. //    options.addArguments("--headless")
  21. ChromeDriver(options).blockUntilQuitSuspend {
  22.     get("https://www.baidu.com")
  23. }
复制代码
2.3 访问百度

至此一个最简朴的功能已将实现了,通过 ChromiumDownloader 不再须要手动去下载Chrome 和它的驱动了
  1. val options = ChromiumLoader.downloadAndLoad(proxy)
  2. // 注意 Root 运行需要关闭沙盒
  3. options.addArguments("--no-sandbox")
  4. options.addArguments("--disable-dev-shm-usage")
  5. options.addArguments("--ignore-ssl-errors=yes")
  6. options.addArguments("--ignore-certificate-errors")
  7. options.addArguments("--headless")
  8. ChromeDriver(options).use {
  9.     get("https://www.baidu.com")
  10. }
复制代码
小工具

获取欣赏器和驱动的版本号
  1. println(ChromiumLoader.getChromeDriverVersion(path))
  2. println(ChromiumLoader.getChromeVersion(path))
复制代码
2.Headless Chrome

2.1 情况搭建

如果你使用了 DownloadChrome 项目则可以跳过该章节
2.1.1 安装Chrome

Windows : 直接在 Chrome/Chromium  官网下载。保举使用 Chromium 开箱即用。
汗青版本:


  • Chromium汗青版本第三方版本统计: 根本包罗驱动版本
  • 官方汗青快照版: 根本包罗驱动版本

    • 选择您的平台:Mac、Win、Linux、ChromiumOS
    • 选择您想要使用的 Chromium 内部版本号

      • LAST_CHANGE文件中提到了最新的

    • 下载包罗 Chromium 的 zip 文件
    • 内里有一个二进制可实验文件可以运行

怎样指定打开的欣赏器,而不是默认的欣赏器 :

  • 通过将驱动放在你欣赏器地点的文件夹内,并设置 System.setProperty("webdriver.chrome.driver","驱动地点"); 即可
  • 通过代码举行设置
  1. System.setProperty("webdriver.chrome.driver","bin path:驱动地址")
  2. ChromeOptions options = new ChromeOptions();
  3. options.setBinary("bin path: 浏览器的执行文件");
  4. ebDriver driver = new ChromeDriver(options);
复制代码

linux: 请百度,我使用的是Ubuntu 以是我直接百度的 Ubuntu Ser ver 安装 Chrome

Linux : 安装chrome headless CHATGPT
Chrome Headless实际上是Chrome欣赏器的无界面版本,可以通过下令行举行利用。以下是在Linux体系中安装Chrome Headless的步调:

  • 确认体系已安装Google Chrome欣赏器,如果没有,可以使用以下下令安装:
    1. sqlCopy codesudo apt update
    2. sudo apt install google-chrome-stable
    复制代码
  • 安装Chromium欣赏器所需的依靠项:
    1. sqlCopy codesudo apt update
    2. sudo apt install -y unzip libgconf-2-4 libnss3-dev libfontconfig1
    复制代码
  • 下载ChromeDriver:
    1. bashCopy codewget https://chromedriver.storage.googleapis.com/91.0.4472.101/chromedriver_linux64.zip
    2. unzip chromedriver_linux64.zip
    3. sudo mv chromedriver /usr/local/bin/
    4. sudo chown root:root /usr/local/bin/chromedriver
    5. sudo chmod +x /usr/local/bin/chromedriver
    复制代码
  • 启动Chrome欣赏器,并设置Headless模式:
    1. cssCopy code
    2. google-chrome-stable --headless --disable-gpu --no-sandbox --remote-debugging-port=9222
    复制代码
  • 如今您可以使用Chrome欣赏器和Headless模式举行利用。比方,您可以使用Selenium WebDriver举行主动化测试或网络爬虫。
注意:请注意安全标题。在生产情况中使用Chrome Headless时,请确保采取得当的安全步调,如限定访问Chrome欣赏器的端口或禁用某些Chrome欣赏器的功能
2.1.2 启动欣赏器

打开 Chromestatus 网站
  1. # chrome 是二进制文件不是命令,你可以打开Chrome的安装目录找到
  2. # 或者新建一个 Chrome 快捷方式,在快捷方式的属性里找到 快捷方式-目标 添加以下参数
  3. # --user-data-dir=D:\Chrome\user1 这是设置缓存目录的参数
  4. chrome --headless --disable-gpu --remote-debugging-port=9222 https://www.chromestatus.com
复制代码
2.1.3 下载chromedriver

找到对应欣赏器版本的驱动
官方网站:http://chromedriver.storage.googleapis.com/index.html
2.1.4 设置 chromedriver 的情况变量

在情况变量内里的 Path 添加 chromedriver 地点文件夹的路径。注意可以不设置
2.1.5 添加依靠

注意第一个的版本必须是最新的否则大概与驱动不匹配。第二个依靠可以不引入,如果发生了非常再引入也可以
  1. <dependency>
  2.     <groupId>org.seleniumhq.selenium</groupId>
  3.     <artifactId>selenium-java</artifactId>
  4.     <!--<version>3.4.0</version>-->
  5.     <version>4.7.2</version>
  6. </dependency>
  7. <!-- https://mvnrepository.com/artifact/com.google.guava/guava -->
  8. <dependency>
  9.     <groupId>com.google.guava</groupId>
  10.     <artifactId>guava</artifactId>
  11.     <version>24.1-jre</version>
  12. </dependency>
复制代码
2.1.6 代码启动欣赏器

https://blog.csdn.net/qq_22003641/article/details/79137327
https://blog.csdn.net/dengjie811227/article/details/102292146
https://www.cnblogs.com/eastonliu/p/9102239.html
https://blog.csdn.net/erhuobuer/article/details/108680617
  1. //驱动地址: 如果不设置环境变量则需要设置驱动地址
  2. //如果想要打开特点的浏览器,就把驱动放在那个浏览器的所在文件夹内,比如要打开Chromium 就放在 Chromium 的文件夹内
  3. System.setProperty("webdriver.chrome.driver","/chromedriver");
  4. // 设置驱动
  5. ChromeOptions options=new ChromeOptions();
  6. //设置 chrome 的无头模式
  7. options.addArguments("--headless");
  8. options.addArguments("--disable-gpu");
  9. options.addArguments("--no-sandbox");
  10. options.addArguments("--disable-dev-shm-usage");
  11. options.addArguments("--start-maximized");
  12. //因为报表页面必须滚动才能全部展示,这里直接给个很大的高度
  13. options.addArguments("--window-size=1280,4300");
  14. //设置用户目录
  15. options.addArguments(" --user-data-dir=D:\\Chrome\\user1");
  16. // 创建webdriver驱动
  17. WebDriver driver = new ChromeDriver(options);
  18. //注意 UA为 User-Agent: selenium/4.8.3 (java windows)
  19. // 访问网页
  20. webDriver.get(url);
  21. // Selenium提供了8种定位方式。请通过 By这个类查看
  22. //clear() 清除文本。sendKeys(*value) 模拟按键输入。click() 单击元素。submit()方法用于提交表单
  23. // 获取输入框,输入selenium
  24. driver.findElement(By.id("kw")).sendKeys("selenium");
  25. // 获取“百度一下”按钮,进行搜索
  26. driver.findElement(By.id("su")).click();
  27. //模拟键盘
  28. //WebElement 对象.sendKeys(Keys.SPACE)//注意可以用组合键
  29. //执行javascript 可以直接设置localstroage,cookie等方式。不过拼字符串实在太麻烦
  30. String token = "localStorage.setItem('cloud.token','{"val":"5d31f455-8ed5-4ebe-80d1-760665df452c","expires":1584531900299}')";
  31. ((JavascriptExecutor)webDriver).executeScript(token);
  32. //定位section元素
  33. WebElement element =  webDriver.findElement(By.tagName("section"));
  34. Point p = element.getLocation();
  35. int width = element.getSize().getWidth();
  36. int height = element.getSize().getHeight();
  37. Rectangle rec = new Rectangle(p.getX(),p.getY(),height,width);
  38. //截取全屏
  39. File scrFile  = ((TakesScreenshot)webDriver).getScreenshotAs(OutputType.FILE);
  40. //在全屏图片下裁剪
  41. BufferedImage img = ImageIO.read(scrFile);
  42. BufferedImage dest = img.getSubimage(p.getX(), p.getY(),rec.getWidth(),rec.getHeight());
  43. ImageIO.write(dest, "png", scrFile);
  44. //拷贝文件
  45. FileUtils.copyFile(scrFile , new File("a.png"));
  46. log.info("截图完成");
  47. //退出
  48. webDriver.quit();
复制代码
  1. WebDriver driver = new ChromeDriver();    //Chrome浏览器
  2. WebDriver driver = new FirefoxDriver();   //Firefox浏览器
  3. WebDriver driver = new EdgeDriver();      //Edge浏览器
  4. WebDriver driver = new InternetExplorerDriver();  // Internet Explorer浏览器
  5. WebDriver driver = new OperaDriver();     //Opera浏览器
  6. WebDriver driver = new PhantomJSDriver();   //PhantomJS
复制代码
2.2 报错

如果报错请重要排查三个缘故原由


  • chrome 版本是否与驱动大版本同等,发起都升级为最新版
  • java 引入的jar库是否是最新版
  • Exception in thread "main" org.openqa.selenium.SessionNotCreatedException: Could not start a new session. Response code 500. Message: unknown error: failed to write first run file
   这个非常通常是由于Selenium驱动步调无法启动欣赏器会话导致的,大概是由于驱动步调版本与欣赏器版本不兼容,大概是由于缺少欣赏器二进制文件或用户权限不敷等缘故原由。 如果你设置了用户缓存目次请给予java步调权限
  

  • org.openqa.selenium.UnhandledAlertException: unexpected alert open: {Alert text : Hello World!}
   这个非常通常是由于在实验测试期间,页面上出现了未预期的弹窗,比方告诫框、确认框或提示框等。
  要办理这个标题,您可以实验以下几个步调:
  

  • 使用switchTo().alert()方法切换到告诫弹窗并处置惩罚它。比方,您可以使用accept()方法点击弹窗上的“确定”按钮,或使用dismiss()方法点击弹窗上的“取消”按钮。
  • 在实验任何大概引发告诫弹窗的利用之前,可以使用driver.switchTo().alert()方法来查抄页面是否有告诫弹窗。如果存在,可以通过上述方法来处置惩罚它。
  

  • NoSuchElementException:当实验访问不存在的元素时,会引发此非常。
  • TimeoutException:当 Selenium 超时并无法在指定时间内找到所需的元素或页面元素时,会引发此非常。
  • StaleElementReferenceException:当实验访问一个已经被删除或不再可用的元素时,会引发此非常。
  • ElementNotVisibleException:当实验访问一个埋伏的元素时,会引发此非常。
  • ElementNotInteractableException:当实验与无法与之交互的元素举行交互时,会引发此非常。
  • InvalidSelectorException:当选择器无效或不符合语法规则时,会引发此非常
  • NoSuchWindowException:当实验访问不存在的窗口时,会引发此非常。
  • UnhandledAlertException:当出现未处置惩罚的告诫弹窗时,会引发此非常。
  • SessionNotCreatedException:当欣赏器会话无法启动时,会引发此非常。
  • WebDriverException:这是一个通用非常,大概由各种缘故原由引起,比方网络毗连标题、署理设置错误等。
  • SessionNotCreatedException:当欣赏器会话无法创建或启动时,会引发此非常。大概是由于缺少驱动步调或欣赏器版本不兼容等缘故原由。
  • TimeoutException:当 Selenium 无法在指定的时间内实验利用时,会引发此非常。比方,当页面加载过慢或元素不可见时。
  • NoSuchWindowException:当实验访问不存在的欣赏器窗口时,会引发此非常。
  • NoSuchSessionException:当实验访问已经关闭的欣赏器会话时,会引发此非常。
  • ElementNotVisibleException:当实验访问不可见的元素时,会引发此非常。
  • ElementNotSelectableException:当实验选择不支持选择利用的元素时,会引发此非常。
  • InvalidSelectorException:当选择器无效或不符合语法规则时,会引发此非常。
  • JavascriptException:当在 JavaScript 代码中发生错误时,会引发此非常。
  • UnhandledAlertException:当出现未处置惩罚的告诫弹窗时,会引发此非常。
2.3 项目实例

2.3.0 设置WebDriver

DesiredCapabilities 和 ChromeOptions 都是用于设置 WebDriver 的选项和设置的类。它们之间的区别在于:

  • DesiredCapabilities 是 Selenium WebDriver 中的一个通用选项类,可以用于设置全部支持的欣赏器的选项。而 ChromeOptions 是针对 Chrome 欣赏器的选项类,只能用于设置 Chrome 欣赏器的选项。
  • DesiredCapabilities 可以设置的选项包罗欣赏器范例、版本、利用体系、页面加载战略、署理等。而 ChromeOptions 可以设置的选项包罗二进制文件路径、启动参数、扩展、调试端口等。
  • 在使用 Chrome 欣赏器时,您通常须要使用 ChromeOptions 来设置选项,比方指定欣赏器的二进制文件路径或设置启动参数。而在使用其他欣赏器时,您大概须要使用 DesiredCapabilities 来设置选项。
  1. // 创建一个 ChromeOptions 对象
  2. ChromeOptions options = new ChromeOptions();
  3. // 设置 Chrome 浏览器的二进制文件路径
  4. options.setBinary("/usr/bin/google-chrome");
  5. // 设置启动参数
  6. options.addArguments("--disable-extensions");
  7. // 创建一个 DesiredCapabilities 对象
  8. DesiredCapabilities capabilities = DesiredCapabilities.chrome();
  9. // 设置 ChromeOptions 选项
  10. capabilities.setCapability(ChromeOptions.CAPABILITY, options);
  11. // 使用 DesiredCapabilities 对象创建 ChromeDriver
  12. // 也可以使用 options 直接设置
  13. WebDriver driver = new ChromeDriver(capabilities);
  14. // 访问网站
  15. driver.get("https://www.example.com");
  16. // 关闭浏览器
  17. driver.quit();
复制代码
2.3.1 控制欣赏器

  1. //控制浏览器
  2. // 设置全屏
  3. driver.manage().window().fullscreen();
  4. //获取当前窗口相对于屏幕左上角的位置。
  5. System.out.println(driver.manage().window().getPosition());
  6. //获取浏览器大小
  7. System.out.println(driver.manage().window().getSize());
  8. //最小化
  9. driver.manage().window().minimize();
  10. //最大化
  11. driver.manage().window().maximize();
  12. //设置窗口大小
  13. driver.manage().window().setSize(...);
复制代码
2.3.2 模拟鼠标



  • ActionChains 模拟鼠标
  • Actions action = new Actions(driver);
  • contextClick() 右击
  • clickAndHold() 鼠标点击并控制
  • doubleClick() 双击
  • dragAndDrop() 拖动
  • release() 开释鼠标
  • dragAndDrop(source, target):模拟鼠标拖拽 拖拽到某个元素然后松开
  • dragAndDropBy(source, xoffset, yoffset):模拟鼠标拖拽 拖拽到某个坐标然后松开
  • moveToElement() 模拟鼠标悬停
  • clickAndHold() 方法用于模拟鼠标悬停利用, 在调用时须要指定元素定位
  • perform() 实验全部Actions中存储的活动
  • build() 构建全部利用
  • 模拟鼠标移动 它是模拟鼠标移动而不是真实的鼠标移动

    • moveByOffset()
    • moveToElement
    • 示例
    • action.clickAndHold(WebElement对象).build().perform();

2.3.3 汗青纪录

  1. //允许驱动程序访问浏览器的历史记录并导航到给定的URL。
  2. WebDriver.Navigation navigate = driver.navigate();
  3. navigate.refresh();//刷新
  4. navigate.back();//回退
  5. navigate.forward();//向前
  6. navigate.to(..);//跳转URL
复制代码
2.3.4 窗口切换

  1. //获取当前打开窗口的所有句柄
  2. Set<String> handles = driver.getWindowHandles();
  3. //获取当前窗口的句柄(String类型)
  4. String handle = driver.getWindowHandle();
  5. //跳转页面,通过窗口句柄,这里使用第一个句柄
  6. driver.switchTo().window(handles.stream().findFirst().orElse(""));
  7. //新开一个窗口
  8. driver.switchTo().newWindow(WindowType.TAB);
  9. driver.get("https://bilibili.com");
复制代码
2.3.5 Cookie

  1. //Cookie 操作
  2. Set<Cookie> cookies = driver.manage().getCookies();
  3. driver.manage().addCookie(null);
  4. driver.manage().deleteAllCookies();
  5. driver.manage().deleteCookieNamed("");
  6. driver.manage().getCookieNamed("");
复制代码
2.3.6 等候页面加载

我们经常会碰到用selenium利用页面上某个元素的时间, 须要等候页面加载完成后, 才气利用。 否则页面上的元素不存在,会抛出非常。大概碰到AJAX异步加载,我们须要等候元素加载完成后, 才气利用。
2.3.6.1 页面加载战略

默认Chrome 欣赏器下 全部的元素定位是在页面被完全加载后(页面tab不再转圈)才开始。实验 get 后的代码
在 Selenium 中,可以通过 WebDriver 接口的 manage() 方法来设置页面加载战略。页面加载战略是指当页面处于加载状态时,WebDriver 应该等候多长时间才应该抛出 TimeoutException 非常。以下是几种页面加载战略:

  • normal:这是默认的页面加载战略。它会等候页面加载完毕,并在超时时间内等候。
  • eager:这个战略会实验尽快地完成页面加载,并在超时时间内等候。如果页面在超时时间内没有加载完毕,它会抛出 TimeoutException 非常。
  • none:这个战略不会等候页面加载完毕,并立即返回。如果您想在页面加载完毕之前实验某些利用,则可以使用这个战略。请注意,如果您在等候利用之前实验访问页面元素,则大概会抛出 StaleElementReferenceException 非常。
1. 元素出现但页面未加载完毕
首选须要明白的一点是,如果什么都不设置,通常,以chrome欣赏器为例,全部的元素定位是在页面被完全加载后(页面tab不再转圈)才开始。
偶尔间着实想要的元素已经加载出来了,只是页面还在加载其他东西,比方图片,此时若不想继续等候直接实验元素定位利用,则须要在创建driver的时间设置页面加载战略:
当调用driver.get(“https://xxxx.xxx.xxx”)来访问某页面时,get方法通常会壅闭欣赏器直到页面完全加载后才实验反面的动作,若一个页面加载过慢,则会导致get方法不停壅闭。偶尔间渴望页面在加载过程中就开始检测元素是否存在,而不是比及页面加载完了才开始检测,想要实现这个效果,可以用DesiredCapabilities类下的setPageLoadStrategy方法(Python,Chrome欣赏器) 设置页面加载战略为 none,以便在页面加载期间实验其他利用。接下来,我们使用 WebDriverWait 类等候元素的可见性。在这里,我们等候了最多 10 秒钟,直到元素可见。如果元素在这个时间内没有可见,它会抛出 TimeoutException 非常。
  1. ChromeOptions options = new ChromeOptions();
  2. options.setPageLoadStrategy(PageLoadStrategy.NONE);
  3. WebDriver driver = new ChromeDriver(options);
  4. driver.get("https://example.com");
  5. //等待页面30s
  6. WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30));
  7. //指定要等待的元素。
  8. WebElement element = wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("example-id")));
  9. System.out.println("Page element is visible: " + element.isDisplayed());
  10. driver.quit();
复制代码
2.3.6.2 隐示等候

隐式等候是一种全局等候,它在 WebDriver 对象实例化后设置一次即可,对于整个 WebDriver 实例的生命周期都起作用。
隐式等候的作用是让 WebDriver 在查找页面元素时等候一段时间,如果在等候时间内找到了指定的元素,则立即实验反面的利用。如果等候时间竣事仍未找到指定的元素,则抛出 NoSuchElementException 非常。这种等候方式实用于那些须要加载一些资源(比方 JavaScript、图片等)的页面,由于这些资源大概会影响页面元素的加载速率。driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
  1. // 设置 Chrome 浏览器驱动路径
  2. System.setProperty("webdriver.chrome.driver", "/path/to/chromedriver");
  3. // 创建 ChromeDriver 实例
  4. WebDriver driver = new ChromeDriver();
  5. // 设置隐式等待时间为 10 秒
  6. driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
  7. // 访问网站
  8. driver.get("https://www.example.com");
  9. // 查找并操作页面元素
  10. WebElement element = driver.findElement(By.id("example-id"));
  11. element.click();
  12. // 关闭浏览器
  13. driver.quit();
复制代码
2.3.6.3 体现等候

体现等候是一种正确控制等候时间的等候方式,它可以让我们在指定时间内等候某个条件的创建。与隐式等候差别,显式等候是在代码中手动编写的,须要指定等候的最长时间,以及判定条件的范例和条件值。当等候时间内判定条件创建,则立即实验后续的利用,否则在等候时间到达后抛出非常。
Selenium WebDriver 提供了一个名为 WebDriverWait 的类来实现显式等候。使用 WebDriverWait 可以指定等候的最长时间和等候条件,常用的等候条件包罗 elementToBeClickable、presenceOfElementLocated、visibilityOfElementLocated 等等。
  1. // 设置 Chrome 浏览器驱动路径
  2. System.setProperty("webdriver.chrome.driver", "/path/to/chromedriver");
  3. // 创建 ChromeDriver 实例
  4. WebDriver driver = new ChromeDriver();
  5. // 访问网站
  6. driver.get("https://www.example.com");
  7. // 显式等待页面元素加载完成
  8. WebDriverWait wait = new WebDriverWait(driver, 10);
  9. //ExpectedConditions.visibilityOfElementLocated 方法来指定等待条件为指定元素的可见性。如果等待时间内指定元素的可见性成立,则 wait.until 方法立即返回找到的页面元素,并执行后续的操作;如果等待时间到达后仍未找到指定元素,则抛出 TimeoutException 异常。
  10. //ExpectedConditions 提供的各种判断条件。WebElement element = wait.until(ExpectedConditions.condition());
  11. WebElement element = wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("example-id")));
  12. // 对页面元素进行操作
  13. element.click();
  14. // 关闭浏览器
  15. driver.quit();
复制代码
2.3.6.4 流通等候

FluentWait是WebDriver提供的另一种等候方式,用于在指定时间内以肯定的时间隔断不停地举行条件判定,直到超时大概条件创建为止。与WebDriverWait相比,FluentWait更加机动,可以根据具体需求自界说等候时间和等候条件,实用于一些比力特别的场景。
使用FluentWait须要先界说等候条件(ExpectedCondition对象)和等候时间隔断,然后将它们传入FluentWait的构造方法中,末了调用until方法即可。与体现等候的 WebDriverWait类似,区别是WebDriverWait已经设置好几个等候条件,而流通等候 FluentWait可以本身设置等候条件。
  1. FluentWait<WebDriver> wait = new FluentWait<>(driver)
  2.         .withTimeout(Duration.ofSeconds(10)) // 设置超时时间为10秒
  3.         .pollingEvery(Duration.ofSeconds(1)) // 每隔1秒检测一次
  4.         .ignoring(NoSuchElementException.class); // 忽略NoSuchElementException异常
  5. WebElement element = wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("example-id")));
复制代码
2.3.7 定位方式


  • 根据元素ID举行定位
  1. driver.findElement(By.id("element-id"));
复制代码

  • 根据元素名称举行定位
  1. driver.findElement(By.name("element-name"));
复制代码

  • 根据链接文本举行定位
  1. driver.findElement(By.linkText("link-text"));
复制代码

  • 根据部门链接文本举行定位
  1. driver.findElement(By.partialLinkText("partial-link-text"));
复制代码

  • 根据元素标署名称举行定位
  1. driver.findElement(By.tagName("tag-name"));
复制代码

  • 根据CSS选择器举行定位
  1. driver.findElement(By.cssSelector("selector"));
复制代码

  • 根据XPath表达式举行定位
  1. driver.findElement(By.xpath("xpath-expression"));
复制代码

  • 根据元素类名举行定位
  1. driver.findElement(By.className("class-name"));
复制代码
须要注意的是,差别的定位方式的服从和实用场景也差别,须要根据实际情况选择符合的定位方式。别的,还可以使用复合定位方式,将多种定位方式组合使用来定位元素。
2.3.7.1 css定位

根据CSS选择器举行定位是Selenium中常用的一种方式,可以通过使用 By.cssSelector() 方法实现。
在使用CSS选择器举行定位时,可以通过元素的id、class、属性和标署名称等信息来定位元素。下面是一些常用的CSS选择器示例:

  • 通过id定位元素
  1. driver.findElement(By.cssSelector("#element-id"));
复制代码

  • 通过class定位元素
  1. driver.findElement(By.cssSelector(".element-class"));
复制代码

  • 通过属性定位元素
  1. driver.findElement(By.cssSelector("[attribute-name='attribute-value']"));
复制代码

  • 通过标署名称定位元素
  1. driver.findElement(By.cssSelector("tag-name"));
复制代码

  • 通过组合选择器定位元素
  1. driver.findElement(By.cssSelector("tag-name#element-id.attribute-name[attribute-value]"));
复制代码

  • 子选择器
使用>符号来选择作为某元素子元素的元素,比方:
  1. driver.findElement(By.cssSelector("parent-element > child-element"));
复制代码

  • 后代选择器
使用空格符号来选择某元素后代元素,比方:
  1. driver.findElement(By.cssSelector("parent-element child-element"));
复制代码

  • 相邻兄弟选择器
使用+符号来选择某元素之后相邻的兄弟元素,比方:
  1. driver.findElement(By.cssSelector("preceding-element + sibling-element"));
复制代码

  • 通用兄弟选择器
使用~符号来选择某元素之后的兄弟元素,比方:
  1. driver.findElement(By.cssSelector("preceding-element ~ sibling-element"));
复制代码
须要注意的是,在使用CSS选择器举行定位时,须要确保选择器的唯一性,否则大概会定位到不符合预期的元素。同时,还须要注意选择器的复杂度和性能标题。在定位复杂的元素时,发起优先思量使用XPath表达式举行定位。
2.3.8 获取页面源代码


  • Java
  1. driver.getPageSource()
复制代码

  • JS
  1. // 注入JavaScript脚本
  2. String script = "return document.documentElement.outerHTML;";
  3. String pageSource = (String) ((JavascriptExecutor) driver).executeScript(script);
复制代码
2.3.9 打开类似的欣赏器(来自于网络)

在使用 Selenium 举行主动化测试时,如果渴望在每次运行脚本时打开类似的欣赏器,可以使用 WebDriver 的 SessionId 属性来实现。
起首,打开欣赏器并实验测试代码,可以通过 driver.getSessionId() 方法获取当前欣赏器会话的 SessionId 值。然后,在下一次运行测试脚本时,可以使用 WebDriver 的 attach 方法,传入上一次运行时获取的 SessionId 值,即可重新打开类似的欣赏器并继续测试。
以下是使用 Java 实现上述方法的示例代码:
  1. // 第一次打开浏览器并执行测试代码
  2. WebDriver driver = new ChromeDriver();
  3. driver.get("https://www.example.com");
  4. String sessionId = driver.getSessionId().toString();
  5. driver.quit();
  6. // 下一次打开相同的浏览器并继续测试
  7. ChromeOptions options = new ChromeOptions();
  8. options.setExperimentalOption("debuggerAddress", "localhost:9222");
  9. WebDriver driver = new ChromeDriver(options);
  10. driver = new ChromeDriver(options);
  11. driver.get("https://www.example.com");
  12. RemoteWebDriver remoteWebDriver = (RemoteWebDriver) driver;
  13. remoteWebDriver.executeScript("window.open('about:blank', '_blank');");
  14. remoteWebDriver.switchTo().window(remoteWebDriver.getWindowHandles().stream().skip(1).findFirst().get());
  15. remoteWebDriver.get("http://localhost:9222/json/new?"+sessionId);
  16. remoteWebDriver.switchTo().window(remoteWebDriver.getWindowHandles().stream().findFirst().get());
复制代码
须要注意的是,在上述代码中,须要事先在下令行启动一个 Chrome 欣赏器实例,并启用远程调试模式。在启动欣赏器实例时,须要使用 --remote-debugging-port 参数指定一个空闲的端标语,如 9222。在运行测试脚本时,须要将 ChromeOptions 实例的 debuggerAddress 属性设置为 localhost:9222,体现毗连到远程调试端口。在毗连上一个已有的欣赏器实例后,须要调用 window.open() 方法打开一个新的空缺窗口,并切换到该窗口,末了通过 http://localhost:9222/json/new?sessionId URL 加载之前会话的 SessionId 值,以规复之前欣赏器会话的状态。
2.3.10 启动参数设置

  1. // Chrome
  2. options = new ChromeOptions();
  3. // 启动就最大化
  4. // options.addArguments("start-fullscreen");
  5. // options.addArguments("--start-maximized");
  6. // 禁用浏览器弹出窗口拦截器。
  7. options.addArguments("--disable-popup-blocking");
  8. // 取消沙盘模式
  9. options.addArguments("no-sandbox");
  10. //禁用 Chrome 的 /dev/shm 空间,在一些低配服务器上可能会导致 Chrome 崩溃。
  11. options.addArguments("--disable-dev-shm-usage");
  12. // 禁止扩展
  13. options.addArguments("disable-extensions");
  14. // 禁止默认浏览器检查
  15. options.addArguments("no-default-browser-check");
  16. options.addArguments("about:histograms");
  17. options.addArguments("about:cache");
  18. // 设置浏览器固定大小
  19. // 注意:设定了浏览器固定大小后,浏览器打开后浏览器的位置可能会变到其他位置,因此可以使用设置刘浏览器的位置方法和设置浏览器的大小方法一起使用;driver.manage().window().maximize();
  20. options.addArguments("--window-size=1600,900");
  21. // chrome正受到自动测试软件的控制
  22. options.addArguments("disable-infobars");
  23. //谷歌插件 注意对于路径都要使用 new File(...).getCanonicalPath();或者使用相对路径
  24. options.addExtensions(new File("/path/to/extension.crx"))
  25. options.setBinary(new File("/path/to/chrome"));
  26. // 禁用 GPU 硬件加速,可以避免一些图形渲染问题和内存泄漏问题。
  27. options.addArguments("--disable-gpu");
  28. //用户工作目录(缓存地址)
  29. options.addArguments("--user-data-dir="+new File("./cache/user/user1").getCanonicalPath());
  30. //每当我们使用selenium启动chrome浏览器时,将为每个新会话创建一个新实例/临时配置文件。如果我们要加载默认的Chrome浏览器或自定义Chrome配置文件,
  31. //我们可以将'user-data-dir'参数传递给ChromeOptions,这是Chrome命令行切换,告诉Chrome使用哪个配置文件。如果路径不存在,chrome将在指定的路径中创建新的配置文件。
  32. options.addArgument("user-data-dir=/path/to/your/custom/profile");
  33. //无头浏览器
  34. options.addArguments("--headless");
  35. //禁用浏览器的同源策略,允许在同一网站内加载来自多个域的资源。
  36. options.addArguments("--disable-web-security");
  37. //设置浏览器的 User-Agent 字符串,可以用来伪装浏览器类型和版本。
  38. options.addArguments("--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3");
  39. //性能优化
  40. options.addArguments("--disable-extensions");//禁用 Chrome 扩展程序。
  41. options.addArguments("--no-sandbox");//高危
  42. options.addArguments("--blink-settings=imagesEnabled=false");//禁用浏览器中的图片加载,可以加快浏览器的渲染速度。
  43. options.addArguments("--disable-features=IsolateOrigins,site-per-process");//高危
  44. options.addArguments("--disable-features=VizDisplayCompositor");//高危
  45. options.addArguments("--disable-features=RendererCodeIntegrity");//高危
  46. options.addArguments("--disable-blink-features=AutomationControlled");// 高危
  47. options.addArguments("--mute-audio");// 禁用浏览器声音。
  48. options.setExperimentalOption("excludeSwitches", Collections.singletonList("enable-automation")); //禁用自动化标识
  49. options.setExperimentalOption("useAutomationExtension", false);// 禁用拓展程序
  50. //不禁用 CSS 的情况下,将网页加载为无样式的版本,从而提高性能。注意这设置了UA
  51. options.addArguments("--user-agent=Googlebot");
  52. options.addArguments("--disable-javascript");//禁用JavaScript
  53. options.addArguments("--disable-blink-features=CSSAnimations");//禁用CSS动画
  54. options.addArguments("--disable-blink-features=CSSTransitions");//禁用CSS过渡
复制代码
  其他
  

  • --disable-notifications: 禁用欣赏器关照。
  • --disable-popup-blocking: 禁用欣赏器弹出窗口拦截器。
  • --disable-default-apps: 禁用默认应用步调。
  • --hide-scrollbars: 埋伏欣赏器滚动条。
  • --mute-audio: 禁用欣赏器声音。
  • --log-level=3: 设置欣赏器的日志日志级别为 WARNING。
  • --disable-logging: 禁用欣赏器日志日志输出。
  • setExperimentalOption("useAutomationExtension", false): 禁用 Chrome 扩展步调,用于克制一些主动化测试过程中出现的标题。
  • setExperimentalOption("excludeSwitches", Collections.singletonList("enable-automation")): 禁用 Chrome 的主动化开关,也是用于克制主动化测试过程中出现的标题。这行代码会禁用 Chrome 的主动化开关。当启用主动化测试时,Chrome 会主动开启一个特别的标记“enable-automation”,这个标记大概会导致一些网站活动非常大概被检测到并制止主动化测试。因此,在实验主动化测试时,禁用此开关可以克制这些标题的发生。
  • setExperimentalOption("prefs", prefs): 设置 Chrome 的偏好选项。方法可以设置 Chrome 欣赏器的偏好选项。在这个方法中,prefs参数是一个 Map<String, Object> 对象,此中包罗一些键值对,用于设置欣赏器的偏好选项。
    偏好选项可以用来控制欣赏器的一些活动,比方下载文件的默认路径、启用 Flash 插件、禁用主动添补表单等。通过设置偏好选项,可以使主动化测试脚本更加机动和可控。
  • --disable-browser-side-navigation: 禁用欣赏器侧边导航。
  • --disable-features=VizDisplayCompositor: 禁用 Chrome 的某个功能,可以进步 Chrome 的性能。这个功能用于渲染页面的图形界面,禁用它可以进步 Chrome 的性能,但大概会影响页面的体现效果。
  • --disable-features=RendererCodeIntegrity: 禁用 Chrome 的某个功能,可以进步 Chrome 的性能。这个功能用于掩护渲染器历程不被攻击者使用,但它会斲丧一些额外的性能,禁用它可以进步 Chrome 的性能。
  • --blink-settings=imagesEnabled=false: 禁用欣赏器中的图片加载,可以加快欣赏器的渲染速率。
  • --disable-blink-features=AutomationControlled: 禁用 Blink 引擎主动化控制的功能。可以禁用 Chrome 欣赏器中 Blink 引擎的主动化控制功能,使得一些原来受到限定的利用变得可行。但须要注意的是,禁用这个功能大概会导致一些不安全的利用被实验,因此须要审慎使用。
  • --disable-features=IsolateOrigins,site-per-process: 禁用 Chrome 的网站隔离和历程隔离功能,可以进步性能和镌汰内存占用。
  • --remote-debugging-port=9222: 开启 Chrome 的远程调试端口。
  • --disable-extensions: 禁用 Chrome 扩展步调。
  • --disable-web-security: 禁用 Chrome 的同源战略,答应在同一网站内加载来自多个域的资源。
  • --disable-features=CSSGridLayout。启用该参数后,Chrome 欣赏器将不会使用 CSS 网格结构来排版页面,大概会进步页面加载速率和欣赏器性能,但也会导致网页排版样式非常。
  2.3.11 实验 JS

在Java中使用Selenium实验JavaScript可以使用JavascriptExecutor接口。这个接口可以在Selenium WebDriver对象上使用
  1. System.setProperty("webdriver.chrome.driver", "path/to/chromedriver");
  2. WebDriver driver = new ChromeDriver();
  3. driver.get("http://www.example.com");
  4. JavascriptExecutor js = (JavascriptExecutor) driver;
  5. // 在页面上执行JavaScript
  6. js.executeScript("alert('Hello World!');");
  7. driver.quit();
复制代码
怎样处置惩罚js的返回值: 吸取返回值,根据 Class 举行欺凌转换
  1. Object o = js.executeScript("return 1+1");
  2. //class java.lang.Long
  3. System.out.println(o.getClass());
  4. if (o instanceof  Long){
  5.     Long l = (Long)o;
  6.     // ........
  7. }
复制代码
2.3.12 关闭日志日志

您使用的是其他日志框架,比方 log4j 或 logback,则须要查找该框架提供的特定方法或设置来关闭日志纪录。通常,这些框架都提供了一些级别设置,您可以将其设置为“OFF”或“ERROR”来关闭日志纪录。
2.3.13 截图

  1. //截取全屏
  2. File scrFile  = ((TakesScreenshot)webDriver).getScreenshotAs(OutputType.FILE);
  3. //在全屏图片下裁剪
  4. BufferedImage img = ImageIO.read(scrFile);
  5. BufferedImage dest = img.getSubimage(p.getX(), p.getY(),rec.getWidth(),rec.getHeight());
  6. ImageIO.write(dest, "png", scrFile);
  7. //拷贝文件
  8. FileUtils.copyFile(scrFile , new File("a.png"));
  9. log.info("截图完成");
复制代码


  • File screenshotFile = ((TakesScreenshot) webDriver).getScreenshotAs(OutputType.FILE);
这行代码使用了 TakesScreenshot 接口中的 getScreenshotAs 方法来获取元素的屏幕截图。 getScreenshotAs 方法继续一个参数,即 OutputType,用于指定截图的范例。在这里,我们使用了 OutputType.FILE 来指定截图以文件情势返回。
TakesScreenshot 接口是一个由 WebDriver 实现的接口,它答应您获取 WebDriver 实例的屏幕截图。通过将 WebDriver 实例转换为 TakesScreenshot 接口范例,您可以调用 getScreenshotAs 方法来获取屏幕截图。但是,请注意,如果您转达的是一个 WebElement 对象而不是 WebDriver 实例,那么将会截取该元素的屏幕截图,而不是整个页面的截图。
别的,由于 getScreenshotAs 方法返回的是一个 File 范例的对象,您须要使用 Java 的 FileUtils 类或其他类库来将截图生存到当地文件中。在上面的代码中,我们使用了 Apache Commons IO 库中的 FileUtils 类来复制文件
2.3.14 插件(来自网络)

控制欣赏器插件的方式取决于您使用的欣赏器和插件范例。下面是一些常见欣赏器插件的控制方式:

  • AdBlock Plus:使用 AdBlock Plus 的 org.openqa.selenium.chrome.ChromeOptions 类和 addExtensions 方法来加载插件。示例代码如下:
  1. javaCopy codeChromeOptions options = new ChromeOptions();
  2. options.addExtensions(new File("/path/to/adblockplus.crx"));
  3. WebDriver driver = new ChromeDriver(options);
复制代码

  • uBlock Origin:使用 uBlock Origin 的 org.openqa.selenium.chrome.ChromeOptions 类和 addExtensions 方法来加载插件。示例代码如下:
  1. javaCopy codeChromeOptions options = new ChromeOptions();
  2. options.addExtensions(new File("/path/to/ublockorigin.crx"));
  3. WebDriver driver = new ChromeDriver(options);
复制代码

  • Firebug:使用 Firefox 的 org.openqa.selenium.firefox.FirefoxProfile 类和 addExtension 方法来加载插件。示例代码如下:
  1. javaCopy codeFirefoxProfile profile = new FirefoxProfile();
  2. File firebug = new File("/path/to/firebug.xpi");
  3. File netExport = new File("/path/to/netExport.xpi");
  4. profile.addExtension(firebug);
  5. profile.addExtension(netExport);
  6. WebDriver driver = new FirefoxDriver(profile);
复制代码
在上面的代码中,我们使用了 Firefox 的 addExtension 方法来加载 Firebug 插件和 NetExport 插件。
请注意,加载欣赏器插件大概会对欣赏器性能产生肯定影响,因此请审慎使用。别的,差别版本的欣赏器和插件大概须要差别的加载方式,请根据您的具体情况举行调解。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

×
登录参与点评抽奖,加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表