如何用Python按指定宽度拆分双栏PDF并提取文本?
解决双栏PDF按栏提取文本的问题
我完全懂你的困扰——PyPDF2默认是按PDF内部的内容流顺序提取文本,双栏布局下会先把左栏内容全读完再读右栏,结果文本串成一团,根本没法按标题拆分。既然你已经明确了栏宽和页面尺寸,用页面裁剪+逐栏提取的方法就能完美解决这个问题,下面是具体的实现思路和代码:
核心思路
PDF的文本提取顺序不遵循视觉排版,但我们可以通过裁剪页面,把原本的双栏页拆成两个单栏的“虚拟页面”,再分别提取每栏的文本。这样就能得到左栏和右栏各自独立的内容,之后按标题拆分就轻松多了。
先明确PDF的坐标规则:原点在页面左下角,单位是用户单位(1/72英寸),所以第一步要把你给出的英寸尺寸转换成这个单位方便计算。
实现步骤
- 单位转换:将英寸尺寸乘以72,转换成PDF标准的用户单位。
- 定义裁剪区域:根据第一栏宽度,分别设置左栏和右栏的裁剪矩形(格式为
[left, bottom, right, top])。 - 裁剪并提取文本:遍历PDF的每一页,裁剪出左栏和右栏的虚拟页,分别提取文本。
- 后续处理:拿到分栏后的文本,就可以按标题拆分或按需合并内容了。
完整代码示例
from PyPDF2 import PdfReader, PdfWriter def extract_two_column_text(pdf_path, left_col_width_inch=2.26, page_width_inch=8, page_height_inch=11): # 转换为PDF标准用户单位(1单位 = 1/72英寸) user_unit = 72 left_col_width = left_col_width_inch * user_unit page_width = page_width_inch * user_unit page_height = page_height_inch * user_unit # 读取目标PDF reader = PdfReader(pdf_path) column_text_results = [] # 遍历每一页进行分栏处理 for page_idx, page in enumerate(reader.pages): # 定义左栏裁剪区域:[左边界, 下边界, 右边界, 上边界] left_crop_rect = [0, 0, left_col_width, page_height] # 定义右栏裁剪区域(左边界从左栏宽度开始) right_crop_rect = [left_col_width, 0, page_width, page_height] # 裁剪左栏页面并提取文本 left_column_page = page.crop(left_crop_rect) left_column_text = left_column_page.extract_text().strip() # 裁剪右栏页面并提取文本 right_column_page = page.crop(right_crop_rect) right_column_text = right_column_page.extract_text().strip() # 存储当前页的分栏文本结果 column_text_results.append({ "page_number": page_idx + 1, "left_column": left_column_text, "right_column": right_column_text }) return column_text_results # 使用示例 if __name__ == "__main__": target_pdf = "your_two_column_document.pdf" extracted_text = extract_two_column_text(target_pdf) # 打印测试结果 for page_data in extracted_text: print(f"=== 第 {page_data['page_number']} 页 ===") print("左栏文本:\n", page_data['left_column']) print("\n右栏文本:\n", page_data['right_column']) print("-" * 60)
注意事项
- 栏间距微调:如果你的PDF左栏和右栏之间有空白间距,可以调整右栏的左边界值(比如
left_col_width + gap_inch * 72),根据实际排版微调即可。 - 文本顺序验证:大部分情况下裁剪后提取的文本顺序是正确的,但如果遇到特殊排版的PDF,可能需要检查提取结果,微调裁剪区域的边界值。
- 标题拆分:现在你已经有了左栏和右栏的独立文本,可以通过匹配左栏中的标题关键词,再对应提取右栏的内容,轻松实现按标题拆分的需求。
内容的提问来源于stack exchange,提问作者ericlighthofmann
相关产品推荐
相关产品推荐

