Selenium driver get не переходит на страницу

Обновлено: 07.07.2024

Как заставить Selenium 2.0 ждать загрузки страницы?

Вы также можете проверить загруженную страницу, используя следующий код

Можно подумать, что что-то подобное будет встроено. Ожидание загрузки страницы - довольно распространенная вещь в Интернете. К вашему сведению - даже вышеупомянутое не гарантирует, что страница готова - просто, что дом готов. Любой dojo / jquery может по-прежнему динамически создавать элементы на странице, поэтому вам может потребоваться сначала подождать динамические элементы, прежде чем взаимодействовать с ними. Имейте в виду, что этот метод проверяет только DOM. Если вы используете Ajax или AngularJS, это не будет работать, потому что будут некоторые асинхронные вызовы, которые не могут быть обнаружены document.readyState. Это сработало отлично. Это очень хороший современный способ решения проблемы. Что делать, если я не знаю, какой элемент будет на странице? Это будет работать, чтобы дождаться загрузки определенного элемента, а не всей страницы. Это вовсе не гарантирует, что элемент будет полностью загружен, и не отвечает на вопрос. Как кто-нибудь может поддержать это?

Если вы установите неявное ожидание драйвера, а затем вызовите findElement метод для элемента, который, как вы ожидаете, будет на загруженной странице, WebDriver будет запрашивать этот элемент, пока не найдет элемент или не достигнет значения времени ожидания.

Это означает, что он попробует что-то в течение 10 секунд, прежде чем вызовет исключение. поэтому он не может быть уверен, что это займет 10 секунд. @ testerjoe2 ждет, пока будет найден конкретный элемент, вопрос в том, как ждать загрузки страницы.

В целом, в Selenium 2.0 веб-драйвер должен возвращать управление вызывающему коду только после того, как определит, что страница загружена. Если это не так, вы можете позвонить waitforelemement , который циклически повторяет вызов findelement до тех пор, пока он не будет найден или не истечет время ожидания (можно установить время ожидания).

