Невозможно найти элемент с Selenium в Python

По этому URL: https://ec.europa.eu/economy_finance/recovery-and-resilience-scoreboard/milestones_and_targets.html?lang=en

Я хочу нажать на следующую кнопку:

а затем нажмите «Просмотреть таблицу данных», но я не могу найти соответствующий элемент. Код, который я использую, следующий:

from selenium import webdriver

driver = webdriver.Firefox()
driver.get('https://ec.europa.eu/economy_finance/recovery-and-resilience-scoreboard/milestones_and_targets.html?lang=en')
element = driver.find_element(By.XPATH, '//*[@id = "highcharts-ldz37cw-0"]/svg/g[7]/g')
element.click()

Ошибка, которую я получаю:

NoSuchElementException: невозможно найти элемент: //*[@id="highcharts-ldz37cw-0"]/svg/g[7]/g; Документацию по этой ошибке можно найти по адресу: https://www.selenium.dev/documentation/webdriver/troubleshooting/errors#no- such-element-Exception

В чем может быть проблема?

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

John Gordon 10.07.2024 18:28

Возможно, вам просто нужно немного подождать, чтобы элемент стал активным. Вы пробовали это?

John Gordon 10.07.2024 18:31

Я получаю ошибку NoSuchElementException. Жду полной загрузки сайта. Проблема не в этом.

Theodosis Siomos 10.07.2024 18:35

«Я жду полной загрузки веб-сайта» — как именно вы ждете? Здесь нет кода, который бы ждал. Вызов find_element() происходит сразу после вызова driver.get(), и между ними нет ничего, что могло бы ждать. Как код ждет?

John Gordon 10.07.2024 18:37

Я запускаю код построчно.

Theodosis Siomos 10.07.2024 18:40

Код Python всегда выполняется «построчно», поэтому я понятия не имею, что вы имеете в виду.

John Gordon 10.07.2024 18:41

Я запускаю код в интерактивном режиме построчно.

Theodosis Siomos 10.07.2024 18:43

Я подозреваю, что значение идентификатора highcharts-ldz37cw-0 не является постоянным — оно может меняться каждый раз при загрузке страницы. Я только что загрузил эту страницу, и значение идентификатора — highcharts-fy53m3a-0.

John Gordon 10.07.2024 18:46

Итак, вопрос в том, какой xpath подходит для этого элемента?

Theodosis Siomos 10.07.2024 18:59

Не зная полной структуры страницы, я не могу ответить на этот вопрос. Обычный подход состоит в том, чтобы просмотреть исходный код страницы и найти некоторый элемент-предок, который однозначно идентифицируется (часто с использованием его атрибутов id или class), и построить относительный xpath, начиная с этого элемента, вплоть до желаемого целевого элемента.

John Gordon 10.07.2024 19:18

И на самом деле это именно то, что вы сделали, за исключением того, что вы не знали, что значение id является переменным.

John Gordon 10.07.2024 19:29
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
11
68
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains

driver = webdriver.Firefox()
element = driver.find_element(By.XPATH, '//*[@class = "highcharts-exporting-group"]')
ActionChains(driver).move_to_element(element).click().perform()

Обратите внимание, что идентификатор highcharts-ldz37cw-0 генерируется динамически, поэтому вам следует либо избегать его использования, либо найти обходной путь с помощью contains или чего-то еще.

find_elements() возвращает список, у которого явно нет метода .click(). Вы имели в виду find_element() вместо этого?
John Gordon 10.07.2024 20:02

Хороший улов, спасибо. Конечно, find_element() или find_elements()[0], я отредактировал ответ.

Kliment Merzlyakov 10.07.2024 20:05

Хотя вы можете выбрать элемент, как вы упомянули, вы не можете щелкнуть его. Я получаю ElementNotInteractableException: элемент <g class = "highcharts-exporting-group"> не удалось прокрутить в поле зрения

Theodosis Siomos 10.07.2024 20:12

@TheodosisSiomos, ты прав. Затем вам нужно прокрутить до элемента. Либо по driver.execute_script("window.scroll(0, 600)") , либо по ActionChains. Я обновил ответ, не могли бы вы проверить?

Kliment Merzlyakov 10.07.2024 20:47

Что ж, теперь я получаю: MoveTargetOutOfBoundsException: цель перемещения (632, 783) выходит за пределы размеров области просмотра (1360, 643).

Theodosis Siomos 10.07.2024 21:18
Ответ принят как подходящий

Я просмотрел код и нашел метод viewData(), который вызывается при нажатии View data table.

Мы можем напрямую вызвать его для первого графика, используя этот скрипт: window.Highcharts.charts[0].viewData()

И сделать это в селене:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

driver = webdriver.Chrome()
driver.get('https://ec.europa.eu/economy_finance/recovery-and-resilience-scoreboard/milestones_and_targets.html?lang=en')

# wait until chart is loaded
WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.CSS_SELECTOR, 'div#fulfillmentStatusBarChart > div[id^=highcharts]')))

# show data table for ALL charts
driver.execute_script('window.Highcharts.charts.forEach(ch => ch.viewData())')

# select the data table
table = driver.find_element(By.CSS_SELECTOR, 'table[id^=highcharts-data-table]') # div.highcharts-data-table
print(table.text)

Как вы узнали, что здесь задействован сценарий?

Theodosis Siomos 11.07.2024 09:51

@TheodosisSiomos отладчик, код не запутан, поэтому его гораздо легче понять.

GTK 11.07.2024 16:53

Другие вопросы по теме