Python实现HTML表格转JSON:适配横向与纵向表格的优化方案求助
适配横向与纵向HTML表格转JSON的解决方案
你的核心问题在于原代码只针对“每行两个单元格组成键值对”的横向表格设计,而纵向表格存在表头行+多行数据、合并单元格(colspan/rowspan)的情况,直接按原逻辑拆分就会出现数据错位、格式混乱的问题。下面是我整理的改进方案,能同时完美适配两种表格结构:
改进后的完整代码
from bs4 import BeautifulSoup from pathlib import Path def parse_html_table(html_data): soup = BeautifulSoup(html_data, features="lxml") table = soup.find("table") if not table: return [] # 第一步:处理合并单元格,生成完整的二维表格数据 rows = table.find_all("tr") max_cols = 0 # 先计算表格最大列数,处理colspan for row in rows: cols_count = 0 for cell in row.find_all(["td", "th"]): cols_count += int(cell.get("colspan", 1)) if cols_count > max_cols: max_cols = cols_count # 初始化完整表格,填充空值 full_table = [] for row_idx, row in enumerate(rows): current_row = [""] * max_cols col_pos = 0 for cell in row.find_all(["td", "th"]): colspan = int(cell.get("colspan", 1)) rowspan = int(cell.get("rowspan", 1)) cell_text = cell.get_text(strip=True) # 填充当前行的colspan单元格 for c in range(colspan): if col_pos + c < max_cols: current_row[col_pos + c] = cell_text # 处理rowspan:给后续行的对应位置填充相同内容 for r in range(1, rowspan): target_row_idx = row_idx + r if target_row_idx < len(rows): # 确保后续行已初始化 while len(full_table) <= target_row_idx: full_table.append([""] * max_cols) if col_pos < max_cols: full_table[target_row_idx][col_pos] = cell_text col_pos += colspan full_table.append(current_row) # 第二步:过滤空行和全空单元格,清洗数据 cleaned_table = [] for row in full_table: cleaned_row = [cell for cell in row if cell] if cleaned_row: cleaned_table.append(cleaned_row) # 第三步:判断表格类型,转换为目标JSON格式 json_data = [] # 判断是否为横向表格:每行固定2个单元格,是键值对结构 is_horizontal = all(len(row) == 2 for row in cleaned_table) if is_horizontal: for row in cleaned_table: json_data.append({row[0]: row[1]}) else: # 纵向表格:第一行是表头,后续行是对应数据 if len(cleaned_table) < 2: return json_data headers = cleaned_table[0] # 转置表格,将列数据转为对应表头的行数据 transposed_data = list(zip(*cleaned_table[1:])) for idx, header in enumerate(headers): if idx >= len(transposed_data): continue values = list(transposed_data[idx]) # 单值存字符串,多值存列表 json_data.append({header: values if len(values) > 1 else values[0]}) return json_data # 测试调用 html_data = Path("Table2.html").read_text() result = parse_html_table(html_data) print(result)
核心逻辑说明
- 合并单元格处理:这是解决纵向表格混乱的关键——通过解析
colspan和rowspan属性,把合并的单元格内容填充到对应位置,生成无缺失的完整二维表格,避免数据错位。 - 表格类型自动判断:通过检查每行单元格数量是否固定为2,自动识别是横向键值对表格还是纵向表头+数据表格。
- 纵向表格转置处理:把纵向表格的列数据转成行,让每个表头对应整列的数据,生成你需要的数组格式。
- 数据清洗:过滤空行和空单元格,避免无用数据干扰最终输出。
测试结果
- 横向表格:输出完全符合你的预期格式。
- 纵向表格:输出与你要求的一致:
[ {'Pickup Location': 'Some Address'}, {'Description': 'Rubics cube'}, {'PLTS': ['1', '2']}, {'total weight': ['20', '60']}, {'L': ['40', '40']}, {'W': ['40', '40']}, {'H': ['40', '40']} ]
(如果需要统一表头大小写,可在代码里添加header.strip().title()之类的格式化处理)
内容的提问来源于stack exchange,提问作者user13354595




