Я пытался войти в систему с помощью python-selenium, и вот мои коды:
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import WebDriverWait #as wait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as ec
from selenium.common.exceptions import TimeoutException
option = webdriver.ChromeOptions()
option.add_argument(“ — incognito”)
decanter = webdriver.Chrome(executable_path=chromedriver_path, chrome_options=option)
BASE_URL = 'www.decanter.com/wine-reviews/search#order[updated_at]=desc&page = {0}'
decanter.get("http://"+BASE_URL.format(1))
delay_sec = 1
decanter.find_element_by_css_selector("button.secondary").click()
Все работало до тех пор, пока здесь последняя строка кода не открыла всплывающее окно входа в систему, как показано на скриншоте здесь:

Следующие коды, с которыми я пытался войти в систему, встретились с ошибкой «TimeoutException: Message:».
USER = "userid"
PASSWORD = "passwd"
WebDriverWait(decanter, delay_sec).until(ec.visibility_of_element_located((By.XPATH, '/html/body/app-widget/screen-layout/main/current-screen/screen-login//p[1]/input'))).send_keys(USER)
decanter.find_element_by_css_selector('/html/body/app-widget/screen-layout/main/current-screen/screen-login/p[2]/input').send_keys(PASSWORD)
decanter.find_element_by_css_selector('button').click()
Я пробовал решение здесь, который выдавал ту же ошибку. Я уверен, что проблема не в количестве времени ожидания или пути.
Дальнейшие попытки и сообщения об ошибках:
>>> WebDriverWait(decanter, delay_sec).until(ec.element_to_be_clickable((By.XPATH, "//label[@class='inputlabel' and contains(.,'E-mail')]//following::p[1]/input[@type='text']"))).send_keys(USER)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/sheng/anaconda/lib/python2.7/site-packages/selenium/webdriver/support/wait.py", line 80, in until
raise TimeoutException(message, screen, stacktrace)
selenium.common.exceptions.TimeoutException: Message:






Ваши локаторы были немного не в порядке. Код ниже должен работать.
wait = WebDriverWait(decanter, delay_sec)
wait.until(EC.frame_to_be_available_and_switch_to_it(By.CSS_SELECTOR,"iframe[id^='piano-id-']"))
wait.until(ec.visibility_of_element_located((By.CSS_SELECTOR, 'input[fieldloginemail]'))).send_keys(USER)
decanter.find_element_by_css_selector('input[fieldloginpassword]').send_keys(PASSWORD)
decanter.find_element_by_css_selector('button[actionlogin]').click()
# once you are done with the content inside the iframe, switch context back to default
decanter.switch_to.default_content()
ПРИМЕЧАНИЕ. Не рекомендуется использовать XPath с несколькими уровнями, особенно с теми, которые начинаются с тега HTML. Они очень вероятно сломаются даже при небольших изменениях в DOM.
Я бы увеличил задержку до 5 или 10 секунд. Может сайт медленно загружается.
спасибо @JeffC, но я на самом деле установил его на 20 и видел, что загрузка завершалась каждый раз
Я вижу, что диалог находится внутри IFRAME. Добавлен код для переключения на него и возврата.
Поскольку вы пытаетесь отправить текст в поля ID пользователя и пароль, поэтому вместо предложения ожидаемые условия как visibility_of_element_located вам необходимо использовать предложение element_to_be_clickable следующим образом:
USER = "userid"
PASSWORD = "passwd"
WebDriverWait(decanter, delay_sec).until(ec.element_to_be_clickable((By.XPATH, "//label[@class='inputlabel' and contains(.,'E-mail')]//following::p[1]/input[@type='text']"))).send_keys(USER)
decanter.find_element_by_xpath("//p[@class='input-group']/input[@type='password']").send_keys(PASSWORD)
Примечание: не существует передовых методов использования CSS / XPath при обходе DOM. У CSS и XPath есть свои плюсы и минусы.
Как я уже упоминал в своих комментариях, согласно вашему обновленному снимку HTML, элемент находится внутри тега <iframe>. Следовательно, вы должны переключиться на предполагаемый фрейм следующим образом:
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it(By.ID,"piano-id-XSavU"))
USER = "userid"
PASSWORD = "passwd"
WebDriverWait(decanter, delay_sec).until(ec.element_to_be_clickable((By.XPATH, "//current-screen/screen-login//label[@class='inputlabel' and contains(.,'E-mail')]//following::p[1]/input[@type='text']"))).send_keys(USER)
decanter.find_element_by_xpath("//p[@class='input-group']/input[@type='password']").send_keys(PASSWORD)
Просмотрите HTML-код и перепроверьте, находится ли тег <main> внутри фрейма, тогда вам нужно сначала переключиться на предполагаемый фрейм. Обновите вопрос с помощью текстового форматированного HTML и трассировки стека ошибок для дальнейшего анализа.
Я попробовал, и это было все то же сообщение об ошибке ... может быть, потому что курсор уже был там в поле ввода, когда я смотрел на управляемый экран, и в каком случае мне все равно нужно переключаться на него?
спасибо, но все равно та же ошибка сразу после первой строки кода.
Спасибо JeffC за оперативный комментарий !! Я уверен, что ваш код имеет смысл ... но он по-прежнему возвращает ту же ошибку ... Что еще, по вашему мнению, могло бы сошло с ума в моих кодах ...?