Selenium возвращает старое состояние PageSource и не обновляется после Javascript Execution - PullRequest
0 голосов
/ 04 августа 2020

У меня есть консольная программа в C# с Selenium, управляющим Chrome экземпляром браузера, и я хочу получить все ссылки со страницы.

Но после того, как страница загрузилась в Selenium, PageSource из Selenium отличается от HTML веб-сайта, на который я перешел. Содержимое страницы асинхронно загружается JavaScript, а HTML изменяется.

Даже если я загружаю HTML веб-сайта, как показано ниже, HTML все равно отличается от внутри окна браузера, управляемого Selenium:

var html = ((IJavaScriptExecutor)driver).ExecuteScript("return document.getElementsByTagName('html')[0].outerHTML").ToString();

Но почему PageSource или HTML, возвращаемый моим JS, по-прежнему такие же, как и при загрузке страницы Selenium?

EDIT: как указал @BinaryBob, я теперь реализовал функцию ожидания, чтобы ждать, пока желаемый элемент не изменит значение атрибута c. Код выглядит так:

private static void AttributeIsNotEmpty(IWebDriver driver, By locator, string attribute, int secondsToWait = 60)
{
    new WebDriverWait(driver, new TimeSpan(0, 0, secondsToWait)).Until(d => IsAttributeEmpty(d, locator, attribute));
}

private static bool IsAttributeEmpty(IWebDriver driver, By locator, string attribute)
{
    Console.WriteLine("Output: " + driver.FindElement(locator).GetAttribute(attribute));

    return !string.IsNullOrEmpty(driver.FindElement(locator).GetAttribute(attribute));
}

И вызов функции выглядит так:

AttributeIsNotEmpty(driver, By.XPath("/html/body/div[2]/c-wiz/div[4]/div[1]/div/div/div/div/div[1]/div[1]/div[1]/a[1]"), "href");

Но условие никогда не выполняется и генерируется тайм-аут. Но внутри браузера Chrome (которым управляет Selenium) условие выполнено, и элемент имеет заполненный атрибут href.

1 Ответ

1 голос
/ 05 августа 2020

Я пытаюсь это сделать. Вы вызываете wait.Until (ExpectedConditions ...) где-нибудь в своем коде? Если нет, это может быть проблемой. Тот факт, что метод FindElement был возвращен, не означает, что страница завершила рендеринг.

Для быстрого примера этот код взят с сайта документации Selenium. Обратите внимание на создание объекта WebDriverWait (строка 1) и его использование в назначении firstResult (строка 4)

WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
driver.Navigate().GoToUrl("https://www.google.com/ncr");
driver.FindElement(By.Name("q")).SendKeys("cheese" + Keys.Enter);
IWebElement firstResult = wait.Until(ExpectedConditions.ElementExists(By.CssSelector("h3>div")));
Console.WriteLine(firstResult.GetAttribute("textContent"));

Если это действительно проблема, вам может потребоваться прочитать различные способы использования ExpectedConditions. Я бы начал здесь: Документация Selenium: WebDriver Waits

...