我有多個 pdf 檔案,我想從中提取一組特定頁面,其中每個 pdf 檔案的每組頁面都不同。我創建了一個字典,其中鍵作為 pdf 檔案名,值作為要從每個 pdf 檔案中提取的頁面串列(顯示為鍵)。我打算從相關的 pdf 檔案中提取給定的頁面并將它們全部寫入一個新的 pdf 檔案,以便我可以對這個最終檔案進行資料提取。我已經嘗試過 PyPDF4 和 FPDF,但還沒有任何樂趣,因為它給了我一個帶有空白頁的大 pdf 或一個僅提取 1 或 2 頁的 pdf,或者找不到 pdf 物件的錯誤。我希望能就我的方法出錯的地方得到一些指導。下面是我的代碼:
import PyPDF4
from PyPDF4 import PdfFileReader, PdfFileWriter
for pdf,pgs in dic_11_1.items():
pdf=list(dic_11_1.keys())
pgs=list(dic_11_1.values())
for i in range(0,len(pdf)):
pages = pgs[i]
object = open(pdf[i],'rb')
pdfinput=PyPDF4.PdfFileReader(object,'rb')
if pdfinput.isEncrypted:
pdfinput.decrypt('')
else:
pdfinput
for p in pages:
page=pdfinput.getPage(p)
pdf_writer=PyPDF4.PdfFileWriter()
pdf_writer.addPage(page)
with open('F111.pdf',mode='wb') as output:
pdf_writer.write(output)
我得到的錯誤是“PdfReadError:找不到物件。”
當我使用以下代碼嘗試 FPDF 時,它運行了很長時間并給了我一個大的空 pdf 檔案:
from fpdf import FPDF
import os
for pdf,pgs in dic_11_1.items():
pdf_in=open(pdf,'rb')
inputpdf=PdfFileReader(pdf_in,'rb')
if inputpdf.isEncrypted:
inputpdf.decrypt('')
else:
inputpdf
for p in pgs:
content=inputpdf.getPage(p).extractText()
pdf = FPDF('P','mm','A4')
pdf.add_page()
pdf.set_font("arial", size = 10)
for text in content:
text2=text.encode('latin-1', 'replace').decode('latin-1')
pdf.write(10,text2)
pdf.ln(8)
pdf.close()
return_byte_string=pdf.output('F_11_1.pdf','S').encode('latin-1')
pdf_file=open('F_11_1.pdf','wb')
pdf_file.write(return_byte_string)
pdf_file.close()
任何指導將不勝感激。先感謝您
@SUTerliakov 提供的解決方案很棒,但只寫了頁面字典值串列中的最后一頁或最后一個檔案。通過代碼中的一個小縮進解決了它,這為我獲取了所有資料。再次感謝@SUTerliakov 讓我走上正確的道路!這是您調整后的代碼:
pdf_writer = PdfFileWriter()
open_files = []
try:
for filename, pgs in dic_11_1.items():
src = open(filename, 'rb')
open_files.append(src)
pdfinput = PdfFileReader(src, 'rb')
if pdfinput.isEncrypted:
pdfinput.decrypt('')
print(f'Extracting relevant pages from {filename} to central repository')
for p in pgs:
print(f'{filename} pg{str(p)}')
pdf_writer.addPage(pdfinput.getPage(p))
print(f'Writing {len(pgs)} pages to central file')
Stream=open('F_11_1.pdf','wb')
pdf_writer.write(Stream)
finally:
print('Closing Source File...')
for f in open_files:
f.close()
uj5u.com熱心網友回復:
好吧,問題是您沒有正確迭代。請參閱代碼中的注釋以更好地理解。
UPD。PyPDF4似乎只添加頁面參考,PdfFileWriter直到它實際寫入某個檔案。所以我們只能在最后關閉輸入源。因此,這種方法不適用于大檔案數(在 linux 上,它會受到限制,ulimit默認情況下它是 1024,所以我們只能打開 1000 個輸入檔案 1 個輸出檔案 3 個系統流 - stdin、stdout、stderr;這個限制可以放大ulimit -n <count>)。
from PyPDF4 import PdfFileReader, PdfFileWriter
sect_11_1 = [
('filename1.pdf', 0, 1),
('filename2.pdf', 0, 1),
]
# note pages are zero-numbered
dic_11_1 = {}
# if sect_11_1 is of another format
# [('filename', [0, 1]), ...]
# remove star below
for filename, *pages in sect_11_1:
dic_11_1.setdefault(filename, [])
dic_11_1[filename].extend(pages)
# if filenames are not repeated, you can do just
# dic_11_1 = dict(sect_11_1)
# you need single writer for all files, don't declare it in a loop
pdf_writer = PdfFileWriter()
open_files = []
try:
for filename, pages in dic_11_1.items():
# now you have filename and pages set to 'filename1.pdf' and [1, 3, 4]
# on second iteration they'll be set to 'filename2.pdf' and [0, 2, 3]
# ...
# don't use `object` as variable name: it's valid, but bad style
# (it shadows builtin `object`)
src = open(filename, 'rb')
open_files.append(src)
pdfinput = PdfFileReader(src, 'rb')
if pdfinput.isEncrypted:
pdfinput.decrypt('')
# you don't need empty `else`
for p in pages:
# you might want to use `p - 1` instead if your input was 1-numbered
page = pdfinput.getPage(p)
pdf_writer.addPage(page)
# when all pages are added, write to output
with open('F111.pdf',mode='wb') as output:
pdf_writer.write(output)
finally: # if something was wrong, do it anyway
for f in open_files:
f.close() # we shouldn't keep files open after program run
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/428378.html
