
本文介绍如何绕过 selenium 渲染难题,直接调用后端 rest api 获取 gavlepistol 赛事名单中的参赛队伍(rv-squad)、标题(rv-squad-header)和选手(rv-participant)结构化数据,避免因 react 动态渲染导致的元素定位失败。
本文介绍如何绕过 selenium 渲染难题,直接调用后端 rest api 获取 gavlepistol 赛事名单中的参赛队伍(rv-squad)、标题(rv-squad-header)和选手(rv-participant)结构化数据,避免因 react 动态渲染导致的元素定位失败。
在爬取基于 React 构建的现代单页应用(SPA)时,常见误区是依赖 Selenium 等浏览器自动化工具“等待并查找 DOM 元素”。然而,目标页面 https://www.php.cn/link/ba85b1fdaab8f50fc116a55a29fe591c 实际由 React 动态渲染,其核心数据全部通过 AJAX 从后端 API 加载——这意味着:
- driver.find_elements(By.CLASS_NAME, 'rv-squad-header') 返回空列表,并非选择器错误,而是对应 HTML 在初始响应中根本不存在;
- 即使添加 time.sleep(5) 或显式等待(如 WebDriverWait),也无法保证 React 完成数据获取与组件挂载(尤其当 API 请求存在延迟或错误时);
- 使用 By.CLASS_NAME 传入复合类名(如 'div.rv-squad-header.full')语法错误——CLASS_NAME 仅支持单个类名,且不接受 CSS 选择器语法。
✅ 推荐方案:直连后端 API,跳过前端渲染层
该站点后端暴露了清晰的 REST 接口(经网络面板分析可得):
- 赛事基础信息:https://dev.bitnux.com/anmalan/competition/{id}
- 每场赛程的参赛名单:https://dev.bitnux.com/anmalan/schedules/{schedule_id}/squad
以下为完整、健壮的 Python 实现:
import requests
from typing import Dict, List, Any
def fetch_competition_roster(comp_id: int) -> None:
base_url = "https://dev.bitnux.com/anmalan"
# 1. 获取赛事主信息
comp_resp = requests.get(f"{base_url}/competition/{comp_id}")
comp_resp.raise_for_status()
comp_data: Dict[str, Any] = comp_resp.json()
print(f"赛事名称:{comp_data['name']}\n")
# 2. 遍历所有赛程(events),获取每场的 squad 数据
for event in comp_data.get("events", []):
schedule_id = event["schedule"]
squad_resp = requests.get(f"{base_url}/schedules/{schedule_id}/squad")
squad_resp.raise_for_status()
squads: List[Dict] = squad_resp.json()
for squad in squads:
if not squad.get("entries"): # 跳过无选手的场次
continue
print(f"【{squad['time']}】")
for entry in squad["entries"]:
# 格式化输出:姓名(左对齐25)、所属组织(左对齐45)、组别
print(f"{entry['name']:<25} {entry['organization']:<45} {entry['division']}")
print()
# 调用示例
if __name__ == "__main__":
fetch_competition_roster(653)? 关键优势与注意事项:
React 与 Next.js 性能优化指南,源自 Vercel 工程团队。适用于编写、审查或重构 React/Next.js 代码时使用。
- 稳定性高:API 响应结构稳定,不受前端框架更新、CSS 类名变更或加载动画影响;
- 性能优异:省去浏览器启动、页面渲染、JS 执行开销,请求耗时通常 < 1s;
- 易扩展:可轻松批量拉取多场赛事(循环 comp_id)、添加重试机制(requests.adapters.HTTPAdapter)、或存入 CSV/数据库;
- 合规提醒:请查阅站点 robots.txt 及服务条款,建议添加 headers={"User-Agent": "Mozilla/5.0..."} 并控制请求频率(如 time.sleep(0.5)),尊重服务器负载。
⚠️ 若必须使用 Selenium(例如需触发前端交互或验证渲染逻辑),请改用 WebDriverWait + presence_of_element_located 等待策略,并确保使用正确 CSS 选择器:
from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC # 正确写法(CSS_SELECTOR 支持复合类) headers = WebDriverWait(driver, 10).until( EC.presence_of_all_elements_located((By.CSS_SELECTOR, ".rv-squad-header.full")) )
但对本场景而言,API 方式是更简洁、可靠、专业的首选解法。

















