我有多个pdf文件,我想提取一组特定的页面,其中每组页面是不同的每一个pdf文件。我已经创建了一个字典,其中键作为pdf文件名,值作为从每个pdf文件中提取的页面列表(显示为键)。我打算从相关的pdf文件中提取给定的页面,并将它们全部写入一个新的pdf文件中,以便我可以在这个最终文件上进行数据提取。我尝试过PyPDF4和FPDF,但到目前为止还没有joy给我一个很大的pdf和空白页,或者一个pdf只提取了1到2页,或者找不到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()发布于 2022-02-07 09:24:11
问题是你没有正确地迭代。请参阅代码中的注释,以更好地理解。
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 runhttps://stackoverflow.com/questions/71015913
复制相似问题