遍历文件夹和子文件夹并合并 pdf

Loop through folder and subfolders and merge pdf

我尝试创建一个脚本来遍历父文件夹和子文件夹并将所有 pdf 合并为一个。下面是我到目前为止写的代码,但我不知道如何将它们组合成一个脚本。

参考: Merge PDF files

第一个功能是遍历父文件夹下的所有子文件夹并获取每个 pdf 的路径列表。

import os
from PyPDF2 import PdfFileMerger

root = r"folder path"
path = os.path.join(root, "folder path")

def list_dir():
    for path,subdirs,files in os.walk(root):
        for name in files:
            if name.endswith(".pdf") or name.endswith(".ipynb"):
                print (os.path.join(path,name))

            
            

其次,我创建了一个列表,将所有路径附加到子文件夹中的 pdf 文件,并合并到一个组合文件中。在这一步,我被告知:

TypeError: listdir: path should be string, bytes, os.PathLike or None, not list

root_folder = []
root_folder.append(list_dir())
    
def pdf_merge():
    
    merger = PdfFileMerger()    
    allpdfs = [a for a in os.listdir(root_folder)]

    
    for pdf in allpdfs:
        merger.append(open(pdf,'rb'))
        
    with open("Combined.pdf","wb") as new_file:
        merger.write(new_file)

pdf_merge()

为了避免错误并将两个函数组合在一起,我应该在哪里修改代码以及修改什么?

首先你必须创建函数来创建包含所有文件的列表和return它。

def list_dir(root):
    result = []
    
    for path, dirs, files in os.walk(root):
        for name in files:
            if name.lower().endswith( (".pdf", ".ipynb") ):
                result.append(os.path.join(path, name))
                
    return result

我还使用 .lower() 来捕捉像 .PDF.

这样的扩展

endswith() 可以使用所有扩展名的元组。

获取外部值作为参数很好 - list_dir(root) 而不是 list_dir()


以后您可以使用 as

allpdfs = list_dir("folder path")

def pdf_merge(root):
    
    merger = PdfFileMerger()    
    allpdfs = list_dir(root)
    
    for pdf in allpdfs:
        merger.append(open(pdf, 'rb'))
        
    with open("Combined.pdf", 'wb') as new_file:
        merger.write(new_file)

pdf_merge("folder path")

编辑:

如果第一个功能也得到扩展,它可能会更加通用

import os

def list_dir(root, exts=None):
    result = []
    
    for path, dirs, files in os.walk(root):
        for name in files:
            if exts and not name.lower().endswith(exts):
               continue 

            result.append(os.path.join(path, name))
                
    return result

all_files  = list_dir('folder_path')
all_pdfs   = list_dir('folder_path', '.pdf')
all_images = list_dir('folder_path', ('.png', '.jpg', '.gif'))

print(all_files)
print(all_pdfs)
print(all_images)

编辑:

对于单个扩展你也可以这样做

improt glob

all_pdfs = glob.glob('folder_path/**/*.pdf', recursive=True)

需要 **recursive=True 才能在子文件夹中搜索。