下面我将为你提供一个从入门到精通的完整指南,包括多种方法、代码示例、最佳实践和注意事项。

核心思路
提取网页表格数据的基本流程如下:
- 获取网页内容:向目标网址发送 HTTP 请求,获取网页的 HTML 源代码。
- 解析 HTML:使用 HTML 解析器读取源代码,并定位到包含表格数据的 HTML 元素。
- 提取数据:从定位到的表格元素中,逐行、逐列地提取出文本数据。
- 存储数据:将提取出的数据整理成结构化的格式(如列表、字典),并保存到文件(如 CSV、Excel)或数据库中。
使用 requests + BeautifulSoup (最常用、最推荐)
这是最流行、最灵活的 Python 爬虫组合。requests 用于下载网页,BeautifulSoup 用于解析 HTML。
安装必要的库
你需要安装这两个库:
pip install requests pip install beautifulsoup4 pip install lxml # 一个更快的HTML解析器,推荐使用
代码示例
假设我们要从一个简单的网页提取表格,这里我们以一个公开的示例网页为例:https://www.w3schools.com/html/html_tables.asp

目标: 提取 "Company" 和 "Contact" 两列的数据。
import requests
from bs4 import BeautifulSoup
import csv
# 1. 获取网页内容
url = "https://www.w3schools.com/html/html_tables.asp"
try:
# 发送HTTP GET请求,设置超时
response = requests.get(url, timeout=10)
# 确保请求成功 (状态码 200)
response.raise_for_status()
except requests.exceptions.RequestException as e:
print(f"请求失败: {e}")
exit()
# 2. 解析HTML
# 使用 'lxml' 解析器,它比默认的 'html.parser' 更快
soup = BeautifulSoup(response.text, 'lxml')
# 3. 提取数据
# 找到所有的表格,通常通过 <table> 标签
# 我们可以根据 id 或 class 来精确定位表格
# 这个页面的第一个表格的 id 是 "main"
table = soup.find('table', id='main')
# 检查是否找到表格
if not table:
print("未找到表格,请检查定位方式是否正确。")
exit()
# 存储提取的数据
table_data = []
# 找到表头 <thead> 和表体 <tbody>
# 如果没有明确的 <thead> 和 <tbody>,可以直接找所有的 <tr>
header_row = table.find('tr')
headers = [th.get_text(strip=True) for th in header_row.find_all('th')]
# 找到所有数据行 (在 <tbody> 或 <table> 下的 <tr>)
for row in table.find_all('tr')[1:]: # [1:] 是为了跳过表头行
# 找到当前行的所有单元格 <td>
cells = row.find_all('td')
# 提取每个单元格的文本内容,并去除首尾空格
row_data = [cell.get_text(strip=True) for cell in cells]
if row_data: # 确保行不为空
table_data.append(row_data)
# 4. 存储数据 (这里以存储为 CSV 为例)
csv_filename = 'w3schools_table.csv'
with open(csv_filename, 'w', newline='', encoding='utf-8') as csvfile:
# 创建一个 CSV writer 对象
csv_writer = csv.writer(csvfile)
# 写入表头
csv_writer.writerow(headers)
# 写入数据行
csv_writer.writerows(table_data)
print(f"数据已成功提取并保存到 {csv_filename}")
print("提取的表头:", headers)
print("提取的第一行数据:", table_data[0] if table_data else "无数据")
代码解析:
requests.get(url): 获取网页内容。BeautifulSoup(response.text, 'lxml'): 创建一个 BeautifulSoup 对象,用于解析 HTML。soup.find('table', id='main'): 查找id为main的<table>标签。find找到第一个匹配项。table.find_all('tr'): 查找表格中所有的<tr>(table row) 标签,返回一个列表。[th.get_text(strip=True) for th in ...]: 使用列表推导式,提取所有表头<th>的文本,并用strip()去除多余空格。csv.writer: Python 内置的csv模块,用于将数据写入 CSV 文件。
使用 pandas (极其简单,适合结构化好的表格)
如果你的目标网页表格结构非常规整,pandas 提供了一个“一键读取”的函数 read_html,非常方便。
安装 pandas
pip install pandas
代码示例
还是使用上面的网址。

