如何用Python提取PDF中的粗体文本、普通文本及表格?
解决PDF粗体文本提取与表格解析方案
问题核心
你当前使用的PyPDF2仅能提取纯文本,无法识别粗体格式属性,这是无法完成粗体列名提取的关键障碍。建议改用PyMuPDF(fitz库)来获取带格式的文本信息,表格提取可结合PyMuPDF内置功能或tabula-py(针对结构化表格)。
分步实现代码
1. 安装依赖工具
pip install pymupdf pandas tabula-py
2. 提取粗体列名及对应详情
import fitz # PyMuPDF import pandas as pd def extract_bold_content(pdf_path): doc = fitz.open(pdf_path) data = {} current_column = None for page in doc: # 获取页面带格式的文本块 text_blocks = page.get_text("dict")["blocks"] for block in text_blocks: if "lines" not in block: continue for line in block["lines"]: for span in line["spans"]: text = span["text"].strip() if not text: continue # 判断是否为粗体:字体名含Bold标记,或flags中粗体位激活 is_bold = "Bold" in span["font"] or (span["flags"] & 16) if is_bold: # 记录新的粗体列名 current_column = text data[current_column] = "" elif current_column is not None: # 将非粗体文本追加到当前列的详情中 data[current_column] += text + " " # 转换为单行DataFrame return pd.DataFrame([data])
3. 提取PDF中的表格数据
import tabula def extract_pdf_tables(pdf_path): # 自动识别所有页面的表格,返回DataFrame列表 tables = tabula.read_pdf(pdf_path, pages="all", multiple_tables=True) # 合并多个表格(可根据实际格式调整合并逻辑) if tables: return pd.concat(tables, ignore_index=True) return pd.DataFrame()
4. 整合数据并批量处理
def process_single_pdf(pdf_path): # 提取粗体对应的详情数据 detail_df = extract_bold_content(pdf_path) # 提取表格数据 table_df = extract_pdf_tables(pdf_path) # 保存结果到Excel(分sheet存储) output_name = f"{pdf_path.split('.')[0]}_processed.xlsx" with pd.ExcelWriter(output_name) as writer: detail_df.to_excel(writer, sheet_name="粗体列详情", index=False) table_df.to_excel(writer, sheet_name="表格数据", index=False) # 单文件测试 process_single_pdf("246427 postop note.pdf") # 批量处理文件夹内所有PDF import os target_folder = "./your_pdf_folder" for file_name in os.listdir(target_folder): if file_name.lower().endswith(".pdf"): full_path = os.path.join(target_folder, file_name) process_single_pdf(full_path)
注意事项
- 粗体判断逻辑:部分PDF的粗体字体命名可能不含"Bold",可仅用
span["flags"] & 16判断(PyMuPDF中flags第5位对应粗体属性)。 - 表格提取:若PDF表格为图片格式,需额外结合OCR工具(如pytesseract)处理;格式统一的结构化表格用上述代码即可直接提取。
- 批量处理时,可根据需求调整数据整合逻辑(如将所有文件的粗体详情合并为一个大DataFrame)。
内容的提问来源于stack exchange,提问作者user19709842
相关产品推荐
相关产品推荐

