当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>
当我的脚本单击验证码复选框时,也会发生同样的行为(删除 disable
和 login-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()
我正在尝试使用 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>
当我的脚本单击验证码复选框时,也会发生同样的行为(删除 disable
和 login-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()