PDF实验指导文档解析为DataFrame的技术问题及代码优化
解决PDF跨页提取实验内容并生成DataFrame的方案
核心思路
- 提取PDF所有页面的文本并记录对应页码
- 用正则定位所有
Laboratory work [数字]标记,确定每个实验的文本起止范围 - 合并跨页的实验文本片段,同时标记覆盖的页码范围
- 将整理好的实验数据转换为包含
Lab #、Lab content、page number的DataFrame
完整代码实现
import PyPDF2 import pandas as pd import re def extract_lab_content(pdf_path): # 存储每页的页码和对应文本(页码从1开始) page_texts = [] with open(pdf_path, 'rb') as file: reader = PyPDF2.PdfReader(file) for idx in range(len(reader.pages)): page = reader.pages[idx] text = page.extract_text() page_texts.append((idx + 1, text)) # 合并所有页面文本,同时记录每页文本在总文本中的结束位置(用于定位页码) full_text = "" page_boundaries = [] for _, text in page_texts: full_text += text + "\n" page_boundaries.append(len(full_text)) # 匹配所有实验起始标记 lab_matches = list(re.finditer(r'Laboratory work (\d+)', full_text)) lab_records = [] # 遍历每个实验标记,提取对应内容和页码范围 for i in range(len(lab_matches)): lab_num = lab_matches[i].group(1) # 实验内容的起始位置:标记结束后 start_idx = lab_matches[i].end() # 实验内容的结束位置:下一个标记的起始,或文本末尾 end_idx = lab_matches[i+1].start() if i < len(lab_matches)-1 else len(full_text) lab_content = full_text[start_idx:end_idx].strip() # 确定起始页码 start_page = 1 for pos in page_boundaries: if start_idx < pos: break start_page += 1 # 确定结束页码 end_page = 1 for pos in page_boundaries: if end_idx < pos: break end_page += 1 # 格式化页码范围 page_range = f"{start_page}-{end_page}" if start_page != end_page else f"{start_page}" lab_records.append({ 'Lab #': lab_num, 'Lab content': lab_content, 'page number': page_range }) return pd.DataFrame(lab_records) # 使用示例:替换为你的PDF路径 lab_df = extract_lab_content("lab_manual.pdf") print(lab_df)
关键步骤说明
- 全页文本提取:先把所有页面的文本整合,避免单页提取导致的跨页内容断裂
- 标记定位:用正则表达式精准捕获每个实验的起始点,明确实验内容的边界
- 页码匹配:通过记录每页文本的总长度边界,快速判断实验内容覆盖的页码区间
- 数据整理:将每个实验的编号、纯内容、页码范围打包成字典,最终转为DataFrame
优化建议
- 如果PyPDF2提取文本出现乱码或格式错乱,可替换为
pdfplumber库,它对复杂排版的PDF文本提取更精准 - 若实验标记存在格式变体(如大小写、额外空格),可修改正则为
r'[Ll]aboratory\s+[Ww]ork\s+(\d+)'以兼容更多情况
内容的提问来源于stack exchange,提问作者Mr. Timax
相关产品推荐
相关产品推荐

