我尝试使用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()
我尝试了the solution here,它抛出了同样的错误。等待时间或路径也不是问题,我是积极的。
进一步的尝试和错误消息是:
>>> 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:
这是整个iframe的html: [![在此处输入图像说明] [3]] [3]
答案 0 :(得分:0)
您的定位器有点偏差。下面的代码应该有效。
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进行微小的更改,它们也很可能会中断。
答案 1 :(得分:0)
当您尝试将文本发送到 userid 和 passwd 字段时,您需要将{em> expectedconditions 子句替换为visibility_of_element_located
而不是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)
使用条款element_to_be_clickable
如下:
<iframe>
注意:在遍历DOM时是否使用CSS / XPath没有最佳实践。 CSS和XPath都有各自的优点和缺点。
正如我在评论中提到的,根据您更新的HTML快照,该元素位于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)
标记内。因此,您必须按如下方式切换到预期的框架:
access_token