使用SpringBoot + selenium-java 做爬虫

spring boot整合selenium 加入maven依赖 <!-- selenium-java --> <dependency> <groupId>org.seleniumhq.selenium</groupId> <artifactId>selenium-java</artifactId> <version>${selenium.version}</version&gt. 阅读详情

题记 最近发现了springboot本身就集成了selenium-java ,就拿来研究了一下,分布式爬虫是很大的一个架构,也比较复杂,没做研究,还是对爬虫的客户端实现有点兴趣,就想着用java做一个小爬虫客户端,其实selenium是做测试的,不过来拿来做小爬虫还是不错的,能真实模拟用户,不用担心异步加载爬取不到,还有一些元素获取不方便,更值得一提的是selenium-java 提供的元素获取的方式真的很方便,根据className、tagName、id 都有,爬取网站的时候会遇到一些验证码,这时候可以使用tess4j做简单的验证码识别,实在不行就等待人工输入也行。下面会提到爬虫验证码处理、frame内容爬取、翻页处理、滚动条等。

1、 Selenium 简介

Selenium 是一个用于Web应用程序测试的工具。Selenium测试直接运行在浏览器中,就像真正的用户在操作一样。支持的浏览器包括IE(7, 8, 9, 10, 11),Mozilla Firefox,Safari,Google Chrome,Opera等。这个工具的主要功能包括:测试与浏览器的兼容性——测试你的应用程序看是否能够很好得工作在不同浏览器和操作系统之上。测试系统功能——创建回归测试检验软件功能和用户需求。支持自动录制动作和自动生成 .Net、Java、Perl等不同语言的测试脚本。

2、selenium-java

selenium-java 是 selenium的java 版,根据不同driver,可以驱动不同的浏览区,比如 selenium-chrome-driver、selenium-edge-driver、selenium-firefox-driver、selenium-ie-driver、selenium-opera-driver、phantomjsdriver等等,我用了其中的chromedriver 和 phantomjsdriver,这个能完全模拟真实用户操作,不错的测试框架。

3、 chromedriver 示例

3.1、 下载

以下是chromedriver对应的chrome版本:

驱动对应版本号
2.37v64-66
2.36v63-65
2.35v62-64
2.34v61-63
2.33v60-62
2.32v59-61
2.31v58-60
2.30v58-60
2.29v56-58

驱动的下载地址如下:
http://chromedriver.storage.googleapis.com/index.html
注意:64位向下兼容,直接下载32位的就可以啦,亲测可用。

3.2、 使用

ChromeOptions options = new ChromeOptions();
// 设置允许弹框
options.addArguments("disable-infobars","disable-web-security");
// 设置无gui 开发时还是不要加,可以看到浏览器效果
options.addArguments("--headless");
String driverPath =  "D:\\crawler-plugin\\chromedriver.exe";
System.setProperty("webdriver.chrome.driver", driverPath);
RemoteWebDriver driver=  new ChromeDriver(options);
driver.get("http://www.baidu.com");
System.out.println(driver.findElement(By.tagName("body")).getText());

4、 phantomjsdriver示例

4.1、 下载

下载地址 http://phantomjs.org/download.html

4.2、 使用

String driverPath = "D:\\crawler-plugin\\phantomjs-2.1.1-windows\\bin\\phantomjs.exe";
System.setProperty("phantomjs.binary.path", driverPath);//设置PhantomJs访问路径
DesiredCapabilities desiredCapabilities = DesiredCapabilities.phantomjs();
//设置参数
desiredCapabilities.setCapability("phantomjs.page.settings.userAgent", "Mozilla/5.0 (Windows NT 6.3; Win64; x64; rv:50.0) Gecko/20100101 Firefox/50.0");
desiredCapabilities.setCapability("phantomjs.page.customHeaders.User-Agent", "Mozilla/5.0 (Windows NT 6.3; Win64; x64; rv:50.0) Gecko/20100101  Firefox/50.0");
RemoteWebDriver driver =  new PhantomJSDriver(desiredCapabilities);
driver.get("http://www.baidu.com");
System.out.println(driver.findElement(By.tagName("body")).getText());

