selenium 自动化测试工具,可以用 Java 实现对浏览器的操作。结合 Jsoup 和 HttpClient 实现爬虫技术。

导入对应的 maven 依赖:

<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>4.18.1</version>
</dependency>

selenium 是使用 chromeDriver 来驱动浏览器的,需要配置 chromeDriver,在线上环境中需要配置对应的 driver 地址,如果是 docker 部署的项目,那么还需要再 docker 中配置 chromeDriver 的地址,这样效率偏低。

可以使用提供的 selenium 的 docker 容器,连接远程的 chromedriver。

docker run -d -p 4443:4444 -p 7901:7900 --shm-size="2g" selenium/standalone-chrome:latest

4443 是远程连接的端口,7901 是 VNC 可视化的端口。

连接配置

ChromeOptions,配置选项。

ChromeOptions options = new ChromeOptions(); //配置选项
options.setAcceptInsecureCerts(true);
options.addArguments("--no-sandbox");//禁用沙盒模式
options.addArguments("--disable-gpu");// 禁用GPU加速
options.addArguments("--disable-dev-shm-usage");//禁用共享内存分区
options.addArguments("--remote-allow-origins=*"); //不加这个会出现跨域问题    

设置 remote 允许远程跨域,不设置会有 403 forbidden 的报错禁止访问。

WebDriver 核心类

WebDriver 是网页的核心

WebDriver driver = null;
try {
    //连接远程chrome地址
    // chromeDriverPath 是服务器上面的4444端口。
    // http://localhost:4444
    driver = new RemoteWebDriver(new URL(chromeDriverPath), options);
} catch (MalformedURLException e) {
    log.error("连接远程chrome失败");
    throw new RuntimeException(e);
}

需要注意的是云服务器禁用了 4444 端口,将其他端口映射到 docker 中的 4444 端口。

里面包含了操作浏览器的方法。

get(),打开进入某个网页。

**getCurrentUrl()**获取当前的 URL

**getTitle(),**获取当前的网页标题

findelement() 这个是使用比较多的,获取网页的元素。根据 By 语法来获取

getPageSource() 网页的来源

void get(String url);

String getCurrentUrl();

String getTitle();

List<WebElement> findElements(By by);

WebElement findElement(By by);

String getPageSource();

void close();

void quit();

Set<String> getWindowHandles();

String getWindowHandle();

TargetLocator switchTo();

Navigation navigate();

Options manage();

当新建了一个网页 tab 的时候需要更换当前的 driver 句柄。

Set<String> getWindowHandles();

String getWindowHandle();

TargetLocator switchTo();

操作百度的页面

driver.get("https://www.baidu.com/");  //进入到百度的页面去

获取网页的输入框,findElement(),往里面输入 keys 值。

WebElement kw = driver.findElement(By.id("kw"));
kw.sendKeys("如何学习Java");

获取点击搜索按钮,调用 click 进行点击

WebElement bgSBtn = driver.findElement(By.xpath("//*[@id=\"su\"]"));
bgSBtn.click();

有的时候打开网页并不是在本页面进行切换了,而是新打开了一个网页,需要进行 driver 的更新。

String mainWinHandler = driver.getWindowHandle(); //拿到当前的句柄
String popupWinHandler = null;
for (String windowHandle : driver.getWindowHandles()) {  //遍历所有的句柄
         if (!windowHandle.equalsIgnoreCase(mainWinHandler)) {
     popupWinHandler = windowHandle;
  }
}
//拿到新打开网页的句柄,调用driver.swithTo().windows()切换到新的句柄上去。
driver.switchTo().window(popupWinHandler);

By 定位网页的元素

selenium 提供了 抽象类 By 来获取网页中的元素。

可以通过网页的 Id、超链接文本内容、name 属性、tagName、xpath、ClassName、cssSelector 来定位网页的元素。

常用的定位方法就是 Xpath 定位。

在网页中右击,可以拿到 xpath 和对应的 selector 来定位元素。

截图

截图整个网页的图片

File screenshotAs = ((RemoteWebDriver) driver).getScreenshotAs(OutputType.FILE);  //截图文件 

截图某个模块的图片,通过 findElement 找到对应的元素,然后调用截图方法

File screenshotAs = driver.findElement(By.xpath("//*[@id=\"content_left\"]/div[1]/div[1]/a[1]")).getScreenshotAs(OutputType.FILE);

有一些场景,比如要获取网页中的验证码截图,然后返回给前端去展示验证码,需要前端自己输入。

WebElement captchaImg = driver.findElement(By.id("captchaImg"));
File screenshotAs = captchaImg.getScreenshotAs(OutputType.FILE);

拿到官网中的图片验证码了,再通过 base64 传送给前端进行输入。

获取 iframe

有的网页里面可能嵌套了 iframe 元素,iframe 将其他的网页嵌套到当前的网页里面来,比如在开发中将别的网页通过一些方式嵌套进来,这样就可以不用自己开发,做二次开发的时候效率会很高。 嵌套进来之后可能就要涉及到组件通信的一些内容。

https://blog.csdn.net/m0_64378913/article/details/123738209

selenium 不能直接获取 iframe 里面的元素,需要先获取到 iframe 元素,然后才能获取到元素。

//得带并切换到对应的iframe元素里面,这个是在爬取qq的时候用到的
wait.until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(By.id("login_frame")));

获取网页的 cookie 信息

模拟登录网页之后需要向后端发送请求,需要携带对应的 Authorization 请求头,这个就是要从 cookie 中获取。

通过 driver.manag().getCookie() 拿到 cookie 信息。

 Set<Cookie> cookies = driver.manage().getCookies();
            StringBuilder cookie= new StringBuilder();
            for (Cookie str : cookies){
                if (cookieStr.contains(str.getName())){
                    cookie.append(str.getName()).append("=").append(str.getValue()).append(";");
                }
            }

更多推荐