自学教程 学编程从这里开始

Pandas 读取 HTML 表格

说明:pandas 读取网页表格依赖 read_html(),底层是解析页面里 <table> 标签,不是爬虫接口,只适合提取静态表格;JS动态渲染表格该方法读不到。

1. 环境安装

# 两个解析引擎二选一,推荐 lxml 速度更快
pip install pandas lxml
# 备选:html5lib(容错更强,适合不规范网页)
# pip install html5lib

2. 基础语法

pd.read_html(
    io,
    match=".+",       # 匹配表格文本,筛选目标表
    flavor="lxml",    # 解析引擎 lxml / html5lib
    header=None,      # 指定哪一行作为表头
    index_col=None,   # 指定索引列
    skiprows=None,    # 跳过行
    attrs=None,       # 根据table标签属性筛选 table attrs
    converters=None,  # 列数据转换
    na_values=None,
    keep_default_na=True
)

返回值:DataFrame列表,一个网页里可能有多个 <table>,每一个对应一个df。

3. 最简单示例:直接读取网页URL

import pandas as pd

url = "[https://example-table-url.com](https://example-table-url.com)"
# 读取页面所有table
df_list = pd.read_html(url, flavor="lxml")

print(f"一共找到 {len(df_list)} 个表格")
# 取第1个表格
df = df_list[0]
print(df.head())

4. 读取本地HTML文件

import pandas as pd

# 读取本地html文件
df_list = pd.read_html("table.html", flavor="lxml")
df = df_list[0]
print(df)

本地示例 table.html 内容:

<table border="1">
  <tr><th>姓名</th><th>年龄</th><th>城市</th></tr>
  <tr><td>张三</td><td>22</td><td>杭州</td></tr>
  <tr><td>李四</td><td>25</td><td>上海</td></tr>
</table>

5. 进阶筛选技巧

5.1 match 匹配包含指定文字的表格

页面很多表格,只取包含“销量”的那张表

df_list = pd.read_html(url, match="销量", flavor="lxml")
df = df_list[0]

5.2 attrs 根据table属性筛选

# 只读取 <table class="data-table">
df_list = pd.read_html(url, attrs={"class": "data-table"}, flavor="lxml")

5.3 指定表头、跳过行

# 第0行作为表头,跳过前1行
df_list = pd.read_html(url, header=0, skiprows=[0], flavor="lxml")

6. 读取字符串里的HTML表格

适合拿到html片段直接解析

import pandas as pd

html_text = """
<table>
<tr><th>id</th><th>name</th></tr>
<tr><td>1</td><td>apple</td></tr>
<tr><td>2</td><td>banana</td></tr>
</table>
"""
df_list = pd.read_html(html_text)
df = df_list[0]
print(df)

7. 读取后保存到 Excel / CSV

df.to_excel("html_table_result.xlsx", index=False)
df.to_csv("html_table_result.csv", index=False, encoding="utf-8-sig")

8. 常见坑 & 限制(重点)

  1. JS渲染表格读不到

    read_html 不会执行JS。网页是Vue/React动态渲染、点击加载表格 → pandas读不到,需要用 Selenium / Playwright 拿到渲染完成后的html源码再传给read_html。

Playwright 简易示例:

from playwright.sync_api import sync_playwright
import pandas as pd

with sync_playwright() as p:
    browser = p.chromium.launch(headless=True)
    page = browser.new_page()
    page.goto(url)
    html = page.content()
    df_list = pd.read_html(html)
    browser.close()
  1. 网页有反爬、需要Cookie、登录态:read_html 不支持请求头,需要先用 requests 拿到html源码
import requests
import pandas as pd

headers = {"User-Agent":"Mozilla/5.0"}
resp = requests.get(url, headers=headers)
df_list = pd.read_html(resp.text)
  1. 合并单元格:pandas读取后会自动填充,和网页显示有差异,需要自己清洗
  2. 表格嵌套、复杂合并、分页表格:read_html 能力弱,优先选专门爬虫解析(BeautifulSoup)

9. 清洗示例:去除空行、重置索引

df = df.dropna(how="all")  # 删除全空行
df = df.reset_index(drop=True)

10. 完整综合代码(requests + read_html + 导出)

import pandas as pd
import requests

url = "xxx"
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
}

res = requests.get(url, headers=headers, timeout=10)
res.raise_for_status()

tables = pd.read_html(res.text, match="", flavor="lxml")
print(f"表格数量:{len(tables)}")

target_df = tables[0]
print(target_df.head())

target_df.to_excel("output_html_table.xlsx", index=False)

0 条笔记