Python抓取网页表格数据方法
**Python网页表格数据抓取教程:高效提取积雪深度信息** 想从网页上抓取表格数据却无从下手?本教程将手把手教你使用Python的requests、BeautifulSoup和Pandas库,轻松搞定复杂网页中的结构化表格数据提取。以抓取特定区域的积雪深度数据为例,我们将详细演示如何识别HTML元素,解析表格结构,最终构建可用于数据分析的Pandas DataFrame。本教程将提供实用代码示例和注意事项,助你掌握精确抓取网页表格数据的技巧,自动化获取并分析各种在线数据源。告别繁琐的手动复制粘贴,提升数据处理效率,让Python成为你数据分析的利器。无论你是数据分析师、开发者还是对数据抓取感兴趣的爱好者,都能从本教程中受益匪浅。

1. 背景与目标
在数据分析和自动化任务中,我们经常需要从网页上获取特定信息。当目标数据以表格形式呈现时,直接通过简单的元素选择器可能无法有效获取其结构化内容。本教程的目标是演示如何从一个包含积雪深度信息的网页(例如:https://www.yr.no/nb/sn%C3%B8dybder/NO-46/Norge/Vestland)中,准确提取特定区域的积雪深度数据,并将其整理成易于分析的Pandas DataFrame。
2. 初始尝试与挑战
许多初学者在尝试抓取网页数据时,可能会先尝试查找页面上所有包含特定值的通用标签,例如通过soup.find_all("span", {"class": "snow-depth__value"})来获取所有带有snow-depth__value类的span标签。这种方法虽然能获取到所有匹配的值,但存在以下问题:
- 缺乏上下文: 仅仅获取值无法知道它属于哪个区域、哪个时间点,数据是零散的。
- 结构化困难: 将这些零散的值与对应的标题或描述关联起来,并最终放入DataFrame中,需要额外的逻辑处理,效率低下且容易出错。
正确的思路是首先识别目标数据在网页上的整体结构,特别是当数据呈现为表格时。
3. 精确抓取表格数据:分步指南
我们将利用requests库获取网页内容,BeautifulSoup解析HTML,然后识别并提取表格的标题和每一行数据,最终使用Pandas构建DataFrame。
3.1 引入必要的库
首先,导入我们将用到的Python库:
import requests from bs4 import BeautifulSoup from bs4.element import ResultSet, Tag from typing import Generator, List from pandas import DataFrame
3.2 发送HTTP请求并解析HTML
使用requests.get()方法获取网页的HTML内容,然后使用BeautifulSoup对其进行解析。
# 目标网页URL url = 'https://www.yr.no/nb/sn%C3%B8dybder/NO-46/Norge/Vestland' # 发送GET请求获取网页内容 response: requests.Response = requests.get(url) html: str = response.content # 使用BeautifulSoup解析HTML soup: BeautifulSoup = BeautifulSoup(html, 'html.parser')
3.3 识别并提取表格头部(列名)
表格的列名通常位于
# 查找所有表格头部单元格
table_headers: ResultSet = soup.find_all('th', class_='fluid-table__cell--heading')
# 提取列名文本
# 注意:在BeautifulSoup中,由于'class'是Python的保留关键字,
# 在find_all/find方法中作为参数传递时需要使用'class_'。
colnames: List[str] = [th.text for th in table_headers]
print("提取到的列名:", colnames)3.4 识别并提取表格行数据
表格的每一行数据通常位于
为了高效处理数据,我们可以使用生成器表达式(Generator comprehension)来延迟计算,避免一次性加载所有数据到内存,这对于大型表格尤其有用。
# 查找所有表格数据行
table_rows: ResultSet = soup.find_all('tr', class_='fluid-table__row fluid-table__row--link')
# 使用生成器表达式提取每行中的所有单元格文本
# 每个子生成器代表一行数据,包含该行所有子元素的文本内容
# 这里的child.text会提取标签下所有子标签(如)的文本
row_data: Generator[Generator[str, None, None], None, None] = (
(child.text for child in row.children) for row in table_rows
)
# 打印前几行数据以供检查(可选)
print("\n提取到的部分行数据:")
for i, row in enumerate(row_data):
if i >= 3: # 只打印前3行
break
print(list(row)) # 将生成器转换为列表以便打印3.5 构建Pandas DataFrame
有了列名和行数据,我们就可以轻松地使用Pandas的DataFrame构造函数来创建结构化的数据表。
# 重新获取row_data,因为上一步的打印操作已经消耗了生成器
table_rows_for_df: ResultSet = soup.find_all('tr', class_='fluid-table__row fluid-table__row--link')
row_data_for_df: Generator[Generator[str, None, None], None, None] = (
(child.text for child in row.children) for row in table_rows_for_df
)
# 创建Pandas DataFrame
df: DataFrame = DataFrame(row_data_for_df, columns=colnames)
# 尝试将所有列的数据类型转换为整数,如果遇到无法转换的值则忽略(保持原类型)
df = df.astype(int, errors='ignore')
print("\n最终生成的Pandas DataFrame:")
print(df.head())4. 完整代码示例
将以上步骤整合,得到完整的代码如下:
import requests
from bs4 import BeautifulSoup
from bs4.element import ResultSet, Tag
from typing import Generator, List
from pandas import DataFrame
def scrape_snow_depth_data(url: str) -> DataFrame:
"""
从指定的URL抓取积雪深度表格数据并返回Pandas DataFrame。
Args:
url (str): 目标网页的URL。
Returns:
DataFrame: 包含积雪深度数据的Pandas DataFrame。
"""
try:
response: requests.Response = requests.get(url)
response.raise_for_status() # 检查HTTP请求是否成功
except requests.exceptions.RequestException as e:
print(f"请求网页失败: {e}")
return DataFrame()
html: str = response.content
soup: BeautifulSoup = BeautifulSoup(html, 'html.parser')
# 提取表格头部(列名)
table_headers: ResultSet = soup.find_all('th', class_='fluid-table__cell--heading')
colnames: List[str] = [th.text.strip() for th in table_headers] # 使用.strip()清除空白符
# 提取表格行数据
table_rows: ResultSet = soup.find_all('tr', class_='fluid-table__row fluid-table__row--link')
# 使用生成器表达式提取每行中的所有单元格文本
# 注意:这里需要确保每个row.children都能正确解析出所需的数据,
# 有时需要更精确的选择器如row.find_all('td')
row_data: Generator[List[str], None, None] = (
[child.text.strip() for child in row.children if isinstance(child, Tag)]
for row in table_rows
)
# 过滤掉空行或不完整的行,确保每行的数据量与列名数量一致
filtered_row_data = [row for row in row_data if len(row) == len(colnames)]
# 创建Pandas DataFrame
df: DataFrame = DataFrame(filtered_row_data, columns=colnames)
# 尝试将所有列的数据类型转换为整数,如果遇到无法转换的值则忽略
# 可能会有非数字列,所以使用errors='ignore'
for col in df.columns:
try:
df[col] = pd.to_numeric(df[col], errors='ignore')
except:
pass # 无法转换为数字的列保持原样
return df
if __name__ == "__main__":
import pandas as pd # 在主执行块中导入pd,避免全局污染
target_url = 'https://www.yr.no/nb/sn%C3%B8dybder/NO-46/Norge/Vestland'
snow_depth_df = scrape_snow_depth_data(target_url)
if not snow_depth_df.empty:
print("成功获取并处理积雪深度数据:")
print(snow_depth_df.head())
print("\nDataFrame信息:")
snow_depth_df.info()
else:
print("未能获取到数据。")
5. 注意事项与最佳实践
- 网站结构变化: 网页的HTML结构可能会随时改变。如果代码突然失效,很可能是因为网站更新了其HTML标签、类名或结构。这时需要重新检查目标网页的HTML,并调整选择器。
- robots.txt: 在进行网页抓取前,务必检查网站的robots.txt文件(例如:https://www.yr.no/robots.txt),了解网站的抓取策略和允许抓取的范围。遵守这些规则是道德和法律要求。
- 请求频率: 避免在短时间内发送大量请求,这可能导致IP被封禁或对网站服务器造成不必要的负担。可以使用time.sleep()在请求之间添加延迟。
- 错误处理: 在实际应用中,应添加更健壮的错误处理机制,例如处理网络连接问题、页面不存在(404错误)、解析失败等情况。
- 数据清洗: 抓取到的数据可能包含额外的空白字符、特殊符号或非预期的格式。使用.strip()、replace()等字符串方法进行进一步清洗是常见的步骤。
- astype(int, errors='ignore'): 这个方法在尝试转换数据类型时非常有用,它会忽略那些无法转换为指定类型的值,保持其原始类型,从而避免程序崩溃。
6. 总结
通过本教程,我们学习了如何利用requests、BeautifulSoup和Pandas库,从复杂的网页中高效且准确地提取结构化表格数据。关键在于深入理解目标网页的HTML结构,特别是表格(
、、 、)的组织方式。掌握这些技术,将使您能够自动化地获取并分析各种在线数据源,极大地提升数据处理能力。今天关于《Python抓取网页表格数据方法》的内容就介绍到这里了,是不是学起来一目了然!想要了解更多关于的内容请关注golang学习网公众号!
Golang大文件读取技巧:bufio.Scanner分块详解
- 上一篇
- Golang大文件读取技巧:bufio.Scanner分块详解
- 下一篇
- 汽水音乐导入本地歌曲步骤详解
查看更多
最新文章
-
-
文章 ·
python教程
| 17小时前 |
性能优化 ·
python ·
Python教程 ·
模块导入 ·
Python 3.15
lazy import
PEP 810
惰性导入
__lazy_modules__
-
Python 3.15 lazy import 怎么渐进接入:模块声明、首次访问与兼容边界
-
453浏览
收藏
-
-
文章 ·
python教程
| 2天前 |
python ·
运行时 ·
发布验收 ·
JIT
Python 3.14
PYTHON_JIT
sys._jit
-
Python 3.14 JIT 开关怎么做灰度检查:PYTHON_JIT、平台范围与生产禁用边界
-
228浏览
收藏
-
-
文章 ·
python教程
| 2天前 |
性能优化 ·
python ·
asyncio ·
版本升级 ·
asyncio
事件循环
性能基准
Python 3.14
native tasks
-
Python 3.14 asyncio 任务为何更快:10%–20% 基准如何正确复测
-
175浏览
收藏
-
-
-
文章 ·
python教程
| 3天前 |
-
Python decimal.Context.create_decimal_from_float 怎么避免浮点误差:上下文精度与舍入检查
-
451浏览
收藏
-
-
文章 ·
python教程
| 3天前 |
python ·
异步编程 ·
上下文变量 ·
Python
asyncio
contextvars
copy_context
ContextVar
-
Python contextvars.copy_context 如何隔离异步任务上下文:ContextVar 复制与回调边界
-
178浏览
收藏
-
-
文章 ·
python教程
| 4天前 |
数据库 ·
SQLite ·
sqlite3 ·
Python教程 ·
Python
SQLite
数据库查询
sqlite3.Row
row_factory
-
Python sqlite3.Row 如何让查询结果支持列名访问:row_factory、类型转换与空值检查
-
399浏览
收藏
-
-
文章 ·
python教程
| 4天前 |
-
Python importlib.resources.files 如何读取包内资源:Traversable 与 as_file 临时路径边界
-
195浏览
收藏
-
-
-
文章 ·
python教程
| 4天前 |
-
Python subprocess.run 如何安全传递多行标准输入:input、text 与返回码验收
-
278浏览
收藏
-
-
文章 ·
python教程
| 4天前 |
-
Python csv.QUOTE_NOTNULL 怎么保留空值语义:写入规则、读取差异与兼容回退
-
225浏览
收藏
-
查看更多
课程推荐
-
- 前端进阶之JavaScript设计模式
-
设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
-
本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
-
如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
-
在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
-
本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
查看更多
AI推荐
-
- SuperCLUE
-
SuperCLUE是权威的中文大语言模型综合评测基准,涵盖语言理解、知识应用、AI Agent智能体及安全性等12项核心能力。通过多轮对话与客观测试,定期发布榜单与技术报告,为模型研发、优化及行业选型提供科学依据。
- 113次使用
-
- C-Eval
-
深入了解C-Eval中文评估套件,涵盖52个学科与4级难度。本文详解其功能特点、Zero-shot/Few-shot使用方法及代码示例,助您全面评测LLM中文理解与泛化能力。
- 32次使用
-
- Gradio
-
Gradio是一个用于构建机器学习和数据科学Web应用的开源Python库。支持快速创建交互界面,获Google、Meta等大厂青睐,适合模型演示、部署反馈及调试。
- 107次使用
-
- AutoGPT
-
AutoGPT是基于GPT-4的开源AI代理平台,拥有超10万GitHub星标。本文介绍其低代码界面、自动化工作流功能、系统配置要求及安装步骤,助您高效部署和管理AI Agent。
- 114次使用
-
- Dataify
-
Dataify是专注AI生态的一站式数据服务平台,整合全球住宅代理、多源数据采集API及高质量训练数据集。支持LLM训练、跨境电商及金融分析,解决数据孤岛难题,助力企业智能化转型。
- 19次使用
查看更多
相关文章
-
- Python sqlite3 Connection serialize 怎么导出数据库快照:备份窗口、内存占用与恢复校验
-
2026-08-26
501浏览
-
- Python监控网页状态:requests异常处理实战
-
2026-05-29
501浏览
-
- TensorFlow模型部署为API的TF Serving方法
-
2026-05-26
501浏览
-
- Python字符串编码转换:encode与decode详解
-
2026-05-16
501浏览
-
- TensorFlow裁剪无用算子方法详解
-
2026-05-15
501浏览

