Python结构化PDF课程表解析求助:提取数据为字典列表
结构化PDF课程表解析实现方案
核心问题分析
你之前用PyPDF2、tabula-py、Camelot提取数据混乱,大概率是因为PDF表格存在合并单元格、不规则布局,而默认参数没适配这类场景。下面给出两种针对性的实现方案,优先推荐pdfplumber(对布局细节支持更好)。
方案一:使用pdfplumber解析原生结构化PDF
pdfplumber能精准获取PDF的文本位置、单元格边界,适合处理带合并单元格的课程表。
步骤1:安装依赖
pip install pdfplumber
步骤2:代码实现
import pdfplumber def parse_timetable(pdf_path): timetable_data = [] # 定义字段顺序,和你的课程表列对应 fields = ["日期", "时段", "教职工", "教室", "课程类型", "开始时间", "结束时间"] with pdfplumber.open(pdf_path) as pdf: for page in pdf.pages: # 提取表格,设置参数识别合并单元格 table = page.extract_table({ "vertical_strategy": "lines", "horizontal_strategy": "lines", "intersection_tolerance": 5 }) if not table: continue # 处理合并单元格填充(以日期列为例,假设日期是合并单元格,跨多行) current_date = "" for row in table[1:]: # 跳过表头行 # 填充合并的日期 if row[0].strip(): current_date = row[0].strip() else: row[0] = current_date # 转换为字典,处理空值 item = dict(zip(fields, [cell.strip() if cell else "" for cell in row])) # 标记空时段:判断核心字段是否为空(比如教职工、课程类型都为空) if not item["教职工"] and not item["课程类型"]: item["空时段"] = True else: item["空时段"] = False timetable_data.append(item) return timetable_data # 调用示例 if __name__ == "__main__": result = parse_timetable("你的课程表.pdf") for idx, item in enumerate(result[:5]): # 打印前5条测试 print(f"时段{idx+1}: {item}")
关键技巧
- 合并单元格处理:通过跟踪前一行的非空值,填充当前行的空单元格(比如日期列通常合并,跨多个时段)
- 空时段判断:根据业务逻辑定义空时段(比如教职工、课程类型同时为空即可判定)
- 参数调整:如果表格线条不清晰,可调整
intersection_tolerance值(越大越容易识别线条交点)
方案二:调整Camelot参数适配
如果坚持用Camelot,针对合并单元格和不规则表格,调整flavor和split_text参数:
import camelot def parse_with_camelot(pdf_path): # 根据PDF类型选flavor:lattice适合带清晰线条的表格,stream适合无线条的表格 tables = camelot.read_pdf(pdf_path, flavor='lattice', split_text=True, pages='all') timetable_data = [] fields = ["日期", "时段", "教职工", "教室", "课程类型", "开始时间", "结束时间"] for table in tables: df = table.df # 处理合并单元格(Camelot会把合并单元格的内容放在第一行,后续行对应位置为空) df = df.fillna(method='ffill') # 向前填充空值 # 转换为字典列表 for _, row in df.iterrows(): item = dict(zip(fields, row.str.strip())) item["空时段"] = not item["教职工"] and not item["课程类型"] timetable_data.append(item) return timetable_data
额外注意事项
- 如果是扫描版PDF(图片转的PDF),上述方案无效,需要结合OCR工具,比如
pytesseract+pdf2image,先把PDF转成图片,再识别表格内容 - 测试时先打印提取的原始表格数据,确认表头和行的对应关系,再调整字段顺序和填充逻辑
内容的提问来源于stack exchange,提问作者Denver
相关产品推荐
相关产品推荐

