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

如何用Selenium访问OpenStreetBrowser的SVG元素获取限速数据

解决OpenStreetBrowser瓦片点击与限速数据获取问题

问题分析

你遇到的TimeoutException是因为页面地图瓦片并非直接通过SVG元素暴露,而是由Leaflet类地图库渲染的图片瓦片,道路数据是叠加在瓦片上的矢量图层,直接定位SVG的XPath逻辑不准确。

解决方案步骤

1. 调整元素定位逻辑

放弃直接定位SVG,转而定位地图容器内的可交互矢量图层。OpenStreetBrowser基于Leaflet开发,地图容器#map下的.leaflet-overlay-pane .leaflet-interactive是承载道路数据的可点击层,定位该元素更可靠:

# 等待地图可交互图层加载完成
map_layer = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, "#map .leaflet-overlay-pane .leaflet-interactive")))

2. 模拟点击道路元素

由于道路是矢量元素,直接点击地图上的道路位置比点击瓦片更精准,可使用ActionChains模拟坐标点击:

from selenium.webdriver.common.action_chains import ActionChains

# 获取地图容器的位置参数
map_container = driver.find_element(By.ID, "map")
map_x = map_container.location['x']
map_y = map_container.location['y']

# 模拟点击地图中心附近的道路(可根据实际场景调整偏移量)
ActionChains(driver).move_to_element_with_offset(map_container, 200, 200).click().perform()

3. 提取弹窗内的限速数据

点击道路后会弹出详情窗口,定位详情按钮并提取限速字段:

# 等待详情按钮可点击并触发
wait.until(EC.element_to_be_clickable((By.XPATH, "//button[contains(text(), 'Details')]"))).click()

# 提取限速数据
maxspeed = wait.until(EC.presence_of_element_located((By.XPATH, "//div[contains(text(), 'maxspeed')]/following-sibling::div"))).text
print(f"道路限速: {maxspeed}")

4. 优化等待策略

增加地图瓦片加载的等待,避免过早执行后续操作:

# 等待所有地图瓦片加载完成
wait.until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, "#map .leaflet-tile")))

完整修改代码

from selenium import webdriver
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains

driver = webdriver.Chrome()
driver.maximize_window()
driver.get('https://www.openstreetbrowser.org')

wait = WebDriverWait(driver, 20)

# 导航至Maxspeed分类
wait.until(EC.element_to_be_clickable((By.XPATH, "//a[contains(text(), 'Transportation')]"))).click()
wait.until(EC.element_to_be_clickable((By.XPATH, "//a[contains(text(), 'Individual Traffic')]"))).click()
wait.until(EC.element_to_be_clickable((By.XPATH, "//a[contains(text(), 'Maxspeed')]"))).click()

# 搜索定位目标区域
wait.until(EC.element_to_be_clickable((By.XPATH, "//ul[@class='tabs-list']//li[@title='search']"))).click()
search_input = wait.until(EC.element_to_be_clickable((By.XPATH, "//div[@class='tabs-section nominatim-search selected']//input")))
search_input.send_keys('53.40125254855821,-3.0876670857133757')
wait.until(EC.element_to_be_clickable((By.XPATH, "//div[@class='tabs-section nominatim-search selected']//ul//li"))).click()

# 等待地图资源加载完成
wait.until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, "#map .leaflet-tile")))
wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, "#map .leaflet-overlay-pane .leaflet-interactive")))

# 模拟点击道路位置
map_container = driver.find_element(By.ID, "map")
ActionChains(driver).move_to_element_with_offset(map_container, 200, 200).click().perform()

# 获取并打印限速数据
wait.until(EC.element_to_be_clickable((By.XPATH, "//button[contains(text(), 'Details')]"))).click()
maxspeed = wait.until(EC.presence_of_element_located((By.XPATH, "//div[contains(text(), 'maxspeed')]/following-sibling::div"))).text
print(f"道路限速: {maxspeed}")

driver.quit()

注意事项

  • 地图元素的层级可能随网站更新变化,需定期检查CSS选择器有效性
  • 若点击位置不准确,可调整move_to_element_with_offset的偏移量,或直接使用绝对坐标点击
  • 如需批量获取数据,可循环遍历地图区域内的多个坐标点

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 18:35:06