You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Python Selenium从ATP官网SVG获取网球落点圆的cx/cy坐标

解决ATP官网SVG落点元素定位问题

问题原因分析

你遇到的定位失败,主要是这几个因素导致:

  • 页面元素动态加载,代码执行时目标元素还未渲染完成
  • SVG元素需要特殊的CSS选择器语法定位
  • 无头模式默认窗口尺寸过小,引发布局异常、元素未加载
  • 未先切换目标球员、发球类型和区域的选项,导致目标SVG元素未被激活

解决方案步骤

1. 优化无头模式配置

默认无头窗口尺寸不足,会导致页面布局错乱,添加窗口大小参数修正:

chrome_options.add_argument("--window-size=1920,1080")

2. 用显式等待替代硬等待

避免使用time.sleep(),改用WebDriverWait等待元素加载完成,确保操作时机正确:

from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

3. 正确定位SVG内的circle元素

SVG属于特殊命名空间,定位时需明确上下文,用CSS选择器直接命中目标:

# 等待并获取所有落点circle元素
ball_plots = WebDriverWait(driver, 10).until(
    EC.presence_of_all_elements_located((By.CSS_SELECTOR, "#ball-plots circle"))
)

4. 实现选项切换(球员、发球类型、区域)

必须先切换到目标视图,才能获取对应落点数据,示例切换到J.Sinner的一发Deuce区:

# 切换球员为J.Sinner
WebDriverWait(driver, 10).until(
    EC.element_to_be_clickable((By.XPATH, "//button[contains(text(), 'Jannik Sinner')]"))
).click()

# 切换发球类型为一发
WebDriverWait(driver, 10).until(
    EC.element_to_be_clickable((By.XPATH, "//button[contains(text(), '1st Serve')]"))
).click()

# 切换区域为Deuce区
WebDriverWait(driver, 10).until(
    EC.element_to_be_clickable((By.XPATH, "//button[contains(text(), 'Deuce')]"))
).click()

完整修正代码

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

chrome_options = webdriver.ChromeOptions()
chrome_options.add_experimental_option("excludeSwitches", ['enable-automation'])
chrome_options.add_argument("headless")
chrome_options.add_argument("--window-size=1920,1080")  # 关键:设置窗口尺寸
chrome_options.add_argument("user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36")  # 模拟真实浏览器

driver = webdriver.Chrome(options=chrome_options)

year = "2021"
url = f"https://www.atptour.com/en/stats/second-screen/archive/{year}/403/ms001"
driver.get(url)

try:
    # 切换到J.Sinner
    WebDriverWait(driver, 10).until(
        EC.element_to_be_clickable((By.XPATH, "//button[contains(text(), 'Jannik Sinner')]"))
    ).click()

    # 切换到一发
    WebDriverWait(driver, 10).until(
        EC.element_to_be_clickable((By.XPATH, "//button[contains(text(), '1st Serve')]"))
    ).click()

    # 切换到Deuce区
    WebDriverWait(driver, 10).until(
        EC.element_to_be_clickable((By.XPATH, "//button[contains(text(), 'Deuce')]"))
    ).click()

    # 等待落点元素加载并获取所有circle
    ball_circles = WebDriverWait(driver, 10).until(
        EC.presence_of_all_elements_located((By.CSS_SELECTOR, "#ball-plots circle"))
    )

    # 提取每个落点的坐标(cx, cy属性)
    for circle in ball_circles:
        cx = circle.get_attribute("cx")
        cy = circle.get_attribute("cy")
        print(f"落点坐标:({cx}, {cy})")

    # 可重复上述切换步骤,获取H.Hurkacz、二发、Add区的数据
finally:
    driver.quit()

额外注意事项

  • 页面按钮文本可能有细微差异(比如全名/缩写),需用浏览器开发者工具确认实际元素属性
  • 若发现元素嵌套在iframe内,需先切换iframe:driver.switch_to.frame("iframe_id")
  • 若遇到反爬限制,可增加--disable-blink-features=AutomationControlled参数规避检测

内容的提问来源于stack exchange,提问作者user20451823

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 22:01:18