5、 爬取页面常遇到的问题

5.1、 验证码

网站有时候需要登录,登录时候遇到验证码就非常棘手,tess4j能做简单的验证码识别,复杂的就别想了。。
maven 依赖

 <dependency>
	<groupId>net.sourceforge.tess4j</groupId>
		<artifactId>tess4j</artifactId>
		<version>3.4.0</version>
		<exclusions>
			<exclusion>
				<groupId>com.sun.jna</groupId>
				<artifactId>jna</artifactId>
			</exclusion>
		</exclusions>
	</dependency>

tess4j 配置项

##tess4j config
tess4j.language=chi_sim
tess4j.language.path=D:\\crawler-plugin\\tessdata
tess4j.data.path=D:\\crawler-plugin\\

读取配置文件

@Configuration
public class Tess4jConfig {
    @Value("${tess4j.data.path}")
    @Setter
    @Getter
    private String tess4jDataPath ;

    @Value("${tess4j.language.path}")
    @Setter
    @Getter
    private String tess4jLanguagePath ;

    @Value("${tess4j.language}")
    @Setter
    @Getter
    private String tess4jLanguage ;
}

工具类


import com.cdchen.crawler.config.Tess4jConfig;
import lombok.extern.slf4j.Slf4j;
import net.sourceforge.tess4j.ITesseract;
import net.sourceforge.tess4j.Tesseract;
import net.sourceforge.tess4j.util.LoggHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;

@Slf4j
public class Tess4jUtil {

    private static final Logger logger                   = LoggerFactory.getLogger(new LoggHelper().toString());
    static final             double MINIMUM_DESKEW_THRESHOLD = 0.05d;
    private static ITesseract instance;

    private static  String datapath = "D:\\crawler-plugin\\";
    private static  String testResourcesLanguagePath = "D:\\crawler-plugin\\tessdata";
    private static  String language = "chi_sim";

    private  static ITesseract getInstance(){

        Tess4jConfig config = SpringBeanUtil.getBean(Tess4jConfig.class);
        if(config != null){
            datapath = config.getTess4jDataPath();
            language = config.getTess4jLanguage();
            testResourcesLanguagePath = config.getTess4jLanguagePath();
        }

        if(datapath == null){
            log.error("必须在properties配置tess4jdata.path,否则验证码无法识别");
            return null;
        }
        if(testResourcesLanguagePath == null){
            log.error("必须在properties配置tess4jlanguage.path,否则验证码无法识别");
            return null;
        }
        if(language == null){
            log.error("必须在properties配置tess4jlanguage,否则验证码无法识别");
            return null;
        }

        if(instance == null){
            instance = new Tesseract();
            instance.setDatapath(new File(datapath).getPath());
            //set language
            instance.setDatapath(testResourcesLanguagePath);
            instance.setLanguage(language);
        }
        return instance;
    }

    public static String  doOcr(File file) throws  Exception{
        String result = getInstance().doOCR(file);
        return result;
    }

}

5.2、 翻页

翻页相对来就很简单了,有很多种解决方法,举例2种
1 找到翻页url规律,替换对应的页码
2 找到翻页按钮,模拟点击
我用的第二种,一下代码为爬取qiushi百科时候的翻页代码,供参考:

private void jumpPageNum(int pageNum){
        if(WebElementUtils.doesWebElementExist(driver,By.className("pagination"))){
            WebElement pagination = driver.findElement(By.className("pagination"));
            String currentText = pagination.findElement(By.className("current")).getText();
            int currentPageNum = Integer.parseInt(currentText);
            while (currentPageNum != pageNum){
                List<WebElement> pageNums = pagination.findElements(By.className("page-numbers"));
                for (int i = 0; i < pageNums.size(); i++) {
                    String pageNumText = pageNums.get(i).getText();
                    if(pageNumText.equals(pageNum+"")){
                        pageNums.get(i).click();
                        scrollBar.toPageEnd();
                        break;
                    }else{
                       if(i == (pageNums.size()-1)){
                           pageNums.get(i).click();
                       }
                    }
                }
                pagination = driver.findElement(By.className("pagination"));
                currentText = pagination.findElement(By.className("current")).getText();
                currentPageNum = Integer.parseInt(currentText);
            }
        }
    }

