webdriver 爬虫 java_java爬虫通过selenium+WebDriver遍历页面链接报错

背景

由于要爬取的页面,每个链接的请求都是点击之后js动态发起的,目标数据也多是js动态生成的,所以使用selenium工具+webdriver(调试用的是chrome,具体使用准备用phantomjs).

模拟登录之后,模拟查询之后,得到如下列表

6b4537956ecbf4a4bf788430a00709e3.png

可以看到链接是不能直接拿到的。

接下去步骤是这样的:

得到链接的集合

遍历集合,点击链接,得到对应的详情页面

通过页面句柄转到详情页面,拿到目标数据,再转回父页面

如上继续遍历

问题

按照如上逻辑,在执行到遍历步骤的时候,在第二次时报错了。

第一种报错:

org.openqa.selenium.StaleElementReferenceException: stale element

reference: element is not attached to the page document

我的代码:

// 获取查询按钮

WebElement queryBtn = driver.findElement(By.ByXPath.xpath("//*[@id=\"mainContent\"]/form/div[3]/div[13]/button[1]"));

// jse.executeScript("arguments[0].scrollIntoView()", queryBtn);

scrollToElementAndClick(queryBtn);

Thread.sleep(500); // 等待加载

driver.manage().window().maximize();

driver.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS);

driver.manage().timeouts().pageLoadTimeout(60, TimeUnit.SECONDS);

int pageIndex = Integer.parseInt(driver.findElement(By.xpath("//*[@id=\"mainContent\"]/div[2]/div[2]/div[1]/table/tfoot/tr[2]/td/div/ul/li[1]/span/font[3]")).getText());

int pageSize = Integer.parseInt(driver.findElement(By.xpath("//*[@id=\"mainContent\"]/div[2]/div[2]/div[1]/table/tfoot/tr[2]/td/div/ul/li[1]/span/font[2]")).getText());

// Actions actions = new Actions(driver);

while (pageIndex <= pageSize) {

pageIndex++;

WebElement tbody = driver.findElement(By.ByXPath.xpath("//*[@id=\"mainContent\"]/div[2]/div[2]/div[1]/table/tbody"));

List links = tbody.findElements(By.cssSelector("a[class=ng-binding]"));

for (WebElement link : links) {

WebDriver window;

System.out.println("-------------- voucherNo: "+ link.getText());

scrollToElementAndClick(link);

// jse.executeScript("arguments[0].scrollIntoView()", link);

// Thread.sleep(1000);

// actions.moveToElement(link).click().perform();

currentWindow = driver.getWindowHandle();

//get all windows

Set handles = driver.getWindowHandles();

for (String s : handles) {

//current page is don't close

if (s.equals(currentWindow) || s.equals(parentWindow))

continue;

else {

window = driver.switchTo().window(s);

window.manage().window().maximize();

window.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS);

window.manage().timeouts().pageLoadTimeout(60, TimeUnit.SECONDS);

//get all tables

String pageSource = window.getPageSource();

String jsonArray = parseDTO(pageSource);

System.out.println(jsonArray);

//close the table window

window.close();

}

//swich to current window

driver.switchTo().window(currentWindow);

}

}

// click next page

if (pageIndex <= pageSize) {

WebElement nextPage = driver.findElement(By.xpath("//*[@id=\"mainContent\"]/div[2]/div[2]/div[1]/table/tfoot/tr[2]/td/div/ul/li[3]/a"));

scrollToElementAndClick(nextPage);

//set next page to current page

driver = driver.switchTo().window(driver.getWindowHandle());

driver.manage().window().maximize();

driver.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS);

driver.manage().timeouts().pageLoadTimeout(60, TimeUnit.SECONDS);

}

}

我在stackoverflow上面查到过类似问题,也去官网上面看到了对应报错的解释:原因应该是我在跳转到子页面的时候,父页面进行的刷新,虽然在ui上面还能到那些链接,但是集合里面的链接是原先定义的,和遍历一次之后回来的父页面对应不上了。(我是这么理解的,如果我理解错了,请大神指出)。

然后我就按照官方的建议,每次页面去页面上拿链接而不是从原先定义的链接集合中拿。

先说明:每个链接的xpath都是有规律的,如:

//*[@id="mainContent"]/div[2]/div[2]/div[1]/table/tbody/tr[1]/td[2]/a

//*[@id="mainContent"]/div[2]/div[2]/div[1]/table/tbody/tr[2]/td[2]/a

//*[@id="mainContent"]/div[2]/div[2]/div[1]/table/tbody/tr[3]/td[2]/a

//*[@id="mainContent"]/div[2]/div[2]/div[1]/table/tbody/tr[%s]/td[2]/a

这是我第二次的代码:

