
在进行网页自动化测试或数据抓取时,经常会遇到一些阻碍脚本正常执行的元素。本教程将以一个具体的场景为例:尝试通过Selenium自动化点击一个SVG图标来打开日期选择器,然后输入日期并点击“Apply”按钮。在此过程中,我们可能会遇到两种常见的挑战:
在许多网站首次加载时,为了遵守隐私法规,会弹出Cookie同意对话框。如果Selenium脚本没有处理这个弹窗,它可能会覆盖页面上的其他元素,导致后续元素无法被点击或交互。解决这个问题的方法是,在执行任何其他操作之前,先等待并点击接受Cookie的按钮。
通常,接受Cookie的按钮会有特定的ID或文本,例如id='onetrust-accept-btn-handler'。我们可以使用显式等待来确保该元素可见且可点击,然后执行点击操作。
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
from selenium.common.exceptions import TimeoutException
# Setup the WebDriver (以Firefox为例)
driver = webdriver.Firefox()
try:
# Open the page
driver.get("https://www.investing.com/equities/tencent-holdings-hk-historical-data")
# 步骤1: 等待并点击Cookie同意按钮
# 检查Cookie弹窗是否存在并处理,避免阻碍后续操作
try:
cookie_accept_button = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.XPATH, "//*[@id='onetrust-accept-btn-handler']"))
)
cookie_accept_button.click()
print("成功点击Cookie同意按钮。")
except TimeoutException:
print("未检测到Cookie同意弹窗或已处理。")
pass # 如果没有弹窗,则继续执行
# ... 后续操作
finally:
# 确保浏览器最终被关闭
pass # 暂时不关闭,以便后续完整代码示例中统一关闭SVG元素由于其特殊的命名空间(xmlns="http://www.w3.org/2000/svg"),在使用XPath定位时需要特别注意。传统的XPath路径可能无法识别这些元素,导致TimeoutException。为了正确地定位SVG元素及其子元素,我们需要使用XPath函数local-name()来忽略命名空间,直接匹配元素的本地名称。
例如,如果一个SVG元素及其子g和path元素是目标,正确的XPath应该如下所示:
//*[@id='__next']/div[2]/div[2]/div[2]/div[1]/div[2]/div[2]/div[2]/div[2]/span/*[local-name()='svg']/*[local-name()='g']/*[local-name()='path']
这个XPath路径通过*[local-name()='svg']等方式,确保无论SVG元素在哪个命名空间下,都能通过其标签名进行匹配。
# ... (承接上述代码,在处理完Cookie弹窗之后)
# 步骤2: 等待SVG元素并点击它
# 注意:SVG元素需要使用local-name()来正确匹配
svg_element = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.XPATH, "//*[@id='__next']/div[2]/div[2]/div[2]/div[1]/div[2]/div[2]/div[2]/div[2]/span/*[local-name()='svg']"))
)
# 实际点击时,可能需要点击SVG本身或其父元素来触发日期选择器
# 如果直接点击path不工作,尝试点击svg或其父span
svg_element.click()
print("成功点击SVG元素。")注意事项: 有时,即使SVG路径是正确的,直接点击path元素也可能无效。在这种情况下,尝试点击SVG元素本身(*[local-name()='svg'])或者其包含SVG的父元素(例如span)来触发所需的操作。根据页面结构和事件监听器的不同,合适的点击目标也会有所不同。
在SVG元素被点击后,通常会弹出一个日期选择器或激活一个日期输入框。接下来,我们需要找到这个日期输入框,清空其现有值(如果存在),然后输入新的日期。最后,找到并点击“Apply”或“确认”按钮来提交更改。
# ... (承接上述代码,在点击SVG元素之后)
# 步骤3: 找到日期输入框,清空并设置新值
date_input = WebDriverWait(driver, 10).until(
EC.visibility_of_element_located((By.CSS_SELECTOR, "input[type='date']"))
)
date_input.clear() # 清空当前值
date_input.send_keys("2020-01-01") # 输入目标日期
print("成功输入日期。")
# 步骤4: 找到并点击"Apply"按钮
apply_button = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.XPATH, "//button[text()='Apply']"))
)
apply_button.click()
print("成功点击Apply按钮。")
# 步骤5: 打印页面源代码(可选,用于验证结果)
page_source = driver.page_source.encode('utf-8').decode('utf-8')
print("\n--- 页面源代码 ---")
# print(page_source) # 打印完整页面源代码可能会很长
print("页面源代码获取成功,此处省略完整输出。")
将上述所有步骤整合到一起,形成一个完整的、可执行的Selenium自动化脚本:
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
from selenium.common.exceptions import TimeoutException, NoSuchElementException
# Setup the WebDriver
driver = webdriver.Firefox()
try:
# Open the page
driver.get("https://www.investing.com/equities/tencent-holdings-hk-historical-data")
print("页面加载成功。")
# 1. 处理Cookie同意弹窗
try:
cookie_accept_button = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.XPATH, "//*[@id='onetrust-accept-btn-handler']"))
)
cookie_accept_button.click()
print("成功点击Cookie同意按钮。")
except TimeoutException:
print("未检测到Cookie同意弹窗或已处理,继续执行。")
except NoSuchElementException:
print("Cookie同意按钮元素未找到,可能页面结构已变化。")
pass # 如果元素不存在,则忽略
# 2. 等待SVG元素并点击它
# 使用local-name()处理SVG命名空间,并尝试点击SVG本身或其父元素
# 目标:点击日期范围选择器,通常是一个包含SVG的span或div
try:
# 假设日期选择器的触发元素是包含SVG的span
date_range_trigger = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.XPATH, "//*[@id='__next']/div[2]/div[2]/div[2]/div[1]/div[2]/div[2]/div[2]/div[2]/span"))
)
date_range_trigger.click()
print("成功点击日期范围触发元素。")
except TimeoutException:
print("日期范围触发元素未找到或不可点击。")
raise # 重新抛出异常,停止执行
# 3. 找到日期输入框,清空并设置新值
try:
date_input = WebDriverWait(driver, 10).until(
EC.visibility_of_element_located((By.CSS_SELECTOR, "input[type='date']"))
)
date_input.clear()
date_input.send_keys("2020-01-01")
print("成功输入日期:2020-01-01。")
except TimeoutException:
print("日期输入框未找到或不可见。")
raise
# 4. 找到并点击"Apply"按钮
try:
apply_button = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.XPATH, "//button[text()='Apply']"))
)
apply_button.click()
print("成功点击Apply按钮。")
except TimeoutException:
print("Apply按钮未找到或不可点击。")
raise
# 5. 打印页面源代码(可选)
page_source = driver.page_source.encode('utf-8').decode('utf-8')
# print(page_source)
print("\n页面源代码获取成功,用于验证更改。")
except Exception as e:
print(f"发生错误: {e}")
finally:
# Remember to close the driver
driver.quit()
print("浏览器已关闭。")
通过遵循这些最佳实践,并理解SVG元素在Selenium自动化中的特殊处理方式,您可以构建出更加健壮和高效的网页自动化脚本。
以上就是Selenium自动化实践:解决SVG点击与日期输入中的常见陷阱的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号