5.3、 滚动条

滚动条就比较麻烦了,因为Driver没有对应的api操作滚动条(或许我没有找到。。),我用了曲线救国的方法去实现,而且用同样的思路可以解决很多类似的问题。思路就是:使用JavaScript去操作滚动条,
实现步骤是:

  1. 向页面body内添加script tag,并把想执行的js function 插入进去
  2. 使用driver的js执行引擎去执行js实现效果

贴出来我写的工具类:


import com.cdchen.crawler.util.SleepUtil;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.openqa.selenium.remote.RemoteWebDriver;

    /**
     *
     * @description: tb
     *
     * @author: cdchen
     *
     * @create: 2019-04-30 17:08
     **/
    @Data
    @Slf4j
    public class ScrollBar {

        RemoteWebDriver driver = null;


        private static String getScrollTopJs = "function getScrollTop(){"
                                               + "  var scrollTop = 0, bodyScrollTop = 0, documentScrollTop = 0;"
                                               + "  if(document.body){"
                                               + "    bodyScrollTop = document.body.scrollTop;"
                                               + "  }"
                                               + "  if(document.documentElement){"
                                               + "    documentScrollTop = document.documentElement.scrollTop;"
                                               + "  }"
                                               + "  scrollTop = (bodyScrollTop - documentScrollTop > 0) ? bodyScrollTop : documentScrollTop;"
                                               + "  return scrollTop;"
                                               + "};";

        private static String getScrollHeightJs = "function getScrollHeight(){"
                                                  + "  var scrollHeight = 0, bodyScrollHeight = 0, documentScrollHeight = 0;"
                                                  + "  if(document.body){"
                                                  + "    bodyScrollHeight = document.body.scrollHeight;"
                                                  + "  }"
                                                  + "  if(document.documentElement){"
                                                  + "    documentScrollHeight = document.documentElement.scrollHeight;"
                                                  + "  }"
                                                  + "  scrollHeight = (bodyScrollHeight - documentScrollHeight > 0) ? bodyScrollHeight : documentScrollHeight;"
                                                  + "  return scrollHeight;"
                                                  + "};";

        private static String getWindowHeightJs = "function getWindowHeight(){"
                                                  + "  var windowHeight = 0;"
                                                  + "  if(document.compatMode == \"CSS1Compat\"){"
                                                  + "    windowHeight = document.documentElement.clientHeight;"
                                                  + "  }else{"
                                                  + "    windowHeight = document.body.clientHeight;"
                                                  + "  }"
                                                  + "  return windowHeight;"
                                                  + "};";

        private static String scroollIsOverJs = "function scroollIsOver(){"
                                                + "  if(getScrollTop() + getWindowHeight() == getScrollHeight()){"
                                                + "    return true;"
                                                + "  }else{"
                                                + "    return false;"
                                                + "  }"
                                                + "};";

        private static String insertScriptJs = "var body = document.getElementsByTagName('body')[0];"
                                               + "var newScript = document.createElement('script');"
                                               + "newScript.type = 'text/javascript';"
                                               + "newScript.innerHTML = '"+getScrollTopJs+getScrollHeightJs+getWindowHeightJs+scroollIsOverJs+"';"
                                               + "body.appendChild(newScript);";
        public ScrollBar(RemoteWebDriver dr){
            driver = dr;
        }
        public  void toPageEnd() {
            getDriver().executeScript(insertScriptJs);
            int start = 0;
            boolean scroollIsOver = false;
            while (!scroollIsOver){
                getDriver().executeScript("window.scrollTo("+start+","+(start+500)+")");
                Boolean res = (Boolean)getDriver().executeScript("return  scroollIsOver();");
                if(res != null && res){
                    scroollIsOver = true;
                }
                start = start+500;
                SleepUtil.sleep(1000);
            }
        }

    }

