Python中的Selenium预期条件适用于Firefox,但不适用于Chrome

Python中的Selenium预期条件适用于Firefox,但不适用于Chrome,python,google-chrome,selenium,firefox,Python,Google Chrome,Selenium,Firefox,我登录到一个私有站点,然后等待出现链接文本,然后使用browser.get()打开链接。下面的代码几乎每次都在等待链接文本“OTD”出现时抛出超时异常。奇怪的是,它在多次尝试中只起一次作用。更奇怪的是,若我使用睡眠计时器而不是等待预期条件,它会工作,但这不是我想要使用的 以下是html: 下面是使用chromedriver的代码: from selenium import webdriver from selenium.webdriver.common.by import By from se

我登录到一个私有站点,然后等待出现链接文本,然后使用browser.get()打开链接。下面的代码几乎每次都在等待链接文本“OTD”出现时抛出超时异常。奇怪的是,它在多次尝试中只起一次作用。更奇怪的是,若我使用睡眠计时器而不是等待预期条件,它会工作,但这不是我想要使用的

以下是html:

下面是使用chromedriver的代码:

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 webbrowser

chrome_options = webdriver.ChromeOptions()
prefs = {'download.default_directory' : 'E:\\folder'}
chrome_options.add_experimental_option('prefs', prefs)

browser = webdriver.Chrome(chrome_options=chrome_options)

#browser.get('private url login page')
#enter login information and submit

wait = WebDriverWait(browser, 10)

wait.until(
    EC.presence_of_element_located((By.LINK_TEXT, "OTD"))
)

browser.get('private url')
我有相同的代码,但是对于Firefox驱动程序,它每次都能完美工作。我只需要改用Chrome浏览器

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 webbrowser

profile = webdriver.FirefoxProfile()
profile.set_preference("browser.download.folderList", 2)
profile.set_preference("browser.download.dir", 'E:\\folder')
profile.set_preference("browser.download.useDownloadDir", True)

browser=webdriver.Firefox(profile)

#browser.get('private url login page')
#enter login information and submit

wait = WebDriverWait(browser, 10)

wait.until(
    EC.presence_of_element_located((By.LINK_TEXT, "OTD"))
)

browser.get('private url')

使用chromedriver使其抛出超时异常的代码中,我做错了什么?

有几件事需要解决:

  • 最后,当您在WebElement上调用
    click()
    时,您应该使用子句元素以使其可单击(定位器),而不是
    expected\u conditions
    子句作为
    presence\u of\u-element\u-located()

  • 当您使用
    expected\u conditions
    子句作为
    element\u to\u be\u clickable(locator)
    时,WebElement将返回,您可以直接调用它上的
    click()
    方法

  • 您的优化代码行将是:

    WebDriverWait(browser, 10).until(EC.element_to_be_clickable((By.LINK_TEXT, "OTD"))).click()
    

更新 根据您的评论更新,您看到了错误:

'element_to_be_clickable' object has no attribute 'click'
另一种方法是提取
href
属性并调用
get()
,如下所示:

element = WebDriverWait(browser, 10).until(EC.visibility_of_element_located((By.LINK_TEXT, "OTD")))
attr_href = element.get_attribute("href")
driver.get(attr_href)

更新B
根据您的评论,更新了硒元素与元素相互作用的想法。。。尽管无法实现元素的可见性,但它不是一个完整的证明解决方案,因为:

  • 预期条件条款提到:

    class selenium.webdriver.support.expected_conditions.presence_of_element_located(locator)
    
    An expectation for checking that an element is present on the DOM of a page. This does not necessarily mean that the element is visible. 
    
    locator - used to find the element returns the WebElement once it is located.
    
    class selenium.webdriver.support.expected_conditions.visibility_of_element_located(locator)
    
    An expectation for checking that an element is present on the DOM of a page and visible. Visibility means that the element is not only displayed but also has a height and width that is greater than 0. 
    
    locator - used to find the element returns the WebElement once it is located and visible.
    
  • 其中,
    预期条件
    条款提到:

    class selenium.webdriver.support.expected_conditions.presence_of_element_located(locator)
    
    An expectation for checking that an element is present on the DOM of a page. This does not necessarily mean that the element is visible. 
    
    locator - used to find the element returns the WebElement once it is located.
    
    class selenium.webdriver.support.expected_conditions.visibility_of_element_located(locator)
    
    An expectation for checking that an element is present on the DOM of a page and visible. Visibility means that the element is not only displayed but also has a height and width that is greater than 0. 
    
    locator - used to find the element returns the WebElement once it is located and visible.
    
  • 从Selenium的角度来看,如果元素未显示,Selenium将不会与元素交互,例如调用
    click()


为此感谢您。我使用的是browser.get而不是单击,因为单击链接会在新选项卡中打开链接,这不是我想要的。此外,这给了我一个错误“'element_to_be_clickable'对象没有属性'click'”使用位于的\u element_的可见性\u不适用于chrome或firefox,因为它会引发超时异常,但将其替换为位于firefox的\u element_的存在性\u只在第一次使用chrome时起作用。我用chrome又试了10次,但它一直抛出超时异常。我通过在页面中定位另一个元素找到了解决方案。我只是觉得奇怪,我的代码与firefox兼容,但与chrome不兼容。谢谢你的帮助!Selenium确实与Firefox中的元素交互,有时甚至与Chrome中的元素交互,尽管它无法获得元素的可见性。它在Firefox中使用元素的presence_而不是visibility_时工作。这就是为什么我认为我遇到的问题很奇怪。我会接受你的答案,因为正是这个答案促使我找到了一个有效的解决方案。非常感谢。现在这是有道理的。非常感谢。如果您正在运行当前版本的Chrome
65
,如果您至少没有运行chromedriver版本
2.36
,请更新chromedriver并再次执行测试。更新自。我已经看到了很多关于chrome新的稳定版本和chromedriver的旧版本的问题。这就是我正在使用的版本,但我通过您提供的链接再次下载了它,并执行了测试,但仍然存在相同的问题。我正在使用Chrome 65的当前版本。我编辑了这篇文章,说睡眠计时器取代了等待的预期条件,但这不是我想要使用的。