
本文详解当网页源码不包含浏览器中显示的数据时(如 valencia 马拉松排名页),如何定位真实数据源、识别 iframe 加载机制,并使用 requests + beautifulsoup 直接解析嵌入的 html 表格,避免依赖 selenium。
现代赛事成绩网站(如 Valencia Marathon 2021 成绩页)常采用 iframe 嵌入独立结果页面,导致你在主 URL 右键“查看网页源代码”时看不到运动员姓名、完赛时间等关键数据——这些内容实际由 iframe 的 src 指向的另一个 URL 动态加载,而非通过 JavaScript 渲染。这并非典型的 AJAX 或 SPA 场景,而是一种静态 HTML 嵌套结构,因此无需启动浏览器即可高效抓取。
关键步骤如下:
定位真实数据 URL:在浏览器开发者工具(F12)的 Elements 标签页中搜索
-
分析目标 HTML 结构:打开该 iframe URL,用 Ctrl+U 查看源码,确认成绩表格是否以标准
形式存在(本例中为 ID 为 tabPodium 的表格),且无 JavaScript 动态渲染逻辑——这意味着 requests 可直接获取完整 HTML。
立即学习“前端免费学习笔记(深入)”;
使用 pandas.read_html() 高效解析:相比手动遍历
/ ,pd.read_html() 能自动识别并转换 HTML 表格为 DataFrame,简洁可靠。配合 BeautifulSoup 提前筛选目标表格元素,可精准提取所需内容。 以下是完整可运行代码示例:
from io import StringIO import pandas as pd import requests from bs4 import BeautifulSoup # 真实成绩页面 URL(即 iframe 的 src) url = "https://www.php.cn/link/2636d8136e53d78459c2718e1bf82d34" # 获取页面 HTML response = requests.get(url) response.raise_for_status() # 确保请求成功 soup = BeautifulSoup(response.content, "html.parser") # 定位成绩表格(根据页面实际 ID 或 class 调整选择器) table = soup.select_one("#tabPodium") if not table: raise ValueError("未找到 ID 为 'tabPodium' 的表格,请检查页面结构是否更新") # 将表格 HTML 字符串转为 DataFrame df = pd.read_html(StringIO(str(table)))[0] print(df)✅ 输出示例:
Unnamed: 0 Name Official time Country 0 1 CHERONO, LAWRENCE 2:05:12 KEN 1 2 DESO, CHALU 2:05:16 ETH 2 3 KACHERAN, PHILEMON 2:05:19 KEN
⚠️ 注意事项:
- 若页面启用了反爬(如 User-Agent 检查、频率限制),需为 requests.get() 添加合理 headers(如 'User-Agent': 'Mozilla/5.0...')并控制请求间隔;
- 表格 ID(如 #tabPodium)可能随年份或赛事变更,建议先人工验证目标页面结构,或使用更鲁棒的选择器(如 soup.find('table', class_='results-table'));
- pandas.read_html() 默认返回列表,索引 [0] 表示第一个匹配表格,若页面含多个表格请确认索引或添加 match= 参数过滤;
- 此方法不适用于真正由 JavaScript 动态生成 DOM 的场景(如 React/Vue 渲染的表格),此时才需考虑 Selenium 或 Playwright。
总结:面对“源码无数据”的网页,优先排查 iframe、AJAX 接口或静态资源链接,而非直接诉诸重量级自动化工具。理解网页架构(HTML 嵌套 vs JS 渲染)是高效抓取的前提——本例正是 iframe 静态加载的典型,轻量级方案即可完美解决。











