如何从Outlook邮件HTML表格提取数据并生成指定格式DataFrame?
解决Outlook邮件HTML跨列表格解析为5×5 DataFrame的问题
问题出在你的代码未处理HTML表格的colspan属性,导致解析时跨列单元格被当作单个单元格,与数据行的5列无法对齐,最终所有单元格被扁平化输出成1×24的结构。
完整修复代码
import win32com.client from bs4 import BeautifulSoup import pandas as pd # 1. 连接Outlook并获取目标邮件HTML内容 outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI") # 替换为你的目标文件夹路径(示例:收件箱下的"每周报表"文件夹) target_folder = outlook.GetDefaultFolder(6).Folders("每周报表") # 按接收时间倒序取最新邮件,如需遍历所有邮件可调整逻辑 messages = target_folder.Items messages.Sort("[ReceivedTime]", True) latest_msg = messages.GetFirst() html_content = latest_msg.HTMLBody # 2. 解析HTML表格并处理跨列逻辑 soup = BeautifulSoup(html_content, "html.parser") target_table = soup.find("table") # 假设仅存在一个目标表格,多表格需额外判断 target_col_count = 5 # 数据行的目标列数 table_rows = [] for tr in target_table.find_all("tr"): cells = tr.find_all(["th", "td"]) processed_row = [] for cell in cells: colspan = int(cell.get("colspan", 1)) cell_text = cell.get_text(strip=True) # 区分表头和数据单元格处理跨列:表头文本放首个单元格,其余补空;数据行直接保留文本 if cell.name == "th": processed_row.append(cell_text) processed_row += [""] * (colspan - 1) else: processed_row.append(cell_text) # 强制每行保持5列,多余截断、不足补空 processed_row = processed_row[:target_col_count] + [""] * max(0, target_col_count - len(processed_row)) table_rows.append(processed_row) # 3. 构建DataFrame并导出 df = pd.DataFrame(table_rows[1:], columns=table_rows[0]) print(f"生成的DataFrame形状:{df.shape}") # 应输出 (4,5),对应5×5结构(表头+4行数据) df.to_excel("weekly_report.xlsx", index=False)
关键修复说明
- 处理
colspan:手动展开跨列单元格,针对首列跨2列的表头,将文本放在第一列,第二列补空,确保表头行与数据行的5列结构对齐。 - 统一列数:强制每行保留5列,避免因表格结构不一致导致的列数混乱。
- 多表格适配:如果邮件存在多个表格,可通过表格内的特定关键词定位目标表格,示例:
# 定位包含指定表头文本的表格 for table in soup.find_all("table"): if "跨列表头" in table.get_text(): target_table = table break
内容的提问来源于stack exchange,提问作者killedbydeath
相关产品推荐
相关产品推荐

