使用Python和Selenium爬取op.gg时,英雄排名类tspan元素无法获取
问题:无法通过Selenium爬取Op.gg中卡西奥佩娅的胜率排名数据
问题背景
需要爬取Op.gg网站中英雄卡西奥佩娅中路不同游戏时长下的胜率排名信息(如2nd这类文本),该信息存储在tspan元素中,但现有Selenium代码仅能获取胜率、游戏时长等部分tspan内容,无法抓取排名相关的tspan。
示例目标元素
<text x="60" y="31.440000000000026" class="recharts-text recharts-label" text-anchor="middle" style="fill: rgb(117, 133, 146); font-size: 11px; font-weight: bold;"> <tspan x="60" dy="0em">2nd</tspan> </text>
现有代码
from selenium import webdriver from selenium.webdriver.common.by import By driver = webdriver.Chrome() driver.get("https://www.op.gg/champions/cassiopeia/mid/trends?region=global&tier=platinum_plus") results = driver.find_elements(By.TAG_NAME, "tspan"); for r in results: print(r.text)
现有输出(缺失排名数据)
13.04 13.05 13.06 13.07 13.08 13.09 13.10 13.11 13.12 13.13 50% 51% 52% 53% 54% 13.04 13.05 13.06 13.07 13.08 13.09 13.10 13.11 13.12 13.13 1% 2% 3% 4% 5% 13.04 13.05 13.06 13.07 13.08 13.09 13.10 13.11 13.12 13.13 0% 1% 2% 3% 4% 0 25 30 35 40 48% 50% 52% 54% 56%
解决方案
问题原因
排名数据所在的tspan属于图表的悬浮提示框(Tooltip),默认状态下不显示,只有鼠标悬停在对应的数据点上时才会加载渲染,因此直接全局抓取tspan无法获取该内容。
修改后的代码
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.common.action_chains import ActionChains from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC import time driver = webdriver.Chrome() driver.get("https://www.op.gg/champions/cassiopeia/mid/trends?region=global&tier=platinum_plus") # 等待页面核心图表数据点加载完成 wait = WebDriverWait(driver, 10) try: chart_points = wait.until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, ".recharts-scatter-symbol"))) # 将图表滚动到可视区域,避免悬停失效 driver.execute_script("arguments[0].scrollIntoView({block: 'center'});", chart_points[0]) action = ActionChains(driver) for idx, point in enumerate(chart_points): # 执行悬停动作触发Tooltip action.move_to_element(point).perform() time.sleep(0.6) # 等待Tooltip完全渲染 # 精准定位排名对应的tspan(父元素带recharts-label类) rank_elements = driver.find_elements(By.CSS_SELECTOR, ".recharts-label tspan") if rank_elements: print(f"游戏时长段 {idx+1}: 排名 {rank_elements[0].text}") # 可选:同时抓取对应时长和胜率数据 tooltip_items = driver.find_elements(By.CSS_SELECTOR, ".recharts-tooltip-item") if tooltip_items: print(f"对应数据: {tooltip_items[0].text}, {tooltip_items[1].text}\n") except Exception as e: print(f"抓取出错: {str(e)}") finally: driver.quit()
代码说明
- 等待元素加载:使用
WebDriverWait确保图表数据点完全加载后再操作,避免空指针异常。 - 滚动到可视区域:通过JS将图表滚动到页面中间,确保悬停动作能被页面识别。
- 触发Tooltip:使用
ActionChains模拟鼠标悬停,触发包含排名的提示框显示。 - 精准定位:通过CSS选择器
.recharts-label tspan直接筛选排名对应的tspan,避免和其他无关tspan混淆。 - 延迟等待:添加短暂等待时间,确保Tooltip的DOM元素完全渲染完成后再抓取。
内容的提问来源于stack exchange,提问作者Artur Szafraniak
相关产品推荐
相关产品推荐