while (pageIndex <= pageSize) {

pageIndex++;

WebElement tbody = driver.findElement(By.ByXPath.xpath("//*[@id=\"mainContent\"]/div[2]/div[2]/div[1]/table/tbody"));

List links = tbody.findElements(By.cssSelector("a[class=ng-binding]"));

int size = links.size();

for (int i = 1; i <= size; i++) {

String href = String.format("//*[@id=\"mainContent\"]/div[2]/div[2]/div[1]/table/tbody/tr[%s]/td[2]/a", i);

WebElement link = driver.findElement(By.xpath(href));

WebDriver window;

System.out.println("-------------- voucherNo: "+ link.getText());

scrollToElementAndClick(link);

currentWindow = driver.getWindowHandle();

//get all windows

Set handles = driver.getWindowHandles();

for (String s : handles) {

//current page is don't close

if (s.equals(currentWindow) || s.equals(parentWindow))

continue;

else {

window = driver.switchTo().window(s);

window.manage().window().maximize();

window.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS);

window.manage().timeouts().pageLoadTimeout(60, TimeUnit.SECONDS);

//get all tables

String pageSource = window.getPageSource();

String jsonArray = parseDTO(pageSource);

System.out.println(jsonArray);

//close the table window

window.close();

}

//swich to current window

driver.switchTo().window(currentWindow);

}

}

// click next page

if (pageIndex <= pageSize) {

WebElement nextPage = driver.findElement(By.xpath("//*[@id=\"mainContent\"]/div[2]/div[2]/div[1]/table/tfoot/tr[2]/td/div/ul/li[3]/a"));

scrollToElementAndClick(nextPage);

//set next page to current page

driver = driver.switchTo().window(driver.getWindowHandle());

driver.manage().window().maximize();

driver.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS);

driver.manage().timeouts().pageLoadTimeout(60, TimeUnit.SECONDS);

}

}

这次报了第二种错误:

Caused by: org.openqa.selenium.NoSuchElementException: {"errorMessage":"Unable to find element with xpath

Emm...试了很多种办法都没有用,希望有大神能救救我

万分感谢!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/431880.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

XmlDocument类

XmlDocument类是.NET框架的DOC解析器。XmlDocument将XML视为树状结构&#xff0c;它装载XML文档&#xff0c;并在内存中构建该文档的树状结构。下面来看下XmlDocument提供了哪些功能。 一、属性&#xff1a; Attributes      获取一个 XmlAttributeCollection&#xff0c…

java类作用域标识符_java入门 (二) 标识符、数据类型、类型转换、变量、常量、作用域...

java入门(二)标识符数据类型类型转换变量、常量、作用域本次笔记引用B站&#xff1a;狂神说,虽然早就会了&#xff0c;现在回头来敲下基础&#xff0c;加深印象1.标识符&#xff1a;java所有的组成部分都需要名字。类名丶变量名丶方法名统称为标识符。标识符大小写敏感。不能使…

0421 AutoLayout的实践/基本使用

历史:从iOS 6开始 ,之前都是3.5英寸没有考虑到适配.iPhone5 变成了4英寸,所以推出了Auto Layout理解: 另外一个体系,去描述位置.像素:点: // 勘误: 图中的像素应为 “点"// 写上以上代码,就可以删掉系统创建的控制器和storyBoard了.// 创建控制器,勾选Xib[]拖一个uiview背…

java 圆形按钮,如何在Java中创建圆形的JButton?

I want to create rounded JButton in Java...For that I use rounded image and placed that image on button but I didnt get rounded button..please any one can tell how to create rounded button in Java like show in below figure..thanks in advance.....解决方案If…

Python学习 Day 3 字符串 编码 list tuple 循环 dict set

字符串和编码 字符 ASCII Unicode UTF-8 A 1000001 00000000 01000001 1000001 中 x 01001110 00101101 11100100 10111000 10101101 格式化 在Python中&#xff0c;采用的格式化方式和C语言是一致的&#xff0c;用%实现&#xff0c;举例如下&#xff1a; >>&…

java 高飞_高飞(土木与水利工程学院)老师 - 合肥工业大学

高飞高飞老师的简历姓名:高飞 性别:男 出生年月:1962.11最终学位:硕士 毕业院校:合肥工业大学职称:教授 职务:副院长电话:0551-2901441,13705510744E-mail:gaofeihfut.edu.cn现从事专业:测绘科学与技术社会团体任职:1.全国高等学校测绘学科教学指导委员会,委员;2.中国测绘学会工…

jwPlayer为js预留的回调方法

参考地址&#xff1a;http://www.cnblogs.com/lori/archive/2014/05/05/3709459.html 应用场合 播放时记录当前视频的时间&#xff0c;播放完成时写入完成的时间&#xff0c;像这些功能&#xff0c;我们都可以通过事件回调的方法解决&#xff0c;即为events属性赋相应的值&…

java list 分组_Java 将List中的实体类按照某个字段进行分组并存

1、JDK1.8之前&#xff1a;假设有实体类User&#xff0c;里面有字段id&#xff0c;我们将相同id的User进行分组&#xff0c;并存放在Map中。(例子不是很恰当&#xff0c;但很能说明问题)public static void main(String[] args) {List list new ArrayList<>();list.add(…

UVa 11481 (计数) Arrange the Numbers

居然没有往错排公式那去想&#xff0c;真是太弱了。 先在前m个数中挑出k个位置不变的数&#xff0c;有C(m, k)种方案&#xff0c;然后枚举后面n-m个位置不变的数的个数i&#xff0c;剩下的n-k-i个数就是错排了。 所以这里要递推一个组合数和错排数。 顺便再复习一下错排递推公式…

java httpclient 关闭_【Java系列007】HttpClient调用:你考虑过关闭连接、并发了吗?...

你好&#xff01;我是miniluo&#xff0c;今天和你分享使用HttpClient过程中&#xff0c;未考虑释放连接和并发导致的坑。HttpClient在项目中还是比较常见的&#xff0c;主要都是通过GET或POST请求第三方以获取响应结果。前段时间还了解到也有企业用它来做爬虫。下面我们就从两…

UESTC_秋实大哥下棋 2015 UESTC Training for Data StructuresProblem I

I - 秋实大哥下棋 Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) Submit Status胜负胸中料已明&#xff0c;又从堂上出奇兵。秋实大哥是一个下棋好手&#xff0c;独孤求败的他觉得下棋已经无法满足他了&#xff0c;他开始研究一种新的…