К сожалению, Selenium 2 не всегда ждет загрузки страницы. Например, WebElement: click () не ждет, и об этом прямо говорится в принадлежащем Javadoc. Тем не менее, они не говорят, как я могу проверить новую страницу для загрузки. If click() causes a new page to be loaded via an event or is done by sending a native event (which is a common case on Firefox, IE on Windows) then the method will not wait for it to be loaded and the caller should verify that a new page has been loaded. С документа . и метод будет блокироваться, пока загрузка не будет завершена . @Karna: Да, теоретически так должно быть всегда, а на практике - большую часть времени. Использование Selenium в то время показало, что были времена, когда он думал, что страница закончила загрузку, но это не так. Я не использовал селен в последнее время, так что это может быть, а может и не быть. Я согласен: особенно драйвер Internet Explorer глючит и сразу же возвращает управление, даже если страница все еще загружается. В моем случае я добавил ожидание, используя для того JavascriptExecutor , чтобы document.readyState было «завершено». Я полагаю, что из-за обратной поездки от селена к браузеру состояние гонки смягчается, и это «всегда» работает для меня. После «click ()», когда я ожидаю загрузки страницы, я явно жду (используя WebDriverWait) состояние готовности. ] Эквивалент Python: WebDriverWait (драйвер, 10) .until (лямбда-d: d.execute_script ('return document.readyState') == 'complete') Python использует приведенный выше код, но не забудьте эту строку .. | из selenium.webdriver.support.ui import WebDriverWait У меня была проблема при нажатии на элемент, когда страница была загружена не полностью. В Python я попробовал time.sleep (30). Это сработало. Это всегда будет ждать максимум 30 секунд. Затем я попробовал следующий код, и теперь он более эффективен, быстрее. WebDriverWait (драйвер, 10) .until (лямбда-д: driver.find_element_by_xpath ("// div [. = 'Administration']").

Вы можете удалить System.out строку. Это добавлено для целей отладки.

Спасибо за эти советы. Я добавляю это в мой SeleniumHelper; ср javabox

Все эти решения подходят для конкретных случаев, но они страдают по крайней мере от одной из пары возможных проблем:

Они не достаточно универсальны - они хотят, чтобы вы знали заранее, что для страницы, на которую вы переходите, будут выполняться некоторые конкретные условия (например, будет отображаться какой-то элемент)

Они открыты для состояния гонки, когда вы используете элемент, который фактически присутствует на старой странице, а также на новой странице.

Вот моя попытка общего решения, которое позволяет избежать этой проблемы (в Python):

Во-первых, общая функция ожидания (используйте WebDriverWait, если хотите, я нахожу их безобразными):

Далее, решение опирается на тот факт, что селен записывает (внутренний) id-номер для всех элементов на странице, включая <html> элемент верхнего уровня . Когда страница обновляется или загружается, она получает новый HTML-элемент с новым идентификатором.

Итак, если вы хотите нажать на ссылку с текстом «моя ссылка», например:

Для большего Pythonic, многоразового, универсального помощника, вы можете сделать контекстный менеджер:

И тогда вы можете использовать его практически для любого взаимодействия с селеном:

В предыдущей статье я рассказал, как Selenium ожидает завершения загрузки страницы.

Вкратце повторю: перед выполнением каждой команды он проверяет значение свойства document.readyState и приостанавливает выполнение команды до тех пор, пока это свойство не приобретёт значение complete .

Однако иногда эта стратегия приводит к провалу. Бывают такие ситуации, когда свойство document.readyState либо очень долго не может попасть в состояние complete, либо вообще никогда не достигает этого состояния.

Представьте себе, что на странице приложения есть большая картинка, которая загружается с ооооочень медленного сервера. Вся страница уже давным-давно загрузилась, с ней можно работать, но из-за этой дурацкой картинки браузер продолжает крутить колёсико загрузки, а Selenium продолжает ждать…

Вот реальный пример, который демонстрирует эту проблему:

На моей машине выполнение этого фрагмента кода занимает от 20 до 40 секунд (без учёта времени на запуск браузера). Причина как раз в том, что на страницу грузится большая картинка (

7 мегабайт). При этом нужная кнопка для переключения на английскую версию сайта становится доступна уже через несколько секунд, но Selenium ждёт, пока загрузится вся страница целиком.

Можно ли что-нибудь сделать, чтобы Selenium не ждал так долго?

Есть два способа:

  • установить таймаут ожидания загрузки
  • изменить стратегию завершения загрузки

Таймаут ожидания загрузки

Установка таймаута ожидания загрузки приводит к тому, что операция get выбрасывает исключение TimeoutException , если страница не успела загрузиться в течение заданного количества времени. При этом после возникновения исключения загрузка страницы не прерывается, но зато появляется возможность “досрочно” выполнять с ней какие-нибудь действия. Однако следует помнить, что на такой “недозагруженной” странице нужные для дальнейших действий элементы ещё могли не появиться, поэтому требуются дополнительные ожидания появления элементов:

В таком варианте код выполняется примерно за 4 секунды (без учёта времени на запуск браузера).

Быстро – ещё не значит правильно :)

Дело в том, что элемент с идентификатором menu есть как на первой странице, так и на второй. В тот момент, когда выполняется клик по кнопке с идентификатором en (переключение на английскую версию сайта), элемент с идентификатором menu тоже присутствует на странице. И Selenium, вместо того, чтобы после клика ждать загрузки второй страницы, немедленно “находит” этот элемент на первой странице.

Причина этого в том, что, как я уже упоминал, после возникновения TimeoutException загрузка страницы не прерывается, она продолжает загружаться, в том числе и в момент выполнения команды click . Это сбивает Selenium с толку, он не понимает, что должна появиться другая страница, и вместо этого ищет элементы на текущей странице.

Ну, раз уж мы отобрали у Selenium и взяли на себя ответственность за ожидание загрузки страницы, надо брать ответственность и за “выгрузку” страницы тоже. То есть перед ожиданием появления элемента, который должен найтись на следующей странице, нужно сначала подождать, пока исчезнет элемент, находящийся на текущей странице. Например, исчезнет та самая кнопка, по которой кликали:

