拿来直接用(java+selenium+WebDriver+chrome+docker实现爬虫)

如果你不需要在linux docker 上运行爬虫,就不需要看这篇文档了,直接拉到最下面点击第二个 参考文档 即可。

问:selenium+WebDriver+chrome 是如何实现爬虫的或者自动化测试的。

答:selenium WebDriver 可以模拟页面上的操作,仿佛一个测试人员 正在拿着鼠标在页面上点来点去。并且可以获取页面上的元素,元素的属性值。

创建一个WebDriver对象,就是打开一个会话。

第一步:拉取镜像

1.拉取镜像

1.1官方镜像

sudo docker run -d -p 4444:4444 --shm-size=2g selenium/standalone-chrome

1.2这个官方镜像是国外的,拉取不下来,使用阿里云加速器

在这里插入图片描述
在这里插入图片描述

使用阿里云加速器其实要的就是红框3中的json,赋值红框3中的json,复制红框2中的地址,替换掉json里面的链接,得到新的json。(这个链接每个人都不一样)

{
  "registry-mirrors": ["https://********"]
}

然后把这个json保存到 你linux机器上 /etc/docker/daemon.json 这个文件里,没有的话就创建这个文件。
在这里插入图片描述
完事之后,再次执行上面的命令就可以成功了
运行成功之后,查看容器,会看到已经容器已经运行了。

sudo docker ps

在这里插入图片描述
在你的电脑,不是linux,访问以下地址

http://<你的linux的ip地址>:4444/

如果可以看到下面的页面,就说明容器运行成功
在这里插入图片描述
sessions:代表创建了几个会话。
max.concurrentcy: 代表 你这个容器同时可以处理几个对话。
图中这种情况只能 同时模拟一个网页,也就是同时只能处理一个会话。

代码部分

依赖

        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-java</artifactId>
            <version>3.141.59</version>
        </dependency>
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>23.0</version>
        </dependency>
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.8.2</version>
        </dependency>
WebDriver chromeDriver  = new RemoteWebDriver(new URL("http://<linux  ip 地址>:4444/wd/hub"), DesiredCapabilities.chrome());

这段代码就是创建和你linux机器上 chrome 容器服务的 会话。
可以本地写个main方法运行一下这段代码。但是一定要加上下面的代码,关闭会话。

chromeDriver.quit();

为了看到效果,可以睡个5秒钟。不报错就说明成功了,同时 http://<你的linux的ip地址>:4444/ 这个地址上,sessions 的值应该变成1,5秒之后变成0。

注意:如果你心急没有加上 关闭会话 的代码就着急运行了。那么你就只能去linux上重启 容器了。

package com.water.disasters.service.schedule;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.ui.WebDriverWait;

import java.net.URL;
import java.time.Duration;
import java.util.List;
import java.util.concurrent.TimeUnit;

import static org.openqa.selenium.support.ui.ExpectedConditions.numberOfWindowsToBe;
import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;

public class MainClass {
    public static void main(String[] args) {

        
        WebDriver driver = null;
        try {
            //打开一个浏览器窗口
            //加载 chromedriver 驱动 
            driver = new RemoteWebDriver(new URL("http://192.168.183.120:4444/wd/hub"), DesiredCapabilities.chrome());
            //打开百度链接
            driver.navigate().to("http://www.baidu.com/");
            //在搜索文本框输入"csdn 西凉的悲伤"
            driver.findElement(By.id("kw")).sendKeys("csdn 西凉的悲伤");
            //点击搜索按钮
            driver.findElement(By.id("su")).click();


            //存储当前原始窗口或页签的ID
            String originalWindow = driver.getWindowHandle();
            //获取当前打开的窗口或页签数
            int windosSize = driver.getWindowHandles().size();

            //等到百度搜索结果页面元素加载完(这里最多等5秒)
            driver.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS);
            //点击第一条搜索结果,会打开新页签,也就是第2个页签
            driver.findElement(By.xpath("//*[@id='content_left']/div[@id='1']/div[@class='c-container']/div/h3/a")).click();


            WebDriverWait wait = new WebDriverWait(driver, 10);
            
            //这里不我建议用,因为我打开第二窗口打不开,可能是因为分配的资源大小的问题。我实际处理业务都是 单窗口操作的,先把第二个网页的链接保存到数据库
            
            //等待第2个新窗口或新页签打开
            wait.until(numberOfWindowsToBe(2));
            //循环指导找到新窗口或页签的句柄
            for (String windowHandle : driver.getWindowHandles()) {
                if (!originalWindow.contentEquals(windowHandle)) {
                    //driver切换为新窗口或新页签的
                    driver.switchTo().window(windowHandle);
                    break;
                }
            }
            //等待新窗口或新页签的内容加载
            wait.until(titleIs("西凉的悲伤的博客_CSDN博客-java,工具,其他领域博主"));


            //读取当前页面标题
            System.out.println("当前网址的标题:" + driver.getTitle());
            //从地址栏中读取当前 URL
            System.out.println("当前网址的链接:" + driver.getCurrentUrl());
            System.out.println();

            //获取多个 h4 标签元素
            List<WebElement> articleTitles = driver.findElements(By.xpath("//*[@class='blog-list-box-top']/h4"));
            //获取多个 a 标签元素
            List<WebElement> articleUrls = driver.findElements(By.xpath("//*[@class='blog-list-box']/a"));
            for (int i = 0; i < articleTitles.size(); i++) {
                //获取 h4 标签中的显示文本
                String articleTitle = articleTitles.get(i).getText();
                //获取 a 标签里的 href 属性的值
                String articleUrl = articleUrls.get(i).getAttribute("href");
                System.out.println("文章标题:" + articleTitle + " 链接:" + articleUrl);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            driver.quit();
        }
    }
}

只是一个例子,selenium+java 操作的语法,大家去网上搜搜吧,我就不赘述了。
但是搜的时候要注意 windows 上 和 docker 容器上 创建会话的方式不一样,即创建Webdriver 的方式不一样。

docker安装selenium/chrome 参考文档
selenium+java 代码 参考文档

  • 7
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值