pandas 的 read_html() 在解析含逗号小数的网页表格时,默认将逗号识别为千位分隔符而非小数点,导致如 0,62 被误转为 062。本文详解通过 decimal=',' 和 thousands=None 参数精准控制数值解析,并提供免 Selenium 的简洁爬取方案。
pandas 的 `read_html()` 在解析含逗号小数的网页表格时,默认将逗号识别为千位分隔符而非小数点,导致如 `0,62` 被误转为 `062`。本文详解通过 `decimal=','` 和 `thousands=none` 参数精准控制数值解析,并提供免 selenium 的简洁爬取方案。
当使用 pandas.read_html() 从网页(尤其是欧洲语言站点,如意大利语版 FBref)抓取含本地化数字格式的表格时,一个常见陷阱是:0,62(表示 0.62)被错误解析为整数 062(即 62)。这是因为 read_html() 默认遵循英语数字习惯——将英文句点 . 视为小数点、逗号 , 视为千位分隔符(如 1,000.5)。而意大利、德国等地区恰恰相反:逗号是小数点,句点是千位分隔符。
要正确解析此类数据,关键在于显式指定 decimal 和 thousands 参数:
- decimal=',':明确告诉 pandas 将逗号作为小数分隔符;
- thousands=None:禁用千位分隔符识别,避免将 0,62 中的逗号误判为分隔符并移除。
此外,FBref 等网站常将 HTML 表格内容包裹在 <!-- --> 注释中,直接 read_html() 会失败。需先清理注释;同时其表头为多级结构,可利用 header=1 跳过第一行(通常为冗余标题),直接以第二行为列名。
以下是完整、轻量化的解决方案(无需 Selenium 或 BeautifulSoup):
立即学习“前端免费学习笔记(深入)”;
import pandas as pd
import requests
url = "https://fbref.com/it/comp/11/shooting/Statistiche-di-Serie-A#all_stats_shooting"
html = requests.get(url).text.replace("<!--", "").replace("-->", "")
df = pd.read_html(
html,
attrs={"id": "stats_shooting"}, # 定位目标表格
header=1, # 使用第2行作为列名(跳过首行合并标题)
decimal=",", # 指定逗号为小数点
thousands=None # 禁用千位分隔符解析
)[0]
# 清理重复的子标题行(FBref 表格中常见 'Pos.' 占位行)
df = df[df["Pos."] != "Pos."].reset_index(drop=True)⚠️ 注意事项:
- decimal 和 thousands 必须同时设置:仅设 decimal="," 而不设 thousands=None,pandas 仍可能将逗号优先解释为千位符;
- 若页面含动态渲染内容(如 JavaScript 加载的表格),requests 可能无法获取完整 HTML,此时才需回退至 Selenium + BeautifulSoup 方案,但务必在传给 read_html() 前对 str(table) 执行相同参数配置;
- 多级列索引(MultiIndex)问题可通过 header=[0,1] 处理,但本例中 header=1 已足够简化结构;
- 解析后建议检查关键数值列类型:df['xG'].dtype 应为 float64,若仍为 object,说明存在非数字字符(如 '—'),可用 df.replace('—', pd.NA).astype(float) 进一步清洗。
掌握 decimal 与 thousands 的协同配置,是可靠解析国际化 HTML 表格数值的核心技巧——它让 read_html() 从“自动猜测”转向“精确控制”,大幅提升数据可信度与开发效率。


















