【问题标题】:Can't get element by id with delay using selenium webdriver使用 selenium webdriver 无法通过 id 延迟获取元素
【发布时间】:2017-05-30 11:26:06
【问题描述】:

我正在尝试使用 Python 使用 selenium 简单地通过 id 获取元素。

问题是测试主机不是那么快,所以网页加载可能会持续长达 10-15 秒。

所以,我从这段代码开始:

from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException

browser = webdriver.Chrome("C:/Users/user/Documents/chromedriver.exe")
browser.get("my_url")
delay = 20 # seconds
try:
    WebDriverWait(browser, delay).until(EC.presence_of_element_located(browser.find_element_by_id('X4')))
    print("Page is ready!")
except TimeoutException:
    print("Loading took too much time!")

但是,此代码根本无法处理这些异常:

Traceback (most recent call last):
  File "C:/Users/user/PycharmProjects/testproj/test_scripts/test.py", line 10, in <module>
    WebDriverWait(browser, delay).until(EC.presence_of_element_located(browser.find_element_by_id('X4')))
  File "C:\Program files (x86)\Python\Python36-32\lib\site-packages\selenium-3.4.2-py3.6.egg\selenium\webdriver\remote\webdriver.py", line 285, in find_element_by_id
    return self.find_element(by=By.ID, value=id_)
  File "C:\Program files (x86)\Python\Python36-32\lib\site-packages\selenium-3.4.2-py3.6.egg\selenium\webdriver\remote\webdriver.py", line 787, in find_element
    'value': value})['value']
  File "C:\Program files (x86)\Python\Python36-32\lib\site-packages\selenium-3.4.2-py3.6.egg\selenium\webdriver\remote\webdriver.py", line 252, in execute
    self.error_handler.check_response(response)
  File "C:\Program files (x86)\Python\Python36-32\lib\site-packages\selenium-3.4.2-py3.6.egg\selenium\webdriver\remote\errorhandler.py", line 194, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"id","selector":"X4"}

这只是说:“页面上没有这样的元素”。

奇怪的是,stacktrace 甚至在整个页面加载之前就被打印出来了,所以我不知道发生了什么。

我也尝试获取其他 ID,但没有运气 - 似乎问题与某些元素无关。

这是我要检索的元素周围的页面来源:

<div id="X4Edit" class="mandatoryFieldStyle xEdit file_Todo field_L_switch_inbox value_Todo" style="height:20px;">
    <div class="xEditInner" style="height:100%;">
        <input type="text" id="X4" value="Todo list" scripttype="combo" tabindex="" datachangeevent="817" 
               onkeydown="widgets.Combo.keyDown(event, 'X4');" 
               dvdvar="var/L.switch.inbox" buttonid="" reflabels="" onkeyup="widgets.Combo.keyUp(event, 'X4');" 
               alias="var/L.switch.inbox" name="var/L.switch.inbox" 
               autocomplete="off" role="combobox" aria-autocomplete="list" aria-owns="X4Popup_div" aria-activedescendant="X4Popup_div" 
               aria-haspopup="true" aria-expanded="false" maxlength="" style="
                height:18px;margin-top:1px;
                " selectonly="1" onfocus="widgets.Combo.handleOnFocus(this, event);" onblur="widgets.Combo.handleOnBlur(this, event);" 
               onclick="handleOnClick(this, event);" onchange="handleOnChange(this, event);">
    </div>
    <div id="X4ButtonDiv" class="xButton" tabindex="-1" style="">
        <a href="javascript:widgets.Combo.togglePopup('X4', true);void(0);" tabindex="-1" class="image-link" draggable="false" role="presention">
          <img id="X4Button" src="images/comboup.png" alt="" draggable="false" tabindex="-1">
        </a>
    </div>
</div>

那么,如何通过 id 正确检索此组合框?下面想尝试设置它的状态。

【问题讨论】:

  • 这可能是JS生成的元素。您在 JS 运行之前获取它。
  • 查看presence_of_element_located 的语法,因为我很确定这是错误的。您的论点 browser.find_element_by_id('X4') 正在立即搜索元素并返回一个元素,或者在您的情况下返回错误。

标签: python selenium css-selectors


【解决方案1】:

您错误地使用了 ExplicitWait:在这一行

WebDriverWait(browser, delay).until(EC.presence_of_element_located(browser.find_element_by_id('X4')))

解释器尝试执行browser.find_element_by_id('X4') 而无需等待。您应该将(By.ID, "some_id") 之类的可迭代对象传递给EC.presence_of_element_located() 而不是WebElement

尝试使用以下代码:

try:
    WebDriverWait(browser, delay).until(EC.presence_of_element_located(("id", "X4")))
    print("Page is ready!")
except TimeoutException:
    print("Loading took too much time!")

【讨论】:

  • 谢谢,不错的收获。你能帮忙解决一下select = Select(browser.find_element_by_id('X4')).select_by_value('My value').click() 给出同样错误的行吗?
  • 在这种情况下您不能使用Select(),因为它仅适用于select/option 节点,但不适用于input
  • 如果您想将值发送到输入字段,您可以尝试WebDriverWait(browser, delay).until(EC.element_to_be_clickable(("id", "X4"))).send_keys("My value")
  • 尽管页面已完全加载,但它会给出 selenium.common.exceptions.TimeoutException: Message: 异常
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-06-19
  • 2014-11-12
  • 2021-07-04
  • 2020-08-21
  • 1970-01-01
  • 2012-07-20
  • 1970-01-01
相关资源
最近更新 更多