ssm框架可以做什么项目_Java整合这款自动化测试框架居然可以做爬虫

点击上方Java资料社区,选择“置顶公众号”

优质文章,第一时间送达

f922e717fa0587aafa9e1fa4d3163738.png

最近迷上了爬虫技术,经过学习了解爬虫基本流程:

e844ef1c2d502c9417f2c88d9e0389a8.png

1.分析接口、页面,及请求参数、数据渲染逻辑

2.通过发起Http工具发起接口、页面请求

3.得到响应之后对响应的数据进行筛选

4.筛选出的数据进行入库

随着业务慢慢的深入,后来发现通过HttpClient做爬虫并不方便,例如碰到某一个需要登录才能进入的网站,使用HttpClient则不太方便,想要模拟登录必须先让用户登录之后获取到真实登录用户的cookie,将cookie设置到请求Cookie当中才能解决,显然这并不是很好的解决方案.

在这段爬虫学习过程中发现一款很有意思的框架,这款框架叫作selenium,做自动化测试的同学应该比较了解,下面可以先观看以下我用selenium写的一个小案例:

看完以上视频,下面了解如何实现的

Selenium介绍

该框架是一个用于web端测试工具,直接运行在浏览器中,使用过程中与真人操作类似,支持兼容市场各大主流浏览器,通过编写程序可以简化web端上的重复操作,从而让程序去替你工作,当然!selenium主要并不是做爬虫,本文只是利用该框架做一个简单的爬虫应用

1 Selenium环境安装

因为selenium是运行在浏览器中,所以首先必须安装浏览器驱动,这里我使用的谷歌浏览器,下载驱动需要根据浏览器版本安装不同的驱动版本,否则会出现异常

谷歌下载地址:

http://npm.taobao.org/mirrors/chromedriver/

火狐下载地址:

https://github.com/mozilla/geckodriver/releases

IE下载地址:

http://selenium-release.storage.googleapis.com/index.html

我的谷歌是80.0.3987.149版本,这里我选择的80.0.3987.16的谷歌驱动,最后可以根据自己的系统环境下载不同的版本.

b84c55ed2726418295154e1b8fef336c.png

f68d9969861e233dd1f713ce73e4309f.png

6479c0f5fa621b2cd2b40f01e96abc83.png

2 案例需求

1.实现拉勾网自动登录(验证码需要人工识别)

5cf860990fec7e2c1ee14fb11da219c4.png

2.自动筛选并搜索指定职位

766598c4c3a6a49311b133695d0b269f.png

3.抓取筛选搜索后的职位信息及分页处理

fa2028b2fcd0badf776f85d34d59fe96.png

3 搭建Java项目

项目环境:maven3.3.1+jdk1.8+IDEA2019.1

maven依赖:

<?xml version="1.0" encoding="UTF-8"?>         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">    4.0.0    com.java134    selenium_Lagou    1.0-SNAPSHOT                        org.seleniumhq.selenium            selenium-server            3.141.59            

1)将下载下来的谷歌驱动放入项目根路径下(也可以自定义,用于项目启动加载驱动)

9c06c0a9bcc7f130e9abe11a68c4d3bd.png

2)实现需求1

 首先分析拉勾网登录页面为https://passport.lagou.com/login/login.html

bb5806f6872cce1341a3bfad13c7028a.png

再分析拉勾网用户名、密码、登录按钮结构

e2e15db2e0284242ee743cb231ea9d9d.png

a2f85a6652faa390bc0203da5d7fc443.png

01640112c5cc6942888e654b5449777c.png

代码实现:

/** * @ClassName LagouJob * @Description * @Author 公众号:Java资料社区-码农小龙 * @Date 2020/3/27 16:51 **/public class LagouJob {  public static void run() throws InterruptedException {       //设置谷歌驱动系统变量       System.setProperty("webdriver.chrome.driver",System.getProperty("user.dir")+"\\chromedriver.exe");       //创建浏览器驱动实例       WebDriver driver = new ChromeDriver();       //打开指定网址(拉勾网登录网址)       driver.get("https://passport.lagou.com/login/login.html");       //定位用户名框        WebElement userName=driver.findElement(By.xpath("//div[@data-propertyname='username']/input"));        //输入手机号        userName.sendKeys("1767xxxxxxx");        //定位密码框        WebElement userPwd=driver.findElement(By.xpath("//div[@data-propertyname='password']/input"));        //输入密码        userPwd.sendKeys("xxxxxxxx");        //定位提交按钮        WebElement btnSubmit=driver.findElement(By.xpath("//div[@data-propertyname='submit']/input"));        //点击提交按钮        btnSubmit.click();  }}

Api介绍:

    1.WebDriver 创建一个浏览器实例,根据不同的驱动创建不同的实现

WebDriver driver = new ChromeDriver();    //Chrome浏览器WebDriver driver = new FirefoxDriver();   //Firefox浏览器WebDriver driver = new EdgeDriver();      //Edge浏览器WebDriver driver = new InternetExplorerDriver();  // Internet Explorer浏览器WebDriver driver = new OperaDriver();     //Opera浏览器WebDriver driver = new PhantomJSDriver();   //PhantomJS

    2.get:属于WebDriver下的方法,用于第一次打开浏览器访问的指定网址

    3.findElement:属于WebDriver下的方法,用于查找页面中的元素,需要配合By使用

    4.By:用于定位页面中的元素,类似于Jquery,提供了8种定位方式

  • id

  • name

  • class name

  • tag name

  • link text

  • partial link text

  • xpath

  • css selector

    对应Api方法:

//这里只简单介绍几个常用的,如果感兴趣可以自行了解findElement(By.id("id"))//通过元素的id名进行定位,类似于$("#id")findElement(By.name("name"))//通过元素name名定位findElement(By.className("class"))//通过元素的id名进行定位,类似于$(".id")//分为两种 1.绝对定位 2.相对定位//绝对定位,这里的下标是从1开始的,用于区分子元素的层级findElement(By.xpath("/html/body/div[1]/a[2]/"))//相对定位,这里的@后面可以用于区分元素的属性值,也可以设置成class name或者自定义属性等等findElement(By.xpath("//a[@href='www.baidu.com']"))findElement(By.tagName())findElement(By.linkText())findElement(By.partialLinkText())findElement(By.cssSelector())

5.WebElement:用于接收findElement查找的元素

6.sendKeys:属于WebElement下的方法,用于向文本框中输入指定字符

7.click:属于WebElement下的方法,用于触发元素的click事件

运行结果

3)实现需求2

登录成功之后会跳转到拉勾首页,由于我们需求是要根据条件搜索职位,所以先从首页搜索入口入手分析,与上述登录流程一致,定位文本框-->输入搜索条件-->点击搜索按钮;

问题1:由于上述登录有可能会出现人机验证,selenium对人机验证暂时没法很好的识别,所以需要设置线程睡眠10秒提供人工识别验证码及登录之后跳转处理时间

631b931410e5eb41c7d92f5b0b37ac31.png

问题2:搜索跳转之后有可能会出现广告模态框,如果不关闭模态框会影响程序的下一步运行,所以需要分析广告模态框是否存在存在则需要关闭

52376262fce9ae3e502cafdbeed5069f.png

需求2搜索实现代码

//省略需求1实现代码...//接着需求1代码块继续//解决问题1:停止运行10秒,提供人工选择验证码及登录跳转时间Thread.sleep(10000);//输入搜索职位名称driver.findElement(By.id("search_input")).sendKeys("Java");//点击搜索按钮driver.findElement(By.id("search_button")).click();   //解决问题2:判断广告框是否存在,取消模态框广告if(driver.findElement(By.className("body-container")).isDisplayed()){    driver.findElement(By.className("body-btn")).click(); }

搜索跳转之后开始分析筛选条件模块,查看源码之后分析到如果要选择条件筛选,必须点击相应的筛选条件文字;

f1bf9b124cc4b0079140e809933a193f.png

fbc534277727369f4b18281219c2f09d.png

需求2筛选条件实现代码:

//省略上述代码...//筛选条件String gzdd="上海";String gzjy="3年及以下";String xl="大专";String rzjd="不限";String gsgm="不限";String hyly="不限";//点击指定地区条件driver.findElement(By.xpath("//div[@class='other-hot-city']/div/a[contains(text(),'" + gzdd + "')]")).click();//点击指定工作经验条件driver.findElement(By.xpath("//li[@class='multi-chosen']/span[contains(text(),'工作经验')]")).       findElement(By.xpath("../a[contains(text(),'" + gzjy + "')]")).click();//点击指定学历条件driver.findElement(By.xpath("//li[@class='multi-chosen']/span[contains(text(),'学历要求')]")).       findElement(By.xpath("../a[contains(text(),'" + xl + "')]")).click();//点击指定融资阶段条件driver.findElement(By.xpath("//li[@class='multi-chosen']/span[contains(text(),'融资阶段')]")).       findElement(By.xpath("../a[contains(text(),'" + rzjd + "')]")).click();//点击指定公司规模条件driver.findElement(By.xpath("//li[@class='multi-chosen']/span[contains(text(),'公司规模')]")).       findElement(By.xpath("../a[contains(text(),'" + gsgm + "')]")).click();点击指定行业领域条件driver.findElement(By.xpath("//li[@class='multi-chosen']/span[contains(text(),'行业领域')]")).       findElement(By.xpath("../a[contains(text(),'" + hyly + "')]")).click();

xpath定位中contains解释:对于以上对筛选模块代码的分析,由于多个a标签的class、name名都一致,无法定位到单个元素,所以用到contains方法直接定位元素中的text内容,根据指定的文字内容匹配相关元素;

运行结果

4)实现需求3

