新闻中心
Python HTML内容到自定义JSON结构的转换教程

本教程旨在解决将html内容转换为特定json格式的需求,特别是当直接使用`html_to_json`等库无法满足自定义键值对和层级结构时。文章将深入探讨如何利用python的`beautifulsoup`库对html进行语义解析,提取所需文本信息,并将其重构为用户定义的json格式,包括嵌套的子元素,以实现更灵活和精确的数据转换。
在数据处理和Web抓取场景中,将HTML文档转换为结构化的JSON数据是一种常见需求。然而,许多现成的HTML到JSON转换库,如html_to_json,通常会生成一个反映HTML DOM(文档对象模型)结构的JSON表示,其中包含了大量的HTML标签信息,这往往与用户期望的、仅包含业务逻辑键值对的扁平或自定义层级结构不符。当需要从HTML中提取特定的文本内容,并将其组织成具有自定义key、value和child数组的JSON格式时,直接的DOM转换工具显得力不从心。此时,我们需要采用更精细的HTML解析方法。
理解问题:为何直接转换不适用
像html_to_json这样的库,其设计目的是将HTML的标签、属性和文本内容完整地映射到JSON结构中。例如,一个标签内的文本会被表示为{"span": [{"_value": "文本内容"}]}。这种方式保留了原始HTML的完整性,但当我们的目标是:
- 去除所有HTML标签,只保留纯文本内容。
- 根据HTML的语义结构(而非DOM结构)构建JSON,例如将标题、段落等作为独立的键值对。
- 创建自定义的层级关系,如child数组来表示嵌套内容。
此时,我们需要一个能够灵活导航HTML树、提取特定元素内容并手动构建JSON对象的工具。Python的BeautifulSoup库正是为此类任务而生。
解决方案:使用BeautifulSoup进行语义解析
BeautifulSoup是一个用于从HTML和XML文件中提取数据的Python库。它能够将复杂的HTML文档转换成一个Python对象,使得开发者可以方便地通过标签名、属性、CSS选择器等方式搜索、导航和修改解析树。
以下是使用BeautifulSoup实现HTML到自定义JSON转换的基本步骤:
- 加载HTML内容:将HTML文件读取为字符串。
- 创建BeautifulSoup对象:将HTML字符串解析为可操作的树结构。
- 定位目标元素:使用find(), find_all(), select()等方法查找需要提取数据的HTML元素。
- 提取数据:从定位到的元素中提取文本内容(.get_text())或属性值(['attribute_name'])。
- 构建自定义JSON结构:根据提取的数据和预期的JSON格式,手动创建Python字典和列表,最终转换为JSON字符串。
示例代码:构建自定义JSON结构
为了演示如何将HTML内容转换为如{"key": "1", "value": "内容", "child": []}这样的自定义JSON格式,我们将假设有一个结构化的HTML片段,其中包含带有特定标识(如data-key属性)的章节和子章节。
假设的HTML文件 (sample.html) 内容:
<!DOCTYPE html>
<html>
<head>
<title>文档标题</title>
</head>
<body>
<div class="section" data-key="1">
<h1>第一章</h1>
<p>这是第一章的主要内容。</p>
<p>可能还有其他描述。</p>
<div class="aritcle_card">
<a class="aritcle_card_img" href="/ai/1273">
<img src="https://img.php.cn/upload/ai_manual/001/431/639/68b6dad229e35722.png" alt="Avatar AI">
</a>
<div class="aritcle_card_info">
<a href="/ai/1273">Avatar AI</a>
<p>AI成像模型,可以从你的照片中生成逼真的4K头像</p>
<div class="">
<img src="/static/images/card_xiazai.png" alt="Avatar AI">
<span>92</span>
</div>
</div>
<a href="/ai/1273" class="aritcle_card_btn">
<span>查看详情</span>
<img src="/static/images/cardxiayige-3.png" alt="Avatar AI">
</a>
</div>
</div>
<div class="section" data-key="2">
<h1>第二章</h1>
<p>这是第二章的主体内容。</p>
<div class="subsection" data-key="2.1">
<h2>第二章第一节</h2>
<p>本节详细阐述了子内容A。</p>
</div>
<div class="subsection" data-key="2.2">
<h2>第二章第二节</h2>
<p>本节详细阐述了子内容B。</p>
<div class="sub-subsection" data-key="2.2.1">
<h3>第二章第二节第一小节</h3>
<p>这是更深层次的细节。</p>
</div>
</div>
</div>
</body>
</html>Python代码实现:
import json
from bs4 import BeautifulSoup
def extract_structured_data_from_html(html_content):
"""
从
HTML内容中提取结构化数据,并转换为自定义JSON格式。
此函数递归处理嵌套的章节。
"""
soup = BeautifulSoup(html_content, 'html.parser')
# 定义一个递归函数来处理嵌套结构
def parse_section(element):
data_list = []
# 查找当前元素下的所有直接子章节
# 这里我们假设'section', 'subsection', 'sub-subsection'是层级结构
# 并且它们都包含一个'data-key'属性
# 遍历当前层级的直接子元素,寻找符合条件的“章节”
# 注意:这里需要根据实际HTML结构调整选择器
# 例如,如果所有层级都用同一个class(如'item'),则需要更复杂的逻辑判断嵌套
# 简化处理:查找当前element下的所有'div',并根据class或data-key判断层级
# 为了演示,我们假设直接子div是下一级
# 获取当前元素的所有文本内容(不包含子元素文本,需要更精确的控制)
# 或者,我们可以从标题标签中获取value
# 示例中,我们假设每个section/subsection/sub-subsection都有一个H标签作为标题
# 查找当前元素下的直接子section/subsection/sub-subsection
# 使用CSS选择器来获取直接子元素
# 获取当前元素的直接文本内容(排除子标签)
# current_value = ' '.join(element.find_all(text=True, recursive=False)).strip()
# 针对示例HTML结构进行解析
# 优先从H标签中提取标题作为value
title_tag = element.find(['h1', 'h2', 'h3'], recursive=False)
value_text = title_tag.get_text(strip=True) if title_tag else ""
# 获取当前层级的纯文本内容(不包含标题和子章节的文本)
# 找到所有直接的<p>标签,并连接它们的文本
paragraph_texts = [p.get_text(strip=True) for p in element.find_all('p', recursive=False)]
if paragraph_texts:
value_text += "\n" + "\n".join(paragraph_texts)
current_key = element.get('data-key')
children = []
# 查找当前元素下的直接子 div,这些 div 可能是下一级章节
# 这里的逻辑需要根据HTML的实际嵌套方式来确定
# 例如,如果子章节总是紧跟在父章节的直接子div中
# 查找所有直接子 div,并判断它们是否是章节
direct_child_sections = element.find_all('div', recursive=False)
for child_section in direct_child_sections:
if child_section.has_attr('data-key'): # 确保是带有data-key的章节元素
children.extend(parse_section(child_section)) # 递归处理子章节
if current_key:
data_list.append({
"key": current_key,
"value": value_text.strip(),
"child": children
})
return data_list
# 从body开始解析,查找所有顶层section
top_level_sections = soup.body.find_all('div', class_='section', recursive=False)
final_json_data = []
for section in top_level_sections:
final_json_data.extend(parse_section(section))
return final_json_data
# 读取HTML文件
html_file_path = "sample.html"
with open(html_file_path, "r", encoding="utf-8") as f:
html_data = f.read()
# 转换数据
output_structured_json = extract_structured_data_from_html(html_data)
# 将结果保存到JSON文件
output_json_file_path = "structured_output.json"
with open(output_json_file_path, "w", encoding="utf-8") as outfile:
json.dump(output_structured_json, outfile, indent=4, ensure_ascii=False)
print(f"结构化JSON已保存到:{output_json_file_path}")
print(json.dumps(output_structured_json, indent=4, ensure_ascii=False))预期的输出 (structured_output.json):
[
{
"key": "1",
"value": "第一章\n这是第一章的主要内容。\n可能还有其他描述。",
"child": []
},
{
"key": "2",
"value": "第二章\n这是第二章的主体内容。",
"child": [
{
"key": "2.1",
"value": "第二章第一节\n本节详细阐述了子内容A。",
"child": []
},
{
"key": "2.2",
"value": "第二章第二节\n本节详细阐述了子内容B。",
"child": [
{
"key": "2.2.1",
"value": "第二章第二节第一小节\n这是更深层次的细节。",
"child": []
}
]
}
]
}
]注意事项与最佳实践
- 了解HTML结构:在编写解析代码之前,务必仔细检查目标HTML文档的结构。了解标签的嵌套关系、类名、ID或自定义属性是成功提取数据的关键。
- 选择合适的解析器:BeautifulSoup支持多种解析器,如html.parser(Python内置)、lxml(速度快,功能强大)和html5lib(容错性好)。根据HTML的质量和性能要求选择。
- 精确选择器:使用find(), find_all(), select()方法时,尽量使用最精确的选择器来定位元素,避免意外捕获不相关的元素。CSS选择器(select())通常非常强大和灵活。
- 处理文本内容:.get_text(strip=True)方法可以获取元素的纯文本内容并去除首尾空白。如果需要保留内部的换行符或空格,可以调整参数。对于复杂的文本提取,可能需要遍历元素的contents或children。
- 错误处理:在实际应用中,HTML结构可能不总是完美的。在尝试访问元素的属性或文本之前,最好检查元素是否存在(例如,if element:)。
- 性能考虑:对于非常大的HTML文件,BeautifulSoup可能会占用较多内存。如果性能是关键因素,可以考虑使用lxml直接进行XPath或CSS选择器查询,或者分块处理HTML。
- 递归解析:对于嵌套的HTML结构,如示例中的章节和子章节,递归函数是处理层级关系的最佳方式。
总结
将HTML内容转换为自定义的JSON格式,不仅仅是简单的结构转换,更是一种语义提取和数据重构的过程。虽然html_to_json等库能提供DOM层面的JSON表示,但当需求涉及到去除标签、提取特定文本并构建自定义层级结构时,BeautifulSoup结合Python的灵活性,提供了强大而精确的解决方案。通过理解HTML结构、运用合适的选择器和递归处理方法,开发者可以高效地将非结构化的HTML数据转化为满足特定业务需求的结构化JSON数据。
以上就是Python HTML内容到自定义JSON结构的转换教程的详细内容,更多请关注其它相关文章!
# python
# html
# css
# 结构化
# 滁州网站建设外包公司
# 第二节
# 文档
# 本节
# 耿马网站优化
# 东宝网站建设费用
# seo技术培训规范
# 无锡营销推广合作公司招聘
# 通化网站关键词优化技巧
# 铁岭外包营销推广
# seo适合火 星
# seo优化策略知多少seo公司
# 推广博客网站
# 转换为
# 选择器
# 这是
# 第二章
# 自定义
# 递归
# 字符串解
# css选择器
# 递归函数
# html文件
# 工具
# app
# html5
# json
# js
相关栏目:
【
科技资讯46185 】
【
网络学院92790 】
相关推荐:
Win10如何开启蓝牙功能_Windows10找不到蓝牙开关解决方法
C++如何实现线程池_C++11手动实现一个简单的固定大小线程池
163邮箱官方主页登录 直达网易邮箱登录核心页面
QQ邮箱网页版入口 QQ邮箱官方邮箱登录通道
漫蛙2(台版)官方入口地址 漫蛙2(台版)正版漫画网页端
MongoDB Aggregation:在嵌套对象数组中精确匹配ObjectId
Tailwind CSS line-clamp 布局问题解析与修复指南
在哪找SublimeJ远程工具_SFTP插件配置教程
Django模型中自动计算可用余额的实现方法
在Pyomo中实现基于变量的条件约束:Big-M方法详解
Golang如何通过reflect操作map_Golang reflect map操作与遍历技巧
Python多线程中正确使用sigwait处理SIGALRM信号
红果短剧网页版官网入口 官方最新网址发布
免费抖音短视频入口_抖音网页版短视频免费通道
Golang如何安装Swagger工具_GoSwagger文档生成环境
Mac怎么锁定备忘录_Mac备忘录加密设置教程
天猫2025双十一0点秒杀攻略 天猫爆款抢购时间
C++如何打印当前代码行号与文件名_C++预定义宏FILE与LINE的使用
中兴BladeV30怎样用测距估书架层高_iPhone中兴BladeV30测距估书架层高【家装参考】
凉拌黄瓜怎么拌更入味 凉拌黄瓜简单家常做法
不会效仿卡普空!《铁拳》制作人澄清:不采取赛事付费|直播|
押井守高度称赞《辐射4》:玩了八年都停不下来!
2026春节假期时间安排 2026春节假日查询
jQuery Mask 插件中实现电话号码固定前导零的教程
深入理解J*a合成构造器:何时以及为何阻止其生成
谷歌浏览器一键优化方案_谷歌浏览器直达主页极速不卡版
汽水音乐在线版入口_汽水音乐网页播放手册
一加 Nord 5 隐私权限异常_一加 Nord 5 系统安全优化
Win11怎么用U盘重装系统 Win11制作启动盘并重装系统完整教程【详解】
J*aScript中高效清空DOM列表元素:解决for循环中断与任务管理问题
支付宝碰一碰设备是REDMI手机吗 博主拆机辟谣:处理器、内存都不一样
必由学官方平台入口 必由学在线课堂登录地址
css滚动动画效果怎么实现_使用Animate.css滚动触发动画类
poki网页游戏推荐_poki免费游戏平台入口
Log4j Console Appender性能瓶颈与高并发优化策略
圆通快递查询实时追踪 圆通物流包裹状态快速查看
Windows10怎么开启夜间模式 Windows10系统设置调整色温与亮度缓解夜间用眼疲劳【教程】
如何提高微信支付的安全性_微信支付安全防护与设置建议
J*a应用集成GitHub CLI与API认证指南
Node.js CSV 数据处理:基于字段值条件过滤整条记录的策略
《北京人工智能产业白皮书(2025)》发布:全年核心产值预计突破 4500 亿元
高德地图公交到站提醒失败如何解决 高德提醒权限设置
在命令行怎么运行html项目_命令行运行html项目方法【教程】
QQ邮箱网页版快速登录 QQ邮箱邮箱账号官方入口地址
UE5.7引擎表现爆炸优化无敌!5090跑4K稳定60FPS
c++中的const_cast和reinterpret_cast怎么用_c++四种类型转换
夸克浏览器图书入口 夸克手机浏览器阅读入口
解决 Vaadin 8 中大文件音频播放与定位时出现的 IOException
抖音网页版快捷访问 抖音网页版网页版入口操作教程
理解Python模块与全局变量的作用域管理