5.4、 iframe 内元素无法获取

有时候页面内置了iframe,想要获取iframe的元素就获取不了,这是就需要把driver切换到iframe内,如下代码:

WebElement iframe = driver.findElement(By.tagName("iframe"));
driver.switchTo().frame(iframe);
// 然后再去获取元素或者其他操作、操作完需切换回来
driver.switchTo().parentFrame();

5.5、 标签页切换

有时候用chromedriver 时候需要开启多个标签页如何操作?

List<String> tabs = new ArrayList<String>(driver.getWindowHandles());
// 切换到第一个标签
driver.switchTo().window(tabs.get(0));
// 切换到第 **n**个标签
driver.switchTo().window(tabs.get(n));

6 数据库问题

爬虫客户短 应该尽量的小,但是有时候需要记录一些 爬取进度信息,不得不使用数据库或者文件之类的记录,所以我就集成了一个sqllite 作为持久化数据库,客户端重启也不用担心丢数据啦。框架 使用的是 SpringBoot + Mybatis+Tkmapper+Sqllite+selenium-java ,使用起来也是相当方便,项目放在了gitee上,地址:https://gitee.com/passionday/crawler

SpringBoot+selenium模拟用户操作浏览器 Selenium是一个用于Web应用程序自动化测试的开源工具套件。总的来说,Selenium帮助开发团队提高Web应用的质量保障效率,通过自动化测试减少手动测试的重复性和复杂性,并有助于持续集成和持续部署(CI/CD)流程的实施。 阅读详情

相关推荐

如何在 Microsoft Edge 上使用开发人员工具

在本文中,我们将仔细研究如何在 Microsoft Edge 上使用开发人员工具。

网络研究观 3858

SpringBoot整合Selenium

SpringBoot整合Selenium package com.vmware.config; import lombok.Data; import lombok.extern.slf4j.Slf4j; import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; import org.openqa.selenium.chrome.ChromeOptions; import org.springf

冰点契约的博客 3365

SpringBoot开发——整合Selenium模拟用户操作浏览器

SpringBoot整合Selenium模拟用户操作浏览器

bjzhang75的博客 1741

SpringBoot中Selenium详解

SpringBoot与Selenium的结合使得自动化测试变得更加简单和高效。通过上述步骤,你可以快速地在你的项目中集成Selenium,并编写自动化测试用例。这不仅提高了测试的覆盖率,也减少了手动测试的工作量。版权声明:本博客内容为原创,转载请保留原文链接及作者信息。参考文章Spring Boot集成selenium实现自动化测试_springboot selenium-优快云博客。

ning的博客 2744

Java+spring boot+selenium+testng+reportng

需要安装的工具idea jdk1.8 (mysql,navicat) chromedriver_win32 如果看Java包,就是spring boot+mybatis+mysql的一个Java开发架构 http://localhost:8080/user/list 如果看test包,就是用Java+spring boot+selenium+testng+reportng搭的一个测试架构 http://localhost:63342/demo/test-output/html/index.html

告别FreeRTOS?手把手带你用NuttX在STM32F4-Discovery上跑起第一个Shell

本文详细介绍了如何在STM32F4-Discovery开发板上从FreeRTOS迁移到NuttX,并运行第一个Shell。NuttX以其完整的POSIX兼容性和模块化架构优势,特别适合复杂网络应用的开发。通过环境搭建、移植配置、调试技巧及POSIX开发实践,帮助开发者高效构建嵌入式系统。

weixin_42526417的博客 300

项目汇总

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_34211761的博客 141

华为路由器 VRRP主备配置

3、R3 出口路由器。

一直被模仿,从未被超越 5590