Теперь этот фрагмент кода выполняется примерно 10 секунд (без учёта времени на запуск браузера), и это правильно – около 5 секунд на каждую страницу.

Недостаток описанного выше способа заключается в том, что приходится оборачивать в блок try-catch все вызовы команд, которые могут привести к началу загрузки новой страницы. А это может быть вообще говоря любая команда. То есть исключение TimeoutException нужно ожидать буквально везде. Это ужасно!

К счастью, есть другой способ.

Стратегия ожидания загрузки

Если вы ещё помните, Selenium перед выполнением каждой команды он проверяет значение свойства document.readyState и приостанавливает выполнение команды до тех пор, пока это свойство не приобретёт значение complete .

В процессе обработки страницы браузер меняет это свойство, отражая информацию о текущем этапе загрузки:

  • loading означает, что страница ещё загружается,
  • interactive означает, что основное содержимое страницы загрузилось и отрисовалось, пользователь уже может с ней взаимодействовать, но ещё продолжается загрузка дополнительных ресурсов,
  • complete означает, что все дополнительные ресурсы тоже загружены.

Так вот, можно изменить настройки Selenium так, чтобы он ждал не значения complete , а значения interactive , или даже вообще не ждал ничего.

Для этого при инициализации драйвера надо установить подходящее значение для capability с названием pageLoadStrategy .

  • normal (установлено по умолчанию) – ждать, пока свойство document.readyState примет значение complete
  • eager – ждать, пока свойство document.readyState примет значение interactive
  • none – вообще не ждать

Конечно, и в этом случае тоже приходится брать на себя ответственность за ожидание “выгрузки” страниц.

Вот тот же самый пример, на этот раз без таймаутов, но с изменённой стратегией ожидания:

В этом варианте сценарий тоже отрабатывает примерно за 10 секунд (без учёта времени на запуск браузера).

P.S. Я думаю, вы поняли, что с использованием только неявных (implicit) ожиданий описанные выше трюки сделать не получится.

Алексей Баранцев

Автор: Алексей Баранцев

Если вам понравилась эта статья, вы можете поделиться ею в социальных сетях (кнопочки ниже), а потом вернуться на главную страницу блога и почитать другие мои статьи.
Ну а если вы не согласны с чем-то или хотите что-нибудь дополнить – оставьте комментарий ниже, может быть это послужит поводом для написания новой интересной статьи.

Я хочу очистить все данные страницы, реализованные с помощью бесконечной прокрутки. Следующий код python работает.

The webdriver будет ждать загрузки страницы по умолчанию через .get() метод.

как вы можете искать какой-то конкретный элемент, как @user227215 сказал, Вы должны использовать WebDriverWait чтобы дождаться элемента, расположенного на Вашей странице:

я использовал его для проверки оповещения. Вы можете использовать любые другие методы типа найти локатор.

EDIT 1:

Я должен упомянуть, что webdriver будет ждать загрузки страницы по умолчанию. Оно не ждет загрузки внутри фреймов или запросов ajax. Это означает, когда вы используете .get('url') Ваш браузер будет ждать, пока страница полностью загружена, а затем перейти к следующей команде в код. Но когда вы отправляете запрос ajax, webdriver не ждет, и это ваша ответственность, чтобы ждать соответствующее количество времени для страницы или части страницы для загрузки; так что есть модуль с именем expected_conditions .

пыталась передать find_element_by_id конструктора presence_of_element_located (как показано на принято отвечать) причинил NoSuchElementException должен быть поднят. Мне пришлось использовать синтаксис fragles'комментарий:

Это соответствует пример в документации. Вот ссылка на документация для By.

readyState

проверка состояния готовности страницы (ненадежно):

The wait_for вспомогательная функция хороша, но к сожалению click_through_to_new_page открыт для условия гонки, где нам удается выполнить скрипт на старой странице, прежде чем браузер начнет обработку щелчка, и page_has_loaded просто возвращает true сразу.

сравнение новых идентификаторов страниц с старый:

возможно, что сравнение идентификаторов не так эффективно, как ожидание устаревших ссылочных исключений.

