点击链接后,目标页面的请求由js发起。
所以我计划使用selenium + webdriver来模拟点击并获取页面数据。(我首先使用chrome驱动程序进行调试)
父页面如下:
很明显,我无法直接获取链接'页面上的网址。
以下步骤如下:
根据上述逻辑,错误发生在第二次。
第一个问题:
org.openqa.selenium.StaleElementReferenceException: stale element
reference: element is not attached to the page document
我的代码:
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());
while (pageIndex <= pageSize) {
pageIndex++;
WebElement tbody = driver.findElement(By.ByXPath.xpath("//*[@id=\"mainContent\"]/div[2]/div[2]/div[1]/table/tbody"));
List<WebElement> links = tbody.findElements(By.cssSelector("a[class=ng-binding]"));
for (WebElement link : links) {
WebDriver window;
System.out.println("-------------- voucherNo: " + link.getText());
scrollToElementAndClick(link);
currentWindow = driver.getWindowHandle();
//get all windows
Set<String> 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上看到链接,但之前定义的链接列表与当前父页面并不对应(我理解这种方式,如果我误解了,请指出)。
所以我修改了代码:
while (pageIndex <= pageSize) {
pageIndex++;
WebElement tbody = driver.findElement(By.ByXPath.xpath("//*[@id=\"mainContent\"]/div[2]/div[2]/div[1]/table/tbody"));
List<WebElement> 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<String> 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);
}
}
链接&#39; 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
然后发生第二次排队:
引起:org.openqa.selenium.NoSuchElementException:{&#34; errorMessage&#34;:&#34;无法找到带有xpath的元素
嗯......我无法理解为什么我无法获得webElement。它就在页面上。
好吧,我注意到在那个问题中,链接url可以从页面获取。该问题的接受答案使用字符串列表来存储链接href。并使用((JavascriptExecutor) driver).executeScript("window.open(arguments[0])
,myhref);执行它们。但就我而言,我无法获得网址。我需要逐个点击链接。