如何在Python3中使用PyPDF2仅提取PDF裁剪区域内的文本
问题:如何真正删除PDF页面部分内容而非仅裁剪?
你需要将PDF页面拆分为两半并提取每一半的文本,但使用PyPDF2裁剪页面后,提取文本仍会获取到裁剪区域外的内容。你的裁剪和文本提取代码如下:
裁剪代码
inputFile = open(PDF_NAME, "rb") input1 = PyPDF2.PdfFileReader(inputFile) output = PyPDF2.PdfFileWriter() numPages = input1.getNumPages() for i in range(numPages): page = input1.getPage(i) page.cropBox.lowerRight = (page.cropBox.lowerRight[0]/2, 0) output.addPage(page) out_f = open("output.pdf", "wb") output.write(out_f) out_f.close()
文本提取代码
f = open(PDF_NAME, 'rb') pdfReader = PyPDF2.PdfFileReader(f) pageTexts = [] for i in range(pdfReader.numPages): pageObj = pdfReader.getPage(i) pageText = pageObj.extractText() pageTexts.append(pageText) f.close()
你的推测完全正确:PyPDF2的cropBox仅修改页面的显示区域,底层的文本内容并没有被真正删除,所以提取文本时仍会拿到全部内容。
解决方案:使用PyMuPDF真正处理页面内容
PyMuPDF(又称fitz)可以精准控制页面内容,不管是提取指定区域文本,还是真正删除页面部分内容,都能满足需求。
方法1:直接提取指定区域的文本(无需修改原PDF)
如果仅需要获取左右两半的文本,不需要生成修改后的PDF,直接针对区域提取即可:
import fitz PDF_NAME = "your_file.pdf" doc = fitz.open(PDF_NAME) left_texts = [] right_texts = [] for page in doc: # 获取页面整体尺寸 page_rect = page.rect # 定义左半页区域:从左边缘到页面宽度中点 left_rect = fitz.Rect(0, 0, page_rect.width/2, page_rect.height) # 定义右半页区域:从页面宽度中点到右边缘 right_rect = fitz.Rect(page_rect.width/2, 0, page_rect.width, page_rect.height) # 提取对应区域的文本 left_texts.append(page.get_text(clip=left_rect)) right_texts.append(page.get_text(clip=right_rect)) doc.close() # 保存提取结果 with open("left_texts.txt", "w", encoding="utf-8") as f: f.write("\n".join(left_texts)) with open("right_texts.txt", "w", encoding="utf-8") as f: f.write("\n".join(right_texts))
方法2:生成真正删除部分内容的PDF
如果需要生成裁剪后且内容彻底移除的PDF,可通过红印删除功能实现:
import fitz PDF_NAME = "your_file.pdf" OUTPUT_LEFT = "left_pages.pdf" OUTPUT_RIGHT = "right_pages.pdf" # 生成仅保留左半部分的PDF doc_left = fitz.open(PDF_NAME) for page in doc_left: page_rect = page.rect # 标记要删除的右半区域 delete_rect = fitz.Rect(page_rect.width/2, 0, page_rect.width, page_rect.height) page.add_redact_annot(delete_rect) page.apply_redactions() # 同步设置裁剪框(确保显示范围正确) page.set_cropbox(fitz.Rect(0, 0, page_rect.width/2, page_rect.height)) doc_left.save(OUTPUT_LEFT) doc_left.close() # 生成仅保留右半部分的PDF doc_right = fitz.open(PDF_NAME) for page in doc_right: page_rect = page.rect # 标记要删除的左半区域 delete_rect = fitz.Rect(0, 0, page_rect.width/2, page_rect.height) page.add_redact_annot(delete_rect) page.apply_redactions() page.set_cropbox(fitz.Rect(page_rect.width/2, 0, page_rect.width, page_rect.height)) doc_right.save(OUTPUT_RIGHT) doc_right.close()
说明
get_text(clip=rect)方法会精准提取指定矩形内的文本,完全不会包含区域外内容。add_redact_annot配合apply_redactions会真正删除标记区域的内容,生成的PDF中该部分文本彻底消失,后续提取也不会再获取到。
内容的提问来源于stack exchange,提问作者Dean Ogle
相关产品推荐
相关产品推荐

