日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

發布時間:2023/12/10 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 webdriver 爬虫 java_java爬虫通过selenium+WebDriver遍历页面链接报错 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

背景

由于要爬取的頁面,每個鏈接的請求都是點擊之后js動態發起的,目標數據也多是js動態生成的,所以使用selenium工具+webdriver(調試用的是chrome,具體使用準備用phantomjs).

模擬登錄之后,模擬查詢之后,得到如下列表

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

接下去步驟是這樣的:

得到鏈接的集合

遍歷集合,點擊鏈接,得到對應的詳情頁面

通過頁面句柄轉到詳情頁面,拿到目標數據,再轉回父頁面

如上繼續遍歷

問題

按照如上邏輯,在執行到遍歷步驟的時候,在第二次時報錯了。

第一種報錯:

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...試了很多種辦法都沒有用,希望有大神能救救我

萬分感謝!!!

總結

以上是生活随笔為你收集整理的webdriver 爬虫 java_java爬虫通过selenium+WebDriver遍历页面链接报错的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。