import pandas as pd
url = "https://www.w3schools.com/html/html_tables.asp"
# pd.read_html 会自动查找页面中所有的 <table> 标签
# 并返回一个包含多个 DataFrame 的列表
# 每个表格对应一个 DataFrame
try:
tables = pd.read_html(url)
# 通常第一个表格是我们想要的
df = tables[0]
# 查看提取的数据
print(df.head())
# 直接保存为 Excel 文件
df.to_excel('table_with_pandas.xlsx', index=False)
print("\n数据已成功保存到 table_with_pandas.xlsx")
except Exception as e:
print(f"使用 pandas 读取表格时出错: {e}")
print("这可能是因为页面结构复杂或需要 JavaScript 渲染。")
优点:
- 代码量极少,通常一行代码就能搞定。
- 数据格式化好,直接得到一个结构化的 DataFrame,方便后续进行数据分析。
缺点:
- 灵活性差:
read_html对复杂的表格(如跨行、跨列的rowspan/colspan)支持不佳。 - 性能开销:
pandas是一个大型库,对于简单的抓取任务来说可能有点“杀鸡用牛刀”。 - 限制:和
requests一样,无法抓取由 JavaScript 动态加载的内容。
处理动态加载的网页 (使用 Selenium)
很多现代网站的数据是通过 JavaScript 动态加载的。requests 只能获取到初始的 HTML,看不到 JS 渲染后的内容,这时就需要 Selenium。
安装 Selenium 和浏览器驱动
pip install selenium
你还需要下载对应浏览器的 WebDriver,这里以 Chrome 为例:
- 确保你已安装 Chrome 浏览器。
- 访问 Chrome for Testing availability 下载与你的 Chrome 版本匹配的
chromedriver。 - 将下载的
chromedriver.exe(Windows) 或chromedriver(Mac/Linux) 放在你的项目目录,或者将其路径添加到系统环境变量PATH中。
代码示例
假设我们要抓取一个需要点击按钮才能加载表格的网站(这里我们用一个需要滚动才能加载的页面作为示例)。
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
from bs4 import BeautifulSoup
import time
# 1. 设置 Selenium
# 替换成你的 chromedriver 的实际路径
chrome_driver_path = './chromedriver'
service = Service(executable_path=chrome_driver_path)
driver = webdriver.Chrome(service=service)
# 2. 打开目标网页
url = "https://example.com/some-dynamic-page" # 替换成你的目标网址
driver.get(url)
# 3. 处理动态加载
# 示例:等待页面滚动到最底部,以触发懒加载
print("正在滚动页面以加载所有表格数据...")
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
time.sleep(3) # 给页面一些时间加载数据
# 4. 获取渲染后的 HTML
html_content = driver.page_source
# 5. 关闭浏览器
driver.quit()
# 6. 使用 BeautifulSoup 解析渲染后的 HTML (与方法一相同)
soup = BeautifulSoup(html_content, 'lxml')
# 假设表格的 class 是 'data-table'
table = soup.find('table', class_='data-table')
if table:
# ... (接下来的提取逻辑和方法一完全一样)
print("表格已找到,开始提取数据...")
# 提取数据的代码...
else:
print("未找到表格,请检查定位方式和动态加载逻辑。")
Selenium 的工作原理:
Selenium 会像真人一样操作一个真实的浏览器,它可以执行点击、输入、滚动等操作,并等待页面完全渲染(包括 JavaScript 执行完毕)后,再获取最终的 HTML 内容。
最佳实践与注意事项
-
检查
robots.txt:在抓取一个网站之前,请务必检查其robots.txt文件(https://www.target-website.com/robots.txt),这个文件告诉爬虫哪些页面可以抓取,哪些不可以,尊重网站规则是良好爬虫的基本素养。 -
设置请求头:有些网站会拒绝没有
User-Agent的请求,模拟浏览器可以降低被屏蔽的风险。headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36' } response = requests.get(url, headers=headers) -
处理反爬机制:如果请求过于频繁,可能会被网站封禁 IP,可以采取以下措施:
- 添加延迟:在两次请求之间使用
time.sleep(random.uniform(1, 3))模拟人类的操作节奏。 - 使用代理 IP:通过代理服务器发送请求,避免使用单一 IP。
- 处理验证码:如果遇到验证码,可能需要借助第三方服务或更高级的技术。
- 添加延迟:在两次请求之间使用
-
错误处理:网络请求可能会因为各种原因失败(如网络中断、404 Not Found、500 Server Error),
try...except语句是必不可少的。 -
数据存储:
- CSV:适合简单的二维表格数据。
- Excel:功能更强,可以格式化,但需要
openpyxl或xlwt等库支持。 - 数据库 (SQLite, MySQL, PostgreSQL):当数据量非常大,或者需要频繁查询时,将数据存入数据库是最佳选择,可以使用
sqlite3(Python内置) 或SQLAlchemy等 ORM 框架。
总结与选择
| 方法 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
requests + BeautifulSoup |
灵活、强大、社区支持好、可处理复杂HTML结构 | 需要手动解析、不处理JS动态内容 | 绝大多数静态网页,是爬虫的基石。 |
pandas.read_html |
极其简单、代码少、直接得到DataFrame | 不灵活、对复杂表格支持差、性能开销大 | 结构非常规整、简单的静态表格,快速分析用。 |
Selenium |
能处理JS动态加载、可模拟用户交互 | 速度慢、资源消耗大、配置复杂 | 需要点击、滚动或JS渲染才能显示数据的网页。 |
给你的建议:
- 从
requests+BeautifulSoup开始,这是最核心、最应该掌握的技能。 - 如果你的表格非常简单,想快速完成任务,可以尝试
pandas。 - 如果发现网页数据是动态加载的,再考虑使用
Selenium。
