Selenium "selenium.common.exceptions.NoSuchElementException" при использовании Chrome
Я пытаюсь воспроизвести QWOP, используя Selenium в Chrome, но продолжаю получать следующую ошибку:
selenium.common.exceptions.NoSuchElementException:
Message: no such element: Unable to locate element
{"method":"id","selector":"window1"
(Session info: chrome=63.0.3239.108
(Driver info: chromedriver=2.34.522913
(36222509aa6e819815938cbf2709b4849735537c), platform=Linux 4.10.0-42-generic x86_64)
при использовании следующего кода:
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
import time
browser = webdriver.Chrome()
browser.set_window_size(640, 480)
browser.get('http://www.foddy.net/Athletics.html?webgl=true')
browser.implicitly_wait(10)
canvas = browser.find_element_by_id("window1")
canvas.click()
while (True):
action = ActionChains(browser)
action.move_to_element(canvas).perform()
canvas.click()
canvas.send_keys("q")
Тот же код отлично работает в Firefox, но поскольку я хочу использовать возможности Chrome для запуска игры webgl в безголовом режиме, я не могу переключиться на Firefox.
Есть какие-либо обходные пути, чтобы это заработало?
Переведено автоматически
Ответ 1
Исключение NoSuchElementException
selenium.common.exceptions.Исключение NoSuchElementException, широко известное как NoSuchElementException
, определяется как :
exception selenium.common.exceptions.NoSuchElementException(msg=None, screen=None, stacktrace=None)
NoSuchElementException
в основном выдается в 2 случаях следующим образом :
При использовании :
webdriver.find_element_by_*("expression")
//example : my_element = driver.find_element_by_xpath("xpath_expression")При использовании :
element.find_element_by_*("expression")
//example : my_element = element.find_element_by_*("expression")
Согласно документации API, как и любой другой, selenium.common.exceptions
, NoSuchElementException
должен содержать следующие параметры :
сообщение, экран, stacktrace
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":".//*[@id='create-portal-popup']/div[4]/div[1]/button[3]"}
(Session info: chrome=61.0.3163.100)
(Driver info: chromedriver=2.32.498550 (9dec58e66c31bcc53a9ce3c7226f0c1c5810906a),platform=Windows NT 10.0.10240 x86_64)
Причина
Причиной исключения NoSuchElementException может быть любое из следующих :
- Принятая вами стратегия поиска не идентифицирует ни один элемент в HTML DOM.
- Принятая вами стратегия поиска не позволяет идентифицировать элемент, поскольку его нет в области просмотра браузера.
- Принятая вами стратегия локатора идентифицирует элемент, но невидима из-за наличия атрибута style="display: none;".
- Принятая вами стратегия поиска не однозначно идентифицирует нужный элемент в HTML DOM и в настоящее время находит какой-либо другой скрытый / невидимый элемент.
- WebElement, который вы пытаетесь найти, находится внутри
<iframe>
тега. - Экземпляр WebDriver ищет WebElement еще до того, как элемент присутствует / виден в HTML DOM.
Решение
Решение для устранения NoSuchElementException может быть любым из следующих :
Используйте стратегию локатора, которая однозначно идентифицирует желаемый WebElement. Вы можете воспользоваться помощью Инструментов разработчика (Ctrl+Shift+I или F12) и использовать инспектор элементов.
Здесь вы найдете подробное обсуждение того, как проверять элемент в selenium3.6, поскольку firebug больше не является опцией для FF 56?
Используйте
execute_script()
метод для прокрутки элемента для просмотра следующим образом :elem = driver.find_element_by_xpath("element_xpath")
driver.execute_script("arguments[0].scrollIntoView();", elem)Здесь вы найдете подробное обсуждение прокрутки страницы в начало в Python с использованием Selenium
Если элемент имеет атрибут style="display: none;", удалите атрибут с помощью
executeScript()
метода следующим образом :elem = driver.find_element_by_xpath("element_xpath")
driver.execute_script("arguments[0].removeAttribute('style')", elem)
elem.send_keys("text_to_send")Чтобы проверить, находится ли элемент внутри,
<iframe>
перейдите вверх по HTML, чтобы найти соответствующий<iframe>
тег иswitchTo()
желаемый iframe любым из следующих методов :driver.switch_to.frame("iframe_name")
driver.switch_to.frame("iframe_id")
driver.switch_to.frame(1) // 1 represents frame indexЗдесь вы можете найти подробное обсуждение того, как я могу выбрать html-элемент независимо от того, в каком фрейме он находится в selenium?.
Если элемент не присутствует / виден в HTML DOM немедленно, вызовите WebDriverWait с expected_conditions, установленным в надлежащий метод следующим образом :
Для ожидания presence_of_element_located :
element = WebDriverWait(driver, 20).until(expected_conditions.presence_of_element_located((By.XPATH, "element_xpath']")))
Для ожидания visibility_of_element_located :
element = WebDriverWait(driver, 20).until(expected_conditions.visibility_of_element_located((By.CSS_SELECTOR, "element_css")
Для ожидания element_to_be_clickable :
element = WebDriverWait(driver, 20).until(expected_conditions.element_to_be_clickable((By.LINK_TEXT, "element_link_text")))
Этот вариант использования
Вы видите, NoSuchElementException
потому что локатор id не идентифицирует canvas однозначно. Чтобы идентифицировать холст и click()
на нем, вам нужно дождаться, пока холст будет clickable
, и для достижения этого вы можете использовать следующий блок кода :
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//canvas[@id='window1']"))).click()
Ссылка
Вы можете найти соответствующее обсуждение клиента Selenium на основе java в: