
本文详解如何修复 pandas.read_html() 因直接传入字符串 HTML 而触发的 FutureWarning,推荐使用 io.StringIO 包装 HTML 字符串,并提供可直接运行的代码示例与关键注意事项。
本文详解如何修复 `pandas.read_html()` 因直接传入字符串 html 而触发的 `futurewarning`,推荐使用 `io.stringio` 包装 html 字符串,并提供可直接运行的代码示例与关键注意事项。
在使用 pandas.read_html() 从网络响应中提取表格(如英超赛程、比分等结构化数据)时,常见写法如下:
import pandas as pd matches = pd.read_html(data.text, match="Scores & Fixtures")[0]
但自 pandas 2.2.0 起,该用法会触发明确警告:
FutureWarning: Passing literal html to 'read_html' is deprecated and will be removed in a future version. To read from a literal string, wrap it in a 'StringIO' object.
这是因为 read_html() 已不再接受原始字符串(str)作为第一参数,而要求输入为类文件对象(file-like object)。直接传入 data.text(即 str 类型)属于已弃用行为,未来版本将彻底报错。
✅ 正确做法:使用 io.StringIO 将 HTML 字符串转换为可读取的流对象:
立即学习“前端免费学习笔记(深入)”;
import pandas as pd import io # 假设 data.text 是 requests.Response 对象的 .text 属性(UTF-8 编码的 HTML 字符串) html_stream = io.StringIO(data.text) matches = pd.read_html(html_stream, match="Scores & Fixtures")[0]
⚠️ 注意事项:
- 编码一致性:确保 data.text 已正确解码(通常 requests.get(...).text 默认按 HTTP 头或 自动解码,无需额外指定 encoding);
- 不要传 io.StringIO(...).read():错误示例 pd.read_html(io.StringIO(data.text).read()) 会传入 str,仍触发警告;必须传入 StringIO 实例本身(即文件对象),而非其读取结果;
-
字节流场景(较少见):若你持有原始 bytes(如 data.content),应使用 io.BytesIO 并显式指定 encoding 参数:
html_bytes = io.BytesIO(data.content) matches = pd.read_html(html_bytes, encoding='utf-8', match="Scores & Fixtures")[0]
-
健壮性建议:添加异常处理与空结果校验,因网页结构变动可能导致 read_html 返回空列表:
tables = pd.read_html(html_stream, match="Scores & Fixtures") if not tables: raise ValueError("No table matching 'Scores & Fixtures' found.") matches = tables[0]
总结:迁移只需两步——导入 io,用 io.StringIO(data.text) 替换 data.text。此举不仅消除警告,更符合 pandas 的 I/O 设计规范,保障代码长期兼容性。务必避免“先 .read() 再传入”的误区,核心是传递可迭代的流对象,而非字符串内容本身。










