文档标题
第一章
这是第一章的主要内容。
可能还有其他描述。
第二章
这是第二章的主体内容。
第二章第一节
本节详细阐述了子内容A。
第二章第二节
本节详细阐述了子内容B。
第二章第二节第一小节
这是更深层次的细节。
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 ""
# 获取当前层级的纯文本内容(不包含标题和子章节的文本)
# 找到所有直接的标签,并连接它们的文本
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))
[
{
"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": []
}
]
}
]
}
]