0

いくつかの特定のアイテムに対してAliExpressをスクラップしようとしていますが、コードがアイテムのいずれかに到達すると(完全に非決定的)、parseItemsメソッドのurle要素は、このメソッドは例外をスローします。SeleniumによるWebスクレイピング:コードがランダムにスローされるStaleElementReferenceException

コード:

package com.ardilgulez.seleniumweb; 

import org.openqa.selenium.By; 
import org.openqa.selenium.WebDriver; 
import org.openqa.selenium.WebElement; 
import org.openqa.selenium.firefox.FirefoxDriver; 
import org.openqa.selenium.support.ui.ExpectedConditions; 
import org.openqa.selenium.support.ui.WebDriverWait; 

import java.util.List; 
import java.util.concurrent.TimeUnit; 

public class App { 

    private static WebDriver firefoxDriver = new FirefoxDriver(); 

    public static boolean parseItems throws StaleElementReferenceException (List<WebElement> items){ 
     System.out.println(items.size()); 
     if(items.size() > 0){ 
      items.forEach((item) -> { 
       WebElement urlelement = item.findElement(By.cssSelector(".detail>h3>a")); 
       String href = urlelement.getAttribute("href"); 
       System.out.println(href); 
       String title = urlelement.getAttribute("title"); 
       System.out.println(title); 
      }); 
     } 
     return true; 
    } 

    public static void main(String[] args) { 
     firefoxDriver.get("https://www.aliexpress.com/"); 
     firefoxDriver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS); 

     WebElement questionElement = firefoxDriver.findElement(By.xpath("//input[@name='SearchText']")); 
     questionElement.sendKeys("ESP8266"); 
     questionElement.submit(); 

     while (true) { 
      try { 
       (new WebDriverWait(firefoxDriver, 10)) 
        .until((WebDriver webDriver) -> ((JavascriptExecutor) webDriver).executeScript("return document.readyState").equals("complete")); 

       (new WebDriverWait(firefoxDriver, 10)) 
        .until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//ul[@id='hs-list-items']"))); 

       (new WebDriverWait(firefoxDriver, 10)) 
        .until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//div[@id='hs-below-list-items']"))); 

       System.out.println("WAIT1"); 

       (new WebDriverWait(firefoxDriver, 20)) 
         .until((WebDriver webDriver) -> { 
          WebElement listItemsUL = (new WebDriverWait(webDriver, 10)) 
           .until(ExpectedConditions.presenceOfElementLocated(By.xpath("//ul[@id='hs-list-items']"))); 

          List<WebElement> items = listItemsUL.findElements(By.tagName("li")); 
          return parseItems(items); 
         }); 

       (new WebDriverWait(firefoxDriver, 20)) 
         .until((WebDriver webDriver) -> { 
          WebElement belowListItemsDiv = (new WebDriverWait(webDriver, 10)) 
           .until(ExpectedConditions.presenceOfElementLocated(By.xpath("//div[@id='hs-below-list-items']"))); 

          WebElement belowListItemsUL = belowListItemsDiv.findElement(By.tagName("ul")); 
          List<WebElement> items = belowListItemsUL.findElements(By.tagName("li")); 
          return parseItems(items); 
         }); 

       System.out.println("WAIT2"); 

       WebElement nextElement = (new WebDriverWait(firefoxDriver, 10)) 
        .until(ExpectedConditions.presenceOfElementLocated(By.xpath("//a[@class='page-next ui-pagination-next']"))); 

       System.out.println(nextElement.toString()); 
       System.out.println("CLICK CLICK"); 
       nextElement.click(); 

      } catch (Exception e) { 
       e.printStackTrace(); 
       break; 
      } 
     } 
    } 
} 

コードがそのHREFを取得しますが、コードの前にそのタイトルを取得した後、時には要素も、例外がスローされます。

私のコードで何が起こっているのか分かりません。無作為に作業しないと決めるまで、実際にはうまく動作しますが、理由は分かりません。

答えて

1

ページが適切に準備されるのを待っているのではなく、リストに前のページの要素が含まれている可能性があります。

前のページには、このように、もはやリストからいくつかの要素は、ページ付け]ボタンをクリックした後、古いなるまで待つ盛試みであることを確認しないように:

nextElement.click(); 
new WebDriverWait(firefoxDriver, 20)).until ExpectedConditions.stalenessOf(someElementFromTheList)); 
+0

あなたは素晴らしい人だ@Renato、どうもありがとうございます。 – ardilgulez

関連する問題