使用文本索引从PDF文件中提取特定数据以找到

时间:2015-08-08 04:40:00

标签: python regex pdf pdfminer

我正在解析PDF文件,显示多个不同货物的信息。数据包括地址,商品数量等。我已经成功地提取了构成每个文件实质的文本字符串。文件在其演示文稿中相对一致,但不提供轻松定位HTML或XML等数据。首先,我试图拉出一些物品。在文本中,子字符串“TOTAL BOXES:”有多个实例。在每个之后,有一个整数(所以它看起来像这样:“TOTAL BOXES: 3”)

我的方法,如下面的代码(一直在底部)所示,是:

  1. 找到关键短语“TOTAL BOXES:
  2. 的实例
  3. 查找“TOTAL BOXES:
  4. 的每个实例的索引
  5. 使用此子字符串中最后一个字符的索引 - 在这种情况下为“:” - 用于“move forward”2个字符索引位置来提取数据。
  6. 我认为可能有更优雅的解决方案,我很高兴听到它们。但是现在我采用我选择的方法的主要障碍是:

    我能够将关键短语的每个索引作为列表中的项返回。然后我将2添加到该索引以获取“后端”索引。我现在知道文本中提供目标数据的确切索引或每个位置。每个索引都存储为我的变量instance_begin下的列表项。

    这是我的代码崩溃的地方,我的新生儿闪耀着光芒。为了获取数据,我这样做:

    用于instance_begin中的框:

    box = raw_data[(instance_begin[box]):(instance_end[box])]
    

    返回异常:

      

    TypeError:列表索引必须是整数,而不是列表

    帮助表示赞赏。

    代码:

    from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter
    from pdfminer.converter import TextConverter
    from pdfminer.layout import LAParams
    from pdfminer.pdfpage import PDFPage
    from cStringIO import StringIO
    from re import findall, finditer
    
    path = "/file.pdf"
    
    def convert_pdf_to_txt(path):
        rsrcmgr = PDFResourceManager()
        retstr = StringIO()
        codec = 'utf-8'
        laparams = LAParams()
        device = TextConverter(rsrcmgr, retstr, codec=codec, laparams=laparams)
        fp = file(path, 'rb')
        interpreter = PDFPageInterpreter(rsrcmgr, device)
        password = ""
        maxpages = 0
        caching = True
        pagenos=set()
    
        for page in PDFPage.get_pages(fp, pagenos, maxpages=maxpages, password=password,caching=caching, check_extractable=True):
            interpreter.process_page(page)
    
        text = retstr.getvalue()
    
        fp.close()
        device.close()
        retstr.close()
        return text
    
    raw_data = convert_pdf_to_txt(path)
    
    key_phrase = "TOTAL BOXES:"
    
    instance_begin = [i.end() for i in re.finditer(key_phrase, raw_data)]
    
    instance_end = [(i + 2) for i in instance_begin]
    
    box = raw_data[(instance_begin[box]):(instance_end[box])]
    

1 个答案:

答案 0 :(得分:0)

让我总结一下我对你的问题的理解。你有一个名为 ID DOG CAT FISH CRANE PIG SHARK DEER 1 1 0 1 0 NA NA NA NA 2 2 0 1 0 NA NA NA NA 3 3 1 1 1 NA NA NA NA 4 4 1 1 0 NA NA NA NA 5 5 0 0 1 NA NA NA NA 的长字符串。您想要从此字符串中剪切某些2个字符的序列。这些切片开始的索引存储在列表raw_data中。如果这是正确的,这是一个单行解决方案:

instance_begin

在此语句的末尾,box = [raw_data[i:i+2] for i in instance_begin] 是所需的双字符字符串列表。列表box不是必需的。抱歉,如果我仍然误解你的问题。