即使出现错误,也要确保循环遍历每个文件

Ensure loop runs through every file even when errors are raised

我正在遍历文件夹中的一堆 pdf,解析它们的内容并将其附加到列表中。 它适用于 pdf 文件的子集。我不想手动删除一些 pdf,运行 代码,然后再添加一些到 运行,直到我发现有故障的 pdf。由于某些 pdf 无法打开或内容可能已损坏,我做了以下操作以确保循环 运行s 通过: check_extractable (如果 pdf 不可提取,pdfminer 应该抛出错误)是方法内部 class (PDFTextExtractionNotAllowed) 可以阻止它尝试打开 pdf 但实际上不能

问题: 我需要做什么才能使代码保持 运行ning 即使有无法打开或没有内容的 pdf (假设这就是为什么在代码中的特定点抛出错误的原因)

import pdfminer
from pdfminer.pdfpage import PDFPage, PDFTextExtractionNotAllowed
import os
import io
from io import StringIO
from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter
from pdfminer.converter import TextConverter, PDFPageAggregator
from pdfminer.layout import LAParams, LTTextBox, LTFigure, LTImage, 
LTTextLine, LTTextContainer, LTChar, LTTextBoxHorizontal
from pdfminer.pdfpage import PDFPage, PDFTextExtractionNotAllowed
from pdfminer.pdfdocument import PDFDocument
from pdfminer.pdfparser import PDFParser, PDFSyntaxError

directory = 'C:/Users/'
data = []
for file in os.listdir(directory):
    if not file.endswith(".pdf"):
        continue
    fake_file_handle = io.StringIO()


    with open(os.path.join(directory, file), 'rb') as fh:
        resource_manager = PDFResourceManager()
        laparams = LAParams(line_margin = 0.6)
        device = PDFPageAggregator(resource_manager, laparams = laparams)
        page_interpreter = PDFPageInterpreter(resource_manager, device)

        positions = []
        raw_text = []
        for page in PDFPage.get_pages(fh, caching=True, check_extractable=True):
            page_interpreter.process_page(page)
            text = fake_file_handle.getvalue()
            layout = device.get_result()
            for lobj in layout:
                
                if isinstance(lobj, LTTextContainer) or isinstance(lobj, LTTextBox) or isinstance(lobj, pdfminer.layout.LTTextBoxHorizontal):
                    coord, word = int(lobj.bbox[1]), lobj.get_text().strip()
                    raw_text.append([coord, word])

                    for text_line in lobj:
                        for character in text_line:
                            if isinstance(character, LTChar):
                                if character.matrix[0]>0 :
                                    position = character.bbox 
                        positions.append(position)

                # if it's a container, recurse
                elif isinstance(lobj, LTFigure):
                    pass

        # extract elements below y0=781 und above y0=57
        text_pos = []
        maxFontpos = 780
        minFontpos = 58
        for coord, word in raw_text:
            if coord <= maxFontpos and coord >= minFontpos:
                text_pos.append(word)
            else:
                pass
 
        try:
            wap = text_pos[0]
        except:
            pass
        
    data.append([text_pos, wap])
    fake_file_handle.close()

具体错误抛出在

---> 28                         for character in text_line:
     29                             if isinstance(character, LTChar):
     30                                 if character.matrix[0]>0 :

TypeError: 'LTChar' object is not iterable

如果这只是一个快速而肮脏的脚本,我建议将整个 with 块包围在一个通用的 try/except 中。通常你不想只是盲目地 except/catch 例外而不指定你正在寻找什么类型,以防发生你不期望的不同 exception/error ,但在这种情况下我认为它会是好的:

from pdfminer.pdfpage import PDFPage, PDFTextExtractionNotAllowed

directory = 'C:/Users/'
data = []
for file in os.listdir(directory):
    if not file.endswith(".pdf"):
        continue
    fake_file_handle = io.StringIO()

    try:
        with open(os.path.join(directory, file), 'rb') as fh:
            resource_manager = PDFResourceManager()
            laparams = LAParams(line_margin = 0.6)
            device = PDFPageAggregator(resource_manager, laparams = laparams)
            page_interpreter = PDFPageInterpreter(resource_manager, device)

            positions = []
            raw_text = []
            for page in PDFPage.get_pages(fh, caching=True, check_extractable=True):
                page_interpreter.process_page(page)
                text = fake_file_handle.getvalue()
                layout = device.get_result()
                for lobj in layout:
                
                    if isinstance(lobj, LTTextContainer) or isinstance(lobj, LTTextBox) or isinstance(lobj, pdfminer.layout.LTTextBoxHorizontal):
                        coord, word = int(lobj.bbox[1]), lobj.get_text().strip()
                        raw_text.append([coord, word])

                        for text_line in lobj:
                            for character in text_line:
                                if isinstance(character, LTChar):
                                    if character.matrix[0]>0 :
                                        position = character.bbox  # font-positon
                            positions.append(position)

                    # if it's a container, recurse
                    elif isinstance(lobj, LTFigure):
                        pass

            # extract elements below y0=781 und above y0=57
            text_pos = []
            maxFontpos = 780
            minFontpos = 58
            for coord, word in raw_text:
                if coord <= maxFontpos and coord >= minFontpos:
                    text_pos.append(word)
                else:
                    pass
 
            try:
                wap = text_pos[0]
            except:
                pass
    except:
        continue # Move on to next loop iteration

    data.append([text_pos, wap])
    fake_file_handle.close()