2025-11-22
浏览次数:次
返回列表
HTML内容中提取结构化数据,并转换为自定义JSON格式。
此函数递归处理嵌套的章节。
"""
soup = BeautifulSoup(html_content, 'html.parser')
# 定义一个递归函数来处理嵌套结构
def parse_section(element):
data_list = []
# 查找当前元素下的所有直接子章节
# 这里我们假设'section', 'subsection', 'sub-subsection'是层级结构
# 并且它们都包含一个'data-key'属性
# 遍历当前层级的直接子元素,寻找符合条件的“章节”
# 注意:这里需要根据实际HTML结构调整选择器
# 例如,如果所有层级都用同一个class(如'item'),则需要更复杂的逻辑判断嵌套
# 简化处理:查找当前element下的所有'div',并根据class或data-key判断层级
# 为了演示,我们假设直接子div是下一级
# 获取当前元素的所有文本内容(不包含子元素文本,需要更精确的控制)
# 或者,我们可以从标题标签中获取value
# 示例中,我们假设每个section/subsection/sub-subsection都有一个H标签作为标题
# 查找当前元素下的直接子section/subsection/sub-subsection
# 使用CSS选择器来获取直接子元素
# 获取当前元素的直接文本内容(排除子标签)
# current_value = ' '.join(element.find_all(text=True, recursive=False)).strip()
# 针对示例HTML结构进行解析
# 优先从H标签中提取标题作为value
title_tag = element.find(['h1', 'h2', 'h3'], recursive=False)
value_text = title_tag.get_text(strip=True) if title_tag else ""
# 获取当前层级的纯文本内容(不包含标题和子章节的文本)
# 找到所有直接的<p>标签,并连接它们的文本
paragraph_texts = [p.get_text(strip=True) for p in element.find_all('p', recursive=False)]
if paragraph_texts:
value_text += "\n" + "\n".join(paragraph_texts)
current_key = element.get('data-key')
children = []
# 查找当前元素下的直接子 div,这些 div 可能是下一级章节
# 这里的逻辑需要根据HTML的实际嵌套方式来确定
# 例如,如果子章节总是紧跟在父章节的直接子div中
# 查找所有直接子 div,并判断它们是否是章节
direct_child_sections = element.find_all('div', recursive=False)
for child_section in direct_child_sections:
if child_section.has_attr('data-key'): # 确保是带有data-key的章节元素
children.extend(parse_section(child_section)) # 递归处理子章节
if current_key:
data_list.append({
"key": current_key,
"value": value_text.strip(),
"child": children
})
return data_list
# 从body开始解析,查找所有顶层section
top_level_sections = soup.body.find_all('div', class_='section', recursive=False)
final_json_data = []
for section in top_level_sections:
final_json_data.extend(parse_section(section))
return final_json_data
# 读取HTML文件
html_file_path = "sample.html"
with open(html_file_path, "r", encoding="utf-8") as f:
html_data = f.read()
# 转换数据
output_structured_json = extract_structured_data_from_html(html_data)
# 将结果保存到JSON文件
output_json_file_path = "structured_output.json"
with open(output_json_file_path, "w", encoding="utf-8") as outfile:
json.dump(output_structured_json, outfile, indent=4, ensure_ascii=False)
print(f"结构化JSON已保存到:{output_json_file_path}")
print(json.dumps(output_structured_json, indent=4, ensure_ascii=False))