条件筛选之后会加载所有与条件匹配的职位数据,接下来开始分析职位列表渲染的html结构,从而爬取关键数据,下图分析出每一条职位数据,都是由一个li标签组成;

dd7ba96c54b723d363fb7ece7c3298d3.png

需求3抓取职位信息实现代码:

//省略上述代码...boolean flag=true;//是否有下一页Double sum=0.0;//总工资int count=0;//职位总数//循环分页爬取数据,直到最后一页while (flag){//设置时间等待网页渲染完毕   Thread.sleep(1500);   WebElement nextBtn=null;   try {   //定位底部分页栏   nextBtn=driver.findElement(By.className("pager_container")).findElement(By.className("pager_next"));   //判断是否包含pager_next_disabled样式,包含则没有下一页   flag=!nextBtn.getAttribute("class").contains("pager_next_disabled");   }catch (Exception e){    //异常则代表只有一页,不存在上面的class名,则无法定位到     flag=false;   }   try {      //定位职位数据列表      List li = driver.findElements(By.xpath("//ul[@class='item_con_list']/li"));      if (li.size() > 0) {         for (WebElement item : li) {           //标题地址           String address = item.findElement(By.tagName("em")).getText();           //公司行业           String industry = item.findElement(By.className("industry")).getText();           //企业福利           String welfare = item.findElement(By.className("li_b_r")).getText();           //详情网址           String url = item.findElement(By.tagName("a")).getAttribute("href");           //职位标题           String name = item.getAttribute("data-positionname");           //工资           String money = item.getAttribute("data-salary");           //公司名           String company = item.getAttribute("data-company");           //切割最低工资与最高工资,用于计算中等工资 例:10k-20k           String arr[] = money.replaceAll("k", "").split("-");           //职位平均工资=职位最低工资+职位最高工资/2           Double avg = (Double.valueOf(arr[0]) + Double.valueOf(arr[1])) / 2;           sum += avg;//加入总工资中           count++;//加入职位总数中           System.out.println(company + "--" + name + "[" + address + "](" + money + ")");           System.out.println("公司行业:" + industry + "---福利:" + welfare);           System.out.println("URL:" + url);           System.out.println("----------------------------------------------------");           }           //下一页按钮存在并且非禁用的情况下则点击下一页           if (flag) {             nextBtn.click();            }     } else {       System.out.println("暂时没有符合该搜索条件的职位!");     }  }catch (Exception e){   System.out.println("------------出现异常----------------");   System.out.println("本次根据指定条件爬取岗位"+count+"个,平均工资为"+sum/count+"k.");   }}System.out.println("本次根据指定条件爬取岗位"+count+"个,平均工资为"+sum/count+"k.");

上述代码解决分页逻辑

经过分析:

1.如果下一页按钮class中存在pager_next_disabled样式则代表没有下一页数据,则停止while循环翻页;

2.通过try-catch包裹下一页按钮代码块,如果首次定位翻页按钮抛出异常则代表Html中没有该按钮,即代表没有下一页数据,停止while循环

selenium远远不止文中所提到仅有的功能,比如浏览器控制、模拟鼠标操作、模拟键盘操作、获取断言信息、多窗口切换、调用JS代码、Cookie操作、截图等待,感兴趣在该网址学习[http://www.testclass.net/selenium_java/]

4 写在最后

无论selenium是做自动化测试还是做爬虫,能够根据自身需要解决痛点则是优秀的框架,对于selenium而言我个人认为可以大胆的发挥想象,其实能够替代很多web端人工操作,例如后台信息审核很多简单的操作完全不需要人工审核,还可以结合我上述代码整合多个招聘平台进行简历一键投递!

最全面试题:入口链接

源码:关注公众号回复【拉钩】

如果对你有帮助,请转发给更多人,顺便下方点个在看!

d5c65a17b80913f1c0b3ff675b958102.png

点一下“ 在看”,好文和朋友一起看~
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值