Python 和 Selenium 以“execute_script”解决“ElementNotVisibleException”
Posted
技术标签:
【中文标题】Python 和 Selenium 以“execute_script”解决“ElementNotVisibleException”【英文标题】:Python and Selenium To “execute_script” to solve “ElementNotVisibleException” 【发布时间】:2015-10-02 13:11:04 【问题描述】:我正在使用 Selenium 来保存网页。单击某些复选框后,网页的内容将发生变化。我想要的是单击一个复选框,然后保存页面内容。 (复选框由 javascript 控制。)
首先我使用:
driver.find_element_by_name("keywords_here").click()
它以错误结束:
NoSuchElementException
然后我尝试了类似“xpath”的隐式/显式等待:
URL = “the url”
verificationErrors = []
accept_next_alert = True
aaa = driver.get(URL)
driver.maximize_window()
WebDriverWait(driver, 10)
#driver.find_element_by_xpath(".//*[contains(text(), ' keywords_here')]").click()
#Or:
driver.find_element_by_xpath("//label[contains(text(),' keywords_here')]/../input[@type='checkbox']").click()
它给出了一个错误:
ElementNotVisibleException
帖子
How to force Selenium WebDriver to click on element which is not currently visible?
Selenium Element not visible exception
建议它应该在单击之前使复选框可见,例如使用:
execute_script
这个问题可能听起来很愚蠢,但是如何从页面源代码中找到正确的句子来“execute_script”复选框的可见性?
除此之外,还有其他方法吗?
谢谢。
顺便说一下,这行html代码看起来像:
<input type="checkbox" onclick="ComponentArt_HandleCheck(this,'p3',11);" name="keywords_here">
它的 xpath 看起来像:
//*[@id="TreeView1_item_11"]/tbody/tr/td[3]/input
【问题讨论】:
【参考方案1】:另一种选择是将click()
放入execute_script()
:
# wait for element to become present
wait = WebDriverWait(driver, 10)
checkbox = wait.until(EC.presence_of_element_located((By.NAME, "keywords_here")))
driver.execute_script("arguments[0].click();", checkbox)
EC
导入为:
from selenium.webdriver.support import expected_conditions as EC
或者,作为在黑暗中的另一个镜头,您可以使用element_to_be_clickable
预期条件并以通常的方式执行点击:
wait = WebDriverWait(driver, 10)
checkbox = wait.until(EC.element_to_be_clickable((By.NAME, "keywords_here")))
checkbox.click()
【讨论】:
alecxe 先生,感谢您的帮助。你是专家。我读过你们的一些帖子。我尝试了这些行,但它们都给出了“raise TimeoutException(message)”“selenium.common.exceptions.TimeoutException: Message: ''. @MarkK 谢谢。但是,同时driver.find_element_by_xpath("//label[contains(text(),' keywords_here')]/../input[@type='checkbox']")
不会产生错误?您是否检查过您在 find_element_by_xpath
中使用的 xpath 是否与我发布的“预期条件”中使用的相同?谢谢。
(对不起,有一个错误 - 我将您发布的内容替换为我拥有的内容,但实际上我认为您的行将添加到原始行之后。)我将您的行添加到原件和其中的 xpath是相同的。 driver.find_element_by_xpath("//label[contains(text(),'keywords_here')]/../input[@type='checkbox']") 本身给出“NoSuchElementException”。
@MarkK 好的,谢谢。那么这意味着我们有一个不同的问题。我们没有正确定位元素。我已经更新了答案并使用了By.NAME
定位技术。检查我们是否仍然收到NoSuchElementException
。谢谢。
@MarkK 哦,是的,这改变了游戏规则。在查找该复选框元素之前,您需要切换到 iframe。例如:driver.switch_to.frame("frame_id_or_name")
.【参考方案2】:
我对预期条件有一些问题,我更喜欢建立自己的超时时间。
import time
from selenium import webdriver
from selenium.common.exceptions import \
NoSuchElementException, \
WebDriverException
from selenium.webdriver.common.by import By
b = webdriver.Firefox()
url = 'the url'
b.get(url)
locator_type = By.XPATH
locator = "//label[contains(text(),' keywords_here')]/../input[@type='checkbox']"
timeout = 10
success = False
wait_until = time.time() + timeout
while wait_until < time.time():
try:
element = b.find_element(locator_type, locator)
assert element.is_displayed()
assert element.is_enabled()
element.click() # or if you really want to use an execute script for it, you can do that here.
success = True
break
except (NoSuchElementException, AssertionError, WebDriverException):
pass
if not success:
error_message = 'Failed to click the thing!'
print(error_message)
可能要添加 InvalidElementStateException 和 StaleElementReferenceException
【讨论】:
以上是关于Python 和 Selenium 以“execute_script”解决“ElementNotVisibleException”的主要内容,如果未能解决你的问题,请参考以下文章
如何识别 ReCaptcha V2 的 32 位数据站点密钥以使用 Selenium 和 Python 请求以编程方式获取有效响应?
如何使用 Python 和 Selenium 发送 ESC 键以关闭弹出窗口?
selenium.common.exceptions.ElementNotVisibleException:消息:元素不可交互,显式等待不能使用Selenium和Python