当Selenium找不到元素时,有没有办法刷新HTML dom?

Is there a way to refresh HTML dom when Selenium cannot locate an element?

我正在尝试使用 Selenium 和 Chromedriver 提交登录表单。该表单包含一个用户名字段、一个密码字段、一个复选框和一个登录按钮。我可以输入用户名,输入密码,然后选中复选框。但是我还没弄清楚如何点击登录按钮。

当用户单击表单时,选中复选框后,登录按钮 HTML 的内容从...

<button tabindex="4" step="1" type="submit" 
class="btn-primary login disable login-disabled" 
id="login-submit" disabled="">Log In</button>

...至:

<button tabindex="4" step="1" type="submit" 
class="btn-primary login" 
id="login-submit">Log In</button>

当我的脚本单击验证码复选框时,也会发生同样的行为(删除 disablelogin-disabled 类)。

这是有问题的代码,我试图处理所有可能的定位器处理程序,但仍然无法找到按钮元素:

def try_click_with_all_locator_strategies(id=None, xpath=None, link_text=None, partial_link_text=None, name=None, tag_name=None, class_name=None, css_selector=None):
    by_fields = []
    by_fields.append((By.ID, id)) if id else None
    by_fields.append((By.XPATH, xpath)) if xpath else None
    by_fields.append((By.LINK_TEXT, link_text)) if link_text else None
    by_fields.append((By.PARTIAL_LINK_TEXT, partial_link_text)) if partial_link_text else None
    by_fields.append((By.NAME, name)) if name else None
    by_fields.append((By.TAG_NAME, tag_name)) if tag_name else None
    by_fields.append((By.CLASS_NAME, class_name)) if class_name else None
    by_fields.append((By.CSS_SELECTOR, css_selector)) if css_selector else None

    found = False
    for (by_key, by_value) in by_fields:
        try:
            time.sleep(0.5)
            driver.implicitly_wait(10)
            element = driver.find_element(by=by_key, value=by_value)
            element.click()
            found = True
        except NoSuchElementException:
            print('unable to find via', by_value)
    if not found:
        print('Unable to find using any locator strategy')

try_click_with_all_locator_strategies(
    id="#login-submit", 
    xpath="/html/body/div[5]/div[1]/div/div[1]/div/form/button", 
    link_text='Log In', 
    class_name="btn-primary", 
    css_selector="#login-submit"
    )

如有任何帮助或想法,我们将不胜感激!

啊哈!原来答案与框架有关。为了排除故障,我最终打印出页面上的所有 ID(引用 Python & Selenium - how do I find all element IDs on a page?),最终只打印了它应该具有的一些 ID。原来,当我点击复选框时,它已经修改了当前帧。

为了解决这个问题,我只需要切换到主框架,然后继续。

driver.switch_to.parent_frame()