首页 > 解决方案 > 使用 Python PDFMiner 将多个 PDF 提取到文本文件的循环脚本

问题描述

感谢您的帮助。我发现这个示例脚本可以将 PDF 提取到文本文件: https ://gist.github.com/vinovator/c78c2cb63d62fdd9fb67

这行得通,它可能是我发现的最准确的提取。我想编辑它以循环浏览多个 PDF 并将它们写入多个文本文件,所有文件都与创建它们的 PDF 同名。我正在努力这样做,要么只写一个文本文件,要么覆盖我试图从中提取的 PDF。任何人都可以帮助我循环遍历单个文件夹中的所有 PDF 并将它们提取到与 PDF 同名的单个文本文件中吗?

在此先感谢您的帮助!

    import os
    from pdfminer.pdfparser import PDFParser
    from pdfminer.pdfdocument import PDFDocument
    from pdfminer.pdfpage import PDFPage
    # From PDFInterpreter import both PDFResourceManager and PDFPageInterpreter
    from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter
    from pdfminer.pdfdevice import PDFDevice
    # Import this to raise exception whenever text extraction from PDF is not allowed
    from pdfminer.pdfpage import PDFTextExtractionNotAllowed
    from pdfminer.layout import LAParams, LTTextBox, LTTextLine
    from pdfminer.converter import PDFPageAggregator

    base_path = "C://some_folder"

    my_file = os.path.join(base_path + "/" + "test_pdf.pdf")
    log_file = os.path.join(base_path + "/" + "pdf_log.txt")

    password = ""
    extracted_text = ""

    # Open and read the pdf file in binary mode
    fp = open(my_file, "rb")

    # Create parser object to parse the pdf content
    parser = PDFParser(fp)

    # Store the parsed content in PDFDocument object
    document = PDFDocument(parser, password)

    # Check if document is extractable, if not abort
    if not document.is_extractable:
        raise PDFTextExtractionNotAllowed

    # Create PDFResourceManager object that stores shared resources such as fonts or images
    rsrcmgr = PDFResourceManager()

    # set parameters for analysis
    laparams = LAParams()

    # Create a PDFDevice object which translates interpreted information into desired format
    # Device needs to be connected to resource manager to store shared resources
    # device = PDFDevice(rsrcmgr)
    # Extract the decive to page aggregator to get LT object elements
    device = PDFPageAggregator(rsrcmgr, laparams=laparams)

    # Create interpreter object to process page content from PDFDocument
    # Interpreter needs to be connected to resource manager for shared resources and device 
    interpreter = PDFPageInterpreter(rsrcmgr, device)

    # Ok now that we have everything to process a pdf document, lets process it page by page
    for page in PDFPage.create_pages(document):
         # As the interpreter processes the page stored in PDFDocument object
         interpreter.process_page(page)
         # The device renders the layout from interpreter
         layout = device.get_result()
         # Out of the many LT objects within layout, we are interested in LTTextBox and LTTextLine
         for lt_obj in layout:
             if isinstance(lt_obj, LTTextBox) or isinstance(lt_obj, LTTextLine):
                   extracted_text += lt_obj.get_text()
        
    #close the pdf file
    fp.close()

    # print (extracted_text.encode("utf-8"))
        
    with open(log_file, "wb") as my_log:
        my_log.write(extracted_text.encode("utf-8"))
    print("Done !!")

标签: pythonloopspdfpdfminer

解决方案


假设您具有以下目录结构:

script.py
pdfs
  ├─a.pdf
  ├─b.pdf
  └─c.pdf
txts

script.py你的 Python 脚本在哪里,pdfs是一个包含 PDF 文档的文件夹,txts是一个空文件夹,提取的文本文件应该放在哪里。

我们可以使用它pathlib.Path.glob来发现给定目录中所有 PDF 文档的路径。txts我们遍历路径,并为每个路径打开相应的 PDF 文档,解析它,提取文本并将文本保存在文件夹中的文本文档(同名)中。

def main():

    from pathlib import Path

    from pdfminer.pdfparser import PDFParser
    from pdfminer.pdfdocument import PDFDocument
    from pdfminer.pdfpage import PDFPage
    from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter
    from pdfminer.pdfdevice import PDFDevice
    from pdfminer.layout import LAParams, LTTextBox, LTTextLine
    from pdfminer.converter import PDFPageAggregator

    for path in Path("pdfs").glob("*.pdf"):
        with path.open("rb") as file:
            parser = PDFParser(file)
            document = PDFDocument(parser, "")
            if not document.is_extractable:
                continue

            manager = PDFResourceManager()
            params = LAParams()

            device = PDFPageAggregator(manager, laparams=params)
            interpreter = PDFPageInterpreter(manager, device)

            text = ""

            for page in PDFPage.create_pages(document):
                interpreter.process_page(page)
                for obj in device.get_result():
                    if isinstance(obj, LTTextBox) or isinstance(obj, LTTextLine):
                        text += obj.get_text()
        with open("txts/{}.txt".format(path.stem), "w") as file:
            file.write(text)
    return 0


if __name__ == "__main__":
    import sys
    sys.exit(main())

推荐阅读