java 6大原则_java 6大设计原则 一:观察者模式

解耦常用的模式OrderService.javaServicepublic class OrderService{AutowiredApplicationContext applicationContext ;public void saveOrder(){//1.创建订单System.out.println(“1.创建订单”)&#xff1b;OrderEvent event new OrderEvent("参数")application…

jbb是什么梗_子水是什么意思,子水命理

子水是十二地支之一&#xff0c;那么命中有子水的代表的是什么呢&#xff1f;适合什么方位呢&#xff1f;有什么喜忌吗&#xff1f;怎么分析你呢?现在金宝贝起名网为你介绍子水是什么意思,子水命理的相关文章。子水是什么意思,子水命理八字地支&#xff1a;子水是什么意思1、对…

IOS高级编程之二:IOS的数据存储与IO

一、应用程序沙盒 IOS应用程序职能在系统为该应用所分配的文件区域下读写文件&#xff0c;这个文件区域就是应用程序沙盒。所有的非代码文件如&#xff1a;图片、声音、映象等等都存放在此。 在mac中command&#xff0b;shift&#xff0b;G命令&#xff0c;然后输入users/用户名…

安卓投屏大师_苹果,安卓手机如何免费投屏?只要悄悄按下这里,便能轻松实现...

现在很多手机都有自带投屏功能&#xff0c;这样一来我们便可以将所看的视频&#xff0c;所玩的游戏投屏到电脑或电视上了&#xff0c;当然也需要这些设备支持投屏才行。一、无线投屏1、苹果手机苹果手机的投屏功能在哪里呢&#xff1f;只要打开苹果手机从下往上滑动&#xff0c…

b站电脑客户端_如何将B站的flv格式的视频转换成mp4格式

经常看到B站有精彩的视频片段&#xff0c;于是想把这些视频下载保存到电脑&#xff0c;但是发现没有下载按钮&#xff0c;是不是很悲催。有些时候想从优酷、土豆网这些视频网站下载视频&#xff0c;结果却提示要先下载视频客户端才能继续下载视频&#xff0c;运气差的话&#x…

asp.net 设置 excel alignment_教你如何用Python轻轻松松操作Excel、Word、CSV,一文就够了,赶紧码住!!!...

作者&#xff1a;奈何缘浅wyjhttps://juejin.im/post/6868073137263607821Python 操作 Excel常用工具数据处理是 Python 的一大应用场景&#xff0c;而 Excel 又是当前最流行的数据处理软件。因此用 Python 进行数据处理时&#xff0c;很容易会和 Excel 打起交道。得益于前人的…

java 页面输出一个页面_java学习之:一个完整页面输出信息的过程(以输出Doctor表中信息为例)...

最近在练习java程序&#xff0c;总结一下从数据库查询信息并输出到jsp页面的过程。主要数据处理在src.cn.javatest包下面项目预览1&#xff0c;配置项目根目录src目录下的druid.properties数据库信息(相当于一个数据库配置文件)里面的信息可以在下载druid中获得&#xff0c;只需…

[xsd学习]xsd介绍

一直以来项目中对xml格式的判断使用的都是dtd格式&#xff0c;直到最近才发现&#xff0c;不知何时都已经转为xsd来进行判断和校验&#xff0c;于是今天专门找资料看下&#xff0c;不得不说&#xff0c;对于这类资料的入门&#xff0c;w3cschool真是个不错的资料库&#xff0c;…

教学目标四个维度_【深度好文】体育教案中的教学目标与学习目标应如何表述...

体育教师大本营教学/训练/职业/成长强 烈 建 议 大 家 星 标 我 们教 学 路 上 ☆ 不 离 不 弃在以往看到的体育课的教案上&#xff0c;目标部分不是用教学目标就是用学习目标来表述&#xff0c;然而&#xff0c;这两种目标表达形式有没有本质区别&#xff1f;分别该如何表述…