Сообщение: ссылка на устаревший элемент: элемент не прикреплен к документу страницы

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

Смотрите мой код ниже.

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

usernameStr = 'USERNAME'
passwordStr = 'PASSWORD'

browser = webdriver.Chrome()
browser.get('https://www.partner.co.il/he-il/login/login/?TYPE=100663297&REALMOID=06-f94d9340-8677-4c32-9f36-efd036fe99f0&GUID=&SMAUTHREASON=0&METHOD=GET&SMAGENTNAME=vmwebcms9&TARGET=-SM-HTTPS%3a%2f%2fwww%2epartner%2eco%2eil%2fcopa%2fpages%2fprotected%2fprotectedredirect%2easpx%3foriginal%3dhttps%3a%2f%2fwww%2epartner%2eco%2eil%2faccount_actions')

# fill in username 

username = browser.find_element_by_xpath('//*[@id="USER"]')
username.send_keys(usernameStr)

# fil the password

password = browser.find_element_by_xpath('//*[@id="PASSWORD"]')
password.click()
password.send_keys(passwordStr)


# press the login button

signInButton = browser.find_element_by_id('LoginBtn')
signInButton.click()

# go to the abroad page

browser.get(('https://biz.partner.co.il/he-il/biz/international/going-abroad'))

Но это возвращает

=========== RESTART: C:\Program Files (x86)\Python36-32\login2.py ===========
Traceback (most recent call last):
  File "C:\Program Files (x86)\Python36-32\login2.py", line 22, in <module>
    password.send_keys(passwordStr)
  File "C:\Program Files (x86)\Python36-32\lib\site-packages\selenium\webdriver\remote\webelement.py", line 479, in send_keys
    'value': keys_to_typing(value)})
  File "C:\Program Files (x86)\Python36-32\lib\site-packages\selenium\webdriver\remote\webelement.py", line 628, in _execute
    return self._parent.execute(command, params)
  File "C:\Program Files (x86)\Python36-32\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 312, in execute
    self.error_handler.check_response(response)
  File "C:\Program Files (x86)\Python36-32\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 237, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.StaleElementReferenceException: Message: stale element reference: element is not attached to the page document
  (Session info: chrome=66.0.3359.139)
  (Driver info: chromedriver=2.35.528161 (5b82f2d2aae0ca24b877009200ced9065a772e73),platform=Windows NT 10.0.14393 x86_64)

3 ответа

Это сообщение об ошибке...

selenium.common.exceptions.StaleElementReferenceException: Message: stale element reference: element is not attached to the page document
  (Session info: chrome=66.0.3359.139)
  (Driver info: chromedriver=2.35.528161 (5b82f2d2aae0ca24b877009200ced9065a772e73),platform=Windows NT 10.0.14393 x86_64)

... подразумевает, что во время вызова send_keys() для поля пароля элемент оказался устаревшим.

Есть несколько фактов, которые необходимо рассмотреть следующим образом:


Поле пароля

password поле содержит onfocus атрибут содержит функцию managePasswordTxt(), Так что, как только вы нажмете на password выставить managePasswordTxt() JavaScript вызывается, и вы должны заставить WebDriverWait сделать поле активным, и вы можете использовать следующее решение:

  • Блок кода:

    from selenium import webdriver
    from selenium.webdriver.chrome.options import Options
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support import expected_conditions as EC
    
    options = Options()
    options.add_argument("start-maximized")
    options.add_argument("disable-infobars")
    options.add_argument("--disable-extensions")
    driver = webdriver.Chrome(chrome_options=options, executable_path=r'C:\WebDrivers\ChromeDriver\chromedriver_win32\chromedriver.exe')
    driver.get('https://www.partner.co.il/he-il/login/login/?TYPE=100663297&REALMOID=06-f94d9340-8677-4c32-9f36-efd036fe99f0&GUID=&SMAUTHREASON=0&METHOD=GET&SMAGENTNAME=vmwebcms9&TARGET=-SM-HTTPS%3a%2f%2fwww%2epartner%2eco%2eil%2fcopa%2fpages%2fprotected%2fprotectedredirect%2easpx%3foriginal%3dhttps%3a%2f%2fwww%2epartner%2eco%2eil%2faccount_actions')
    username = driver.find_element_by_xpath("//input[@id='USER']").send_keys("Alex")
    driver.find_element_by_xpath("//input[@id='PASSWORD']").click()
    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//input[@id='PASSWORD']"))).send_keys("Pruteanu")
    
  • Снимок клиента браузера:

partner_co_li_login


Совместимость версий

Дополнительной проблемой является совместимость версий между используемыми вами двоичными файлами:

  • Вы используете chromedriver=2,35
  • В примечаниях к выпуску chromedriver=2.35 четко упоминается следующее:

Поддерживает Chrome v62-64

Поддерживает Chrome v65-67

  • Ваша версия Selenium Client нам неизвестна.

Таким образом, существует явное несоответствие между ChromeDriver v2.35 и Chrome Browser версии v66.0

Решение

  • Обновление Selenium до текущих уровней Версия 3.11.0.
  • Обновите ChromeDriver до текущего уровня ChromeDriver v2.38.
  • Держите версию Chrome на уровне Chrome v66.x. ( согласно примечаниям к выпуску ChromeDriver v2.38)
  • Очистите рабочее пространство проекта через IDE и перестройте проект только с необходимыми зависимостями.
  • Используйте инструмент CCleaner, чтобы стереть с себя все обязанности ОС до и после выполнения тестового пакета.
  • Если ваша базовая версия веб-клиента слишком старая, удалите ее с помощью Revo Uninstaller и установите последнюю версию GA и выпущенную версию веб-клиента.
  • Возьмите перезагрузку системы.
  • Выполните свой @Test,

Переход на FireFox Driviver решил проблему с использованием того же кода, который я разместил здесь

Ваши локаторы в порядке. Однако, когда вы нажимаете или изменяете фокус на элемент пароля, появляется StaleElementReference Исключение.

Добавить это утверждение импорта

from selenium.common.exceptions import StaleElementReferenceException

И добавьте это в свой код

try:
    ActionChains(browser).send_keys(Keys.TAB).send_keys(passwordStr).perform()
    password.send_keys(passwordStr)
except StaleElementReferenceException:
    pass

При правильном имени пользователя и пароле код будет входить нормально.

Измените свой код, чтобы заполнить пароль следующим образом

# fil the password

password = browser.find_element_by_xpath('//*[@id="PASSWORD"]')
password.click()
password = browser.find_element_by_xpath('//*[@id="PASSWORD"]')
password.send_keys(passwordStr)

Исключение StaleElement выдается, когда вы пытаетесь выполнить операцию с webElement, который больше не доступен на странице, вероятно, потому что страница была обновлена, и, следовательно, ваш код удерживается на объекте, который более недействителен. Вам нужно снова выполнить поиск после выполнения щелчка на поле пароля и затем попытаться отправить по нему. Возможно, что xpath изменился бы после нажатия, обновите ваш xpath после щелчка, если это сценарий.