SAP系统登录以及注册开发人员

SAP系统登录以及注册开发人员 今天初学SAP,主要学了SAP GUI的安装,登录以及注册为开发人员。在此感谢SAP大佬提供的账号。 1.下载SAP GUI 我这里用的是网上找的SAP GUI 730版本,安装教程网上有很多,我就不赘述了。SAP GUI 730版本资源: 链接:https://pan.baidu.com/s/1GkS5AEQMeyKnhnqUqGQi0g 提取码:43cd 2.安装完进入登录界面,如下图: 3.点击连接 以上需要自己向大佬要,百度上虽然有很多,但都是好多年前的帖

XSY520_的博客 7412

腾讯滑块验证码collect参数逆向与JSVMP对抗实战

本文深入解析腾讯滑块验证码collect参数的逆向过程与JSVMP虚拟机对抗技术。通过详细的环境搭建、抓包分析和JSVMP逆向技巧,揭示collect参数的生成逻辑与加密流程,并提供完整的模拟实现方案和常见问题排查方法,助力开发者突破腾讯天御验证码的防护机制。

weixin_29009501的博客 1578

从机械到数字:EC11旋转编码器与ESP32的PWM控制艺术

本文详细解析了EC11旋转编码器与ESP32的PWM控制技术,探讨了如何将机械旋转动作转换为精确的数字信号控制。通过硬件连接、信号处理和软件优化等实践技巧,开发者可以构建高效的人机交互系统,适用于智能照明、电机控制等多种应用场景。

android的专栏 786

IE8的调试工具使用详解-web标准开发人员专用

认识“开发人员工具” 虽然这玩意改了时髦的名字,但是却也不是什么新玩意,它的前身是“IEdevtoolbar”。但是,以前只是IE的一个插件而已。而在IE8中,浏览器已经自动集成了这玩意,不仅改了个有点土鳖的名字,而且功能也加强了很多。 开发人员工具在IE8的工具菜单下,或者直接点击F12快捷键也可以呼叫出来。  在我们介绍它之前,我们先来说说这玩意到底能做什么?如果你只是用浏览器来

龙胜LONGAIN 3万+

FLUX.1 LoRa 微调

微调的好处:可以让你突破换脸这种输入图片的场景约束,微调好的模型可以让你真正的文生图。换脸只能根据输入的图片和视频来生成内容。

szmars的博客 3621

开发人员,你该如何做自测,做设计?

本文是最近为公司所做的两篇总结之一。主旨是为公司的开发人员提供一些做自测,界面设计时的思路。 关于开发人员自测 开发人员做好自测,是非常必要和也是大趋势。Google公司里面,纯粹的测试人员是很少的,前期都是开发自测(包含必要的测试),后期才是用户体验方面的测试;从成本上分析,BUG越晚发现修复成本越高;从修改的效率来讲,越早处理会越快。另外,写出高质量的代码,是能力的体现,专业的体现

在劫录 7032

在 SAP GUI Editor 中使用 OpenAI 自动生成 ABAP 代码 —— 技术实践与思考

在传统 SAP GUI Editor 场景下融入OpenAI开发者表达意图,模型负责实现。随着的持续演进,以及Joule等官方 Copilot 的加入,未来 ABAP 开发形态必将更加专注业务逻辑与架构设计,而把样板式编码交给 AI 自动完成。现在就动手试试,让你的下一段 ABAP 由 AI 来书写吧!

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 709

【YOLOv13多模态融合改进】| CFT:跨模态融合Transformer | 利用Transformer的自注意力机制,解决跨模态融合中的长距离依赖和全局信息整合问题

本文记录的是利用 CFT 模块改进 YOLOv13 的多模态目标检测网络模型。的设计出发点在于解决传统多模态检测中跨模态特征融合不充分的问题,即当不同模态数据需协同检测时,基于CNN的方法因局部卷积的局限性,难以捕捉长距离依赖和全局模态间的互补信息,导致复杂光照、遮挡等场景下检测精度不足。本文利用模块,将多模态特征序列拼接后自动学习模态内与模态间的交互权重,在特征提取阶段整合全局上下文信息,增强对不同模态互补特征的利用能力,从而提升模型在多模态场景下的检测鲁棒性与准确性。Cross-Modality Fus

Limiiiing的博客 540

springboot整合selenium实现页面数据爬取,两个问题记录

springboot整合selenium实现页面数据爬取,允许远程连接和允许跨域问题的解决

dyp723的博客 1498

基于Simulink的双向DC-DC变换器在储能系统中的应用仿真

摘要:本文详细介绍了基于Simulink的双向DC-DC变换器在光伏储能系统中的仿真实现。主要内容包括:1)采用非隔离型双向Buck-Boost拓扑作为储能系统枢纽;2)针对750V直流微网中的20kWh锂电池接口场景进行建模;3)详细阐述双闭环控制器设计(电压外环+电流内环)、工作模式判断逻辑等关键步骤;4)通过仿真验证了系统在功率阶跃和模式切换下的性能。文章提供了完整的建模流程和控制方法,为储能系统接口设计提供了实用参考。

amy_mhd的博客 179

Spring Boot集成selenium实现自动化测试

它使用现有的 Selenium 命令记录用户在浏览器中的操作, 参数由元素的上下文确定。浏览器自动化的一系列工具,它提供了扩展来模拟用户与浏览器的交互,用于扩展浏览器分配的分发,以及用于实现W3C WebDriver 规范 的基础结构, 该规范允许您为所有主要Web 浏览器编写可互换的代码。Selenium Grid允许您在不同平台的不同机器上运行测试用例. 可以本地控制测试用例的操作, 当测试用例被触发时, 它们由远端自动执行. 当开发完WebDriver测试之后, 您可能需要在多个浏览器和。

OKCRoss的博客 1587

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

spring boot集成selenium,chromedriver 自动化测试 报错Lcom/google/common/util/concurrent/SimpleTimeLimiter

<!--selenium 浏览器测试--> <dependency> <groupId>org.seleniumhq.selenium</groupId> <artifactId>selenium-java</artifactId> <version>3.4.0</version> </dependen.

qq_43898141的博客 2018

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

springboot集成webmagic和selenium,并部署到linux(问题坑)

springboot集成webmagic和selenium,并部署到linux

qq_36249132的博客 2053

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

springBoot整合selenium

springBoot整合selenium及新版本可能出现的问题

m0_60898924的博客 871

基于springboot2.x集成selenium3.141.59

这里写目录标题前言windows环境参考核心代码pom.xml国内镜像地址 前言 本人也是初次接触selenium,总结几点避免入坑的注意点, 不要太在意浏览器版本过低有什么影响的,只要能满足你的需求就可以了。 ---->重要的话说三遍<----- 1. 不管是chrome还是firefox最重要的就是他们驱动与浏览器之间的版本对应关系。 2. 不管是chrome还是firefox最重要的就是他们驱动与浏览器之间的版本对应关系。 3. 不管是chrome还是firefox最重要的就是他们驱动与浏

若成风的博客 2159

Springboot+Selenium+TestNg登录功能

Springboot+Selenium登录功能 一、Springboot+Selenium+testNg框架搭建 1.配置依赖 org.springframework.boot spring-boot-starter spring-context org.springframework org.springframework.boot spring-boot-starter-test test org.projectlombok lombok true org.springframe

汤姆是只猫 884

SpringBoot项目如何安装Selenium自动化(详解)

java版本最低要求为8。电脑至少已安装一种浏览器,如:Chrome(推荐)、Edge、Firefox、IE、Safari等安装正版浏览器,非官网浏览器会出现问题。(下面以Chrome为例)

m0_60462557的博客 685
上一篇: java 高级面试题
下一篇: SpringBoot集成sqlite,并用集成tk做baseservice封装
cdchen2017
博客等级 码龄15年 44粉丝 54原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值