0

我正在解析显示多个不同货物运输信息的 PDF 文件。数据包括地址、商品金额等。我已经成功提取出构成每个文件实质的文本字符串。文件的呈现方式相对一致,但不像 HTML 或 XML 那样易于定位数据。首先,我正在尝试提取项目数量。在文本中,子字符串“<code>TOTAL BOXES:”有多个实例。每一个之后,都有一个整数(所以它看起来像这样:“<code>TOTAL BOXES: 3”)

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

  1. 找到关键短语“<code>TOTAL BOXES:”的实例
  2. 查找“<code>TOTAL BOXES:”的每个实例的索引</li>
  3. 使用这个子字符串中最后一个字符的索引——在这种情况下是“<code>:”——到“<code>向前移动”2个字符索引位置来拉数据。

我认为可能有更优雅的解决方案,我很高兴听到它们。但现在我选择方法的主要绊脚石是:

我能够将关键短语的每个索引作为列表中的一个项目返回。然后我将 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])]
4

1 回答 1

0

让我总结一下我对您的问题的理解。您有一个名为 的长字符串raw_data。您想从此字符串中分割某些 2 字符序列。这些切片开始的索引存储在列表中instance_begin。如果这是正确的,这是一个单行解决方案:

box = [raw_data[i:i+2] for i in instance_begin]

该语句的末尾box是所需的两字符字符串列表。该列表instance_end不是必需的。抱歉,如果我仍然误解了您的问题。

于 2015-08-10T20:41:02.593 回答