staleness_of

используя staleness_of способ:

для получения более подробной информации, проверьте Гарри.

на боковой ноте, вместо прокрутки вниз 100 раз, вы можете проверить, нет ли больше изменений в DOM (мы находимся в случае нижней части страницы, загруженной AJAX lazy-loaded)

Как насчет того, чтобы поместить WebDriverWait в цикл While и поймать исключения.

Три случая, когда Selenium WebDriver не может найти элемент

Потратьте некоторое время сегодня, чтобы подвести итог ситуации, когда Selenium WebDriver не может найти элемент.
Конечно, здесь дело в том, что CSS или XPath не ошибочны, позиционирование является точным, и это не использование нестабильных операторов позиционирования.


Ситуация 1:(StaleElementReferenceException: Message: Element not found in the cache. )
обновление страницы


Причина: страница была обновлена.
Я не могу найти этот элемент на текущей странице, но вы вручную скопировали его в инструмент разработчика страниц, чтобы убедиться, что он есть. Почему вы не можете найти его в коде? В это время вы также можете спросить«Но элемент явно присутствует, и он не изменился. Даже если я вернул его обратно, страница не изменилась. Как я могу сказать, что это новая страница?».
Фактически, страница изменилась и обновилась во время операции. Хотя два элемента на поверхности выглядят одинаково, фактически каждый элемент имеет свой собственный идентификатор номер.
Используйте код (Python), чтобы доказать это!


Результат выглядит следующим образом: Очевидно, что элемент имеет соответствующий идентификатор, который отличается, он может быть использован и доступен только при текущей странице.

Анализ:
refresh , Активно ли вы обновляете или автоматически обновляете страницу
back , Перешел на другую страницу, а затем вы используете driver.back (), чтобы перейти назад, это тоже новая страница
Перейти на новую страницу , Но есть некоторые элементы на этой новой странице, которые выглядят так же, как и на предыдущей странице, это тоже новая страница. Например: ряд кнопок подкачки, вы нажимаете на следующую страницу, чтобы перейти на вторую страницу, вы хотите использовать оригинальные элементы для перехода на следующую страницу, что невозможно.

Решение:
Пока вы обновляете страницу и повторно запрашиваете элементы, не получайте заранее группу элементов, а затем просматривайте каждый элемент в цикле Элемент местоположения приобретается только при его использовании, так что вы можете получить последний идентификатор, не стесняясь найти неправильного человека.


Я встретил один сегодня, но я встречал это раньше, но я не сосредоточился на записи.
Существует четыре меню, в каждом из которых четыре раза щелкают входящие данные, чтобы проверить, может ли быть достигнута другая страница и нормально ли она возвращается.
Я использовал цикл, но сначала я не стал внимательно присматриваться, я непосредственно зациклил его на элементе, и после завершения проверки новой страницы я вернулся на исходную страницу и продолжил поиск. Потом я вспомнил, что вместо циклических элементов число элементов должно быть зациклено.В процессе зацикливания мы должны найти элементы.

Ситуация 2:Iframe не может найти элемент и нужно переключить Iframe

【Ссылка на эту статью】Эта ситуация обычно возникает, когда есть встроенный iframe, и вам нужно переключить iframe
Также обратите внимание, что на некоторых страницах будет несколько iframe, и если элемент не найден, iframe не переключается, просто переключитесь.

Случай 3: скорость нажатия слишком высока, и вам нужно щелкнуть элементы на странице перед загрузкой страницы.


Это должно увеличить определенное время ожидания, время ожидания дисплея может быть достигнуто с помощью WebDriverWait и util

Интеллектуальная рекомендация

совместный запрос mysql с тремя таблицами (таблица сотрудников, таблица отделов, таблица зарплат)

1. Краткое изложение проблемы: (внизу есть инструкция по созданию таблицы, копирование можно непосредственно практиковать с помощью (mysql)) Найдите отделы, в которых есть хотя бы один сотрудник. Отоб.


[Загрузчик классов обучения JVM] Третий день пользовательского контента, связанного с загрузчиком классов


IP, сеанс и cookie

Читайте также: