Как отправить ключи в форму без идентификатора или имени в селене (Python)

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

Теперь у меня есть проблема: я хочу отправить ключи в поле ввода, поэтому, поскольку поле ввода не имеет имени или идентификатора, я нашел поле ввода с помощью xpath:

xxx = driver.find_element_by_xpath("//input[@placeholder='081xxxxxxxx']")

Я распечатал это, и он вернул некоторые объекты селена, но когда я пытаюсь отправить такие ключи, как:

xxx.send_keys('08100000000')

Вот фрагмент HTML-кода:

<div class = "row">
<div class = "medium-12 columns">
    <div class = "guest-text">
        One step closer! <br />
        <span>Please provide your contact number to view business contact details</span>
    </div>

    <form action = "" data-abide = "ajax" novalidate = "novalidate">
        <div id = "txtUserPhoneNumber" ng-show = "!isLoggedIn && collectUserPhone == ''" class = "guest-no">
            <label>
                <div class = "guest-label">Phone Number</div>
                <input type = "text" placeholder = "081xxxxxxxx" ng-model = "UserPhoneNew" required data-invalid = "" aria-invalid = "true" maxlength = "11">

            </label>
        </div>
    </form>
</div>

Я пытался:

xxx = driver.find_element_by_xpath("//input[@placeholder='081xxxxxxxx']")
xxx.send_keys('08100000000')

dummy_number = driver.find_element_by_xpath("//div[contains(@class, 'modal small guest')]/div[contains(@class, 'guest-modal-wrapper')]//form[1]//input[1]")
dummy_number.send_keys('081000000')

Я получил сообщение об ошибке:

Traceback (most recent call last):
File "Dropbox/automation/vconnect.py", line 76, in <module>
    RunAutomation.instantiatechrome()
  File "Dropbox/automation/vconnect.py", line 61, in instantiatechrome
    xxx.send_keys('081xxxxxxxx')
  File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/remote/webelement.py", line 479, in send_keys
    'value': keys_to_typing(value)})
  File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/remote/webelement.py", line 628, in _execute
    return self._parent.execute(command, params)
  File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/remote/webdriver.py", line 312, in execute
    self.error_handler.check_response(response)
  File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/remote/errorhandler.py", line 237, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.ElementNotVisibleException: Message: element not visible
  (Session info: chrome=66.0.3359.139)
  (Driver info: chromedriver=2.35.528139 (47ead77cb35ad2a9a83248b292151462a66cd881),platform=Linux 4.13.0-39-generic x86_64)

Ваше мнение приветствуется.

Поделитесь соответствующим HTML и вашими пробными версиями кода

DebanjanB 02.05.2018 15:34

Я отредактировал вопрос и добавил HTML-код

molecules 02.05.2018 15:49

Вы уверены, что значение placeholder стабильно? Немного похоже на сгенерированное значение. И каков точный тип ошибки и сообщение?

Würgspaß 02.05.2018 15:56

заполнитель не меняется, и я добавил точный тип ошибки @ Würgspaß

molecules 02.05.2018 16:10
Почему в 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
4
1 465
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

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

В итоге ваш код может выглядеть так (ожидание до 120 секунд):

from selenium.webdriver.support import expected_conditions as EC

...

wait = WebDriverWait(driver, 120)
element = wait.until(EC.visibility_of_element_located((By.XPATH, "//input[@placeholder='081xxxxxxxx']")))
element.send_keys('08100000000')

Это действительно помогло ... Спасибо

molecules 04.05.2018 09:15

@molecules Приятно слышать. Чтобы пометить полезные ответы в Stackoverflow, нужно проголосовать за и / или принять ответ, используя стрелку слева.

Würgspaß 04.05.2018 10:30

Что касается ошибки, вам нужно подождать, пока элемент отобразится и будет включен для взаимодействия с ним. Вы можете узнать об этом, прочитав "Неявность и очевидность ожиданий в Selenium".

Здесь вы можете найти дополнительную информацию о том, что: https://stackoverflow.com/a/27600986/5120498

Также дополнительный совет.

Обычно мы используем XPath только тогда, когда элемент очень сложно или даже невозможно найти с помощью идентификатора или CssSelector. Это потому, что XPath не является распространенным в качестве CssSelector, и его сложнее понять в зависимости от того, как он написан.

Когда нам нужно найти какой-либо элемент с помощью XPath или CssSelector, в первую очередь нам нужно проверить, какие значения не изменятся после взаимодействия со страницей, а также что дает нам уникальное значение (когда нам нужен только один элемент, ofc).

Поскольку ваш html имеет только один элемент с идентификатором txtUserPhoneNumber, и желаемый элемент находится внутри него, давайте начнем его выбирать. После, посмотрите имя тега желаемого элемента. Внутри всего один элемент input? Хороший! Таким образом, мы можем достичь элемента, используя только эту небольшую информацию.

CssSelector:

#txtUserPhoneNumber input

А также

Xpath:

//*[@id='txtUserPhoneNumber ']//input

Это действительно полезно ... Спасибо

molecules 04.05.2018 09:15

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

selenium.common.exceptions.ElementNotVisibleException: Message: element not visible

... означает, что адаптированный вами Стратегия поиска не идентифицирует уникальный WebElement на веб-странице.

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

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

Supports Chrome v62-64

  • Вы используете хром = 66.0
  • Примечания к выпуску ChromeDriver v2.38 четко упоминают следующее:

Supports Chrome v65-67

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

Решение

  • Обновить Селен до текущего уровня Версия 3.11.0.
  • Обновите ChromeDriver до текущего уровня ChromeDriver v2.38.
  • Держите версию Хром на уровнях Chrome v66.x. (согласно примечаниям к выпуску ChromeDriver v2.38)
  • Чистый ваш Рабочая область проекта через ваш IDE и Восстановить ваш проект только с необходимыми зависимостями.
  • Используйте инструмент CCleaner, чтобы стереть все рутинные операции ОС до и после выполнения вашего тестирование.
  • Если ваша базовая версия Веб-клиент слишком старая, удалите ее с помощью Revo Деинсталлятор и установите последнюю версию GA и выпущенную версию Веб-клиент.
  • Возьмите Перезагрузка системы.
  • Поскольку вы видите ElementNotVisibleException, вам нужно вызвать WebDriverWait, чтобы WebElement был доступен для кликов следующим образом:

    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support import expected_conditions as EC
    # other code
    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//form[@data-abide='ajax']//input[@ng-model='UserPhoneNew']"))).send_keys("08100000000")
    
  • Запустите свой @Test.

Примечание: Здесь вы найдете подробное обсуждение ElementNotVisibleException: Selenium Python

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