не могу ввести учетные данные, используя селен - PullRequest
2 голосов
/ 22 мая 2019

Я пытаюсь зайти на сайт, используя selenium, выполнив:

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()
driver.get("https://www.eco-visio.net/v5/")
username = driver.find_element_by_id("login-username")
username.send_keys("midregcog.admin")

но я получаю следующую ошибку

ElementNotInteractableException           Traceback (most recent call last)
<ipython-input-9-975030640535> in <module>()
      8 driver.get("https://www.eco-visio.net/v5/")
      9 username = driver.find_element_by_id("login-username")
---> 10 username.send_keys("midregcog.admin")
     11 

C:\Anaconda2\lib\site-packages\selenium\webdriver\remote\webelement.pyc in send_keys(self, *value)
    477         self._execute(Command.SEND_KEYS_TO_ELEMENT,
    478                       {'text': "".join(keys_to_typing(value)),
--> 479                        'value': keys_to_typing(value)})
    480 
    481     # RenderedWebElement Items

C:\Anaconda2\lib\site-packages\selenium\webdriver\remote\webelement.pyc in _execute(self, command, params)
    631             params = {}
    632         params['id'] = self._id
--> 633         return self._parent.execute(command, params)
    634 
    635     def find_element(self, by=By.ID, value=None):

C:\Anaconda2\lib\site-packages\selenium\webdriver\remote\webdriver.pyc in execute(self, driver_command, params)
    319         response = self.command_executor.execute(driver_command, params)
    320         if response:
--> 321             self.error_handler.check_response(response)
    322             response['value'] = self._unwrap_value(
    323                 response.get('value', None))

C:\Anaconda2\lib\site-packages\selenium\webdriver\remote\errorhandler.pyc in check_response(self, response)
    240                 alert_text = value['alert'].get('text')
    241             raise exception_class(message, screen, stacktrace, alert_text)
--> 242         raise exception_class(message, screen, stacktrace)
    243 
    244     def _value_or_default(self, obj, key, default):

ElementNotInteractableException: Message: element not interactable
  (Session info: chrome=74.0.3729.131)
  (Driver info: chromedriver=74.0.3729.6 (255758eccf3d244491b8a1317aa76e1ce10d57e9-refs/branch-heads/3729@{#29}),platform=Windows NT 10.0.17134 x86_64)

Вот тег id сайта, который я пытаюсь получить. enter image description here

Ответы [ 2 ]

2 голосов
/ 22 мая 2019

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

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
from selenium.webdriver.common import action_chains
import time

driver = webdriver.Chrome()
driver.get("https://www.eco-visio.net/v5/")
username_element = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH, "//form/div/input[@id='login-username']")))# driver.find_element_by_id("login-username")

driver.execute_script("arguments[0].click();", username_element)
time.sleep(1) # give the click a moment to register
action = action_chains.ActionChains(driver)
action.send_keys("midregcog.admin")
action.perform()

Это работает, чтобы заполнить поле на моей машине! Надеюсь, это поможет.

обновление

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

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
import time

driver = webdriver.Chrome()
driver.get("https://www.eco-visio.net/v5/")
username_element = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH, "//form/div/input[@id='login-username']")))# driver.find_element_by_id("login-username")
time.sleep(2) # give a longer wait than the explicit wait in the previous line
username_element.click()
username_element.send_keys("username")
password_element = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH, "//form/div/input[@id='login-password'][@type='password']")))# driver.find_element_by_id("login-username")
password_element.click()
password_element.send_keys("password")

Я думаю, это может быть потому, что в javascript, который генерирует страницу (а я не эксперт по javascript), есть такие строки, как if: loaded(), что заставляет меня поверить, что явный WebDriverWait получает элемент, но javascript все еще находится в процессе его загрузки. Таким образом, WebDriverWait проверяет, что элемент существует, а time.sleep(2) проверяет, что он также загружен, прежде чем пытаться взаимодействовать с ним, и в этот момент кажется, что вы можете взаимодействовать с ним как обычная страница без проблем. Я даже узнал кое-что новое для этого поста XD!

1 голос
/ 22 мая 2019

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

Попробуйте что-то вроде этого.

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

driver = webdriver.Chrome()
driver.get("https://www.eco-visio.net/v5/")
wait = WebDriverWait(driver, 10)
ec = EC.visibility_of_element_located((By.ID, "login-username"))
try:
    username = wait.until(ec, f"Could not find {ec.locator}")
    username.send_keys("midregcog.admin")
except Exception as exc:
    raise
finally:
    driver.quit()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...