【问题标题】:How to refresh the DOM tree in Selenium so newly generated elements are shown?如何刷新 Selenium 中的 DOM 树以便显示新生成的元素?
【发布时间】:2019-10-09 18:54:38
【问题描述】:

我想获取页面加载时不存在的 DOM 元素,但之后使用脚本添加。具体场景如下:

  1. 我加载了https://www.binance.com/de/trade/pro/XRP_BTC
  2. 我点击“TradingView”按钮
  3. 我在“技术指标”按钮上选择“随机 RSI”。

(所有这些步骤都由驱动程序本身使用click() 或机器人使用键和鼠标按键来处理)

在我选择了随机 RSI 之后,添加了新的 DOM 元素,而无需刷新页面。我正在寻找类名为"pane-legend-item-value-wrap"<span> 元素,它们是在添加“随机RSI”后生成的。

调用 driver.findElements(By.className("pane-legend-item-value-wrap")) 给我 0 个结果。我认为那是因为驱动程序页面源仍然是第一次立即加载页面后的那个。有没有办法刷新该页面源或 DOM 树无需重新加载整个页面

我尝试了隐式和显式等待,仍然没有成功并出现以下错误:

线程“主”org.openqa.selenium.TimeoutException 中的异常:预期条件失败:等待 By.className 定位的任何元素的存在:pane-legend-item-value-wrap(尝试了 15 秒)间隔 500 毫秒)

这是相关代码:

public class Main {

    public static void main(String args[]) {

        try {
            Selenium selenium = new Selenium();

            selenium.startChrome();

            for (int i = 0; i < 30000; i++) {

                try {
                    selenium.getChromeDriver().getTitle();
                } catch (WebDriverException e) {
                    i = 30000;
                    continue;
                }
                System.out.println("Current Coin Value: " + selenium.getValueOfCoin() + "$ - " + "StRSI Blue: "
                        + selenium.getBlueStRSI() + " - StRSI Red: " + selenium.getRedStRSI());
                Thread.sleep(200);

            }

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

    }
}

public class Selenium {

    private ChromeDriver chromeDriver;
    WebDriverWait wait;
    private Robot robot;

    public Selenium() throws AWTException {

    }

    public void startChrome() throws InterruptedException, AWTException {

        robot = new Robot();
        String pathToChromeDriver = "resources/driver/chromedriver.exe";
        ChromeOptions options = new ChromeOptions();
        options.addArguments("--start-maximized");
        System.setProperty("webdriver.chrome.driver", pathToChromeDriver);
        chromeDriver = new ChromeDriver(options);
        chromeDriver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);
        wait = new WebDriverWait(chromeDriver, 15);

        chromeDriver.get("https://www.binance.com/de/trade/pro/XRP_BTC");
        Thread.sleep(200);
        chromeDriver.findElement(By.className("DEMrI")).click();
        Thread.sleep(200);
        chromeDriver.findElements(By.className("csajsa")).get(0).click();
        chromeDriver.findElements(By.className("bEXbyP")).get(6).click();
        chromeDriver.findElements(By.className("bEXbyP")).get(5).click();

        setStochRSI();

        chromeDriver.findElements(By.className("mt9q6r-1")).get(1).click();

    }

    private void setStochRSI() throws AWTException, InterruptedException {

        Thread.sleep(3000);
        robot.mouseMove(650, 250);
        mouseClick();
        robot.keyPress(KeyEvent.VK_S);
        robot.keyRelease(KeyEvent.VK_S);
        robot.keyPress(KeyEvent.VK_T);
        robot.keyRelease(KeyEvent.VK_T);
        Thread.sleep(500);
        robot.mouseMove(500, 310);
        mouseClick();
        robot.mouseMove(877, 205);
        mouseClick();
        robot.mouseMove(1250, 650);
        Thread.sleep(100);
        robot.mouseMove(0, 0);

    }

    public Double getValueOfCoin() {

        return Double.parseDouble(chromeDriver.findElement(By.className("sc-1yysggs-0")).getText().substring(12));

    }

    public Double getBlueStRSI() {

        String value;
        value = wait
                .until(ExpectedConditions.presenceOfAllElementsLocatedBy(By.className("pane-legend-item-value-wrap")))
                .get(9).getText();

        return Double.parseDouble(value);

    }

    public Double getRedStRSI() {

        String value;
        value = wait
                .until(ExpectedConditions.presenceOfAllElementsLocatedBy(By.className("pane-legend-item-value-wrap")))
                .get(19).getText();

        return Double.parseDouble(value);

    }

    public ChromeDriver getChromeDriver() {

        return chromeDriver;

    }

    private void mouseClick() throws InterruptedException {
        robot.mousePress(MouseEvent.BUTTON1_MASK);
        Thread.sleep(50);
        robot.mouseRelease(MouseEvent.BUTTON1_MASK);
    }

}

【问题讨论】:

  • 如果它在页面上可见,它就在 DOM 中。听起来您可能需要添加一个等待它才能看到。

标签: java selenium selenium-webdriver dom selenium-chromedriver


【解决方案1】:

您找不到元素的原因是因为它们位于“iframe”中。您应该首先切换到 iframe 上下文,然后单击。这是一个工作示例:

    ChromeOptions chromeOptions = new ChromeOptions();

    ChromeDriver driver = new ChromeDriver(chromeOptions);

    driver.get("https://www.binance.com/de/trade/pro/XRP_BTC");

    WebDriverWait wait = new WebDriverWait(driver, 10);

    wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//*[@class='sc-1t2bpae-5 bEXbyP' and contains(text(),'TradingView')]"))).click();
    wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("//*[@class='sc-1t2bpae-5 bEXbyP' and contains(text(),'Technical Ind')]"))).click();
    WebElement frameElement = wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("//iframe[contains(@id, \"tradingview\")]")));
    driver.switchTo().frame(frameElement);
    wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("//div[contains(text(),'Stochastic RSI')]"))).click();

    WebElement element = driver.findElement(By.className("pane-legend-item-value-wrap"));

    driver.quit();

【讨论】:

  • 哇,我觉得自己很愚蠢...我应该彻底检查页面源代码。我稍后会尝试。已经谢谢了,这可能是真的。
  • 如果这对您有帮助,请告诉我
【解决方案2】:

有没有办法刷新页面源或 DOM 树?

再次致电get(),或使用navigate().refresh()

【讨论】:

  • 这只是刷新页面导致相同的过程再次发生。
  • 正确...回答了您最初提出的问题...在您对其进行编辑以澄清之前。
  • 对。好像我忘了具体说明,现在它有点清楚了:)。还是谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-17
  • 1970-01-01
  • 2015-08-20
  • 2013-05-22
  • 2011-04-04
相关资源
最近更新 更多