LINUX.ORG.RU

Одновременный поиск одного из двух элементов на странице

 , ,


0

2

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

data = WebDriverWait(driver, 100000).until(
            EC.visibility_of_element_located((By.ID, "id_name"))
        )

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

nodata = WebDriverWait(driver, 100000).until(
            EC.visibility_of_element_located((By.XPATH, "xpath_text"))
        )

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

Ответ на: комментарий от Irma

Речь о конструкциях вида

WebDriverWait(driver, 100000).until(
            EC.presense_of_all_elements_located((By.XPATH, '//*'))
        )
elements = driver.find_elements(By.XPATH, '//*')
for element in elements:
    ...
    ...

? Это так же приводит к слишком долгому выполнению кода, на странице много элементов и, как я и говорю, загружаются как попало.

Nevermind
() автор топика
Ответ на: комментарий от Nevermind

Ну я вообще не программист, но ждать чего-то по таймеру и мне кажется глупой идеей. Погугли в направлении python do not wait for EC.presense_of_all_elements_located или даже не ожидание, а перехват события.

Короче, гугл навел меня на python wait for multiple EC.presense_of_all_elements_located и отправил на stackoverflow.

Irma ★★
()
Последнее исправление: Irma (всего исправлений: 1)

рой в сторону async await - но не глубоко до них - а чисто использовать асинхронные либы - и общее понимание io-bound процессов

ибо алгоритма тут нет есть реакции на события -> асинхронность без всяких твоих явных ожиданий машинерия организации порядка обработки на цикле_обработки_событий того или иного модуля с тебя тока сами обработчики событий

давай уже

qulinxao3
()

Не помню как с питоном, в жаве можно обращаться к JS событиям и тупо ждать окончания всех фоновых процессов, возможно идея с async await это оно и есть, как выше подсказали. Или сам напиши цикл ожидания с проверкой двух условий на замену until.

Lordwind ★★★★★
()

Посмотри, что принимает метод until и реализуй кастомный Wait Condition (или найди готовый). Должно получиться что-то типа

.until(or(EC.visibility_of_element_located((By.XPATH, "xpath_text1")), EC.visibility_of_element_located((By.XPATH, "xpath_text2"))))

DarkAmateur ★★★★
()
Ответ на: комментарий от Irma

Ну я вообще не программист, но ждать чего-то по таймеру и мне кажется глупой идеей.

Это не совсем по таймеру. Это максимально допустимое время ожидания, при превышении которого выкидывается исключение и тест проваливается. Это не глупая идея, это стандартная практика.

DarkAmateur ★★★★
()

А если просто воспользоваться оператором | в xpath-выражении и потом проверить что именно появилось? Такое .//pre/code[contains(text(), 'id_name')]|.//code[contains(text(), 'xpath_text')], например, на этой странице найдет оба ваших <code>

melanogaster
()

Существует какой-то способ одновременно ожидать появление одного из двух элементов?

EC.any_of. Нужно было всего лишь в доку заглянуть.

anonymous
()