我正在解析显示多个不同货物运输信息的 PDF 文件。数据包括地址、商品金额等。我已经成功提取出构成每个文件实质的文本字符串。文件的呈现方式相对一致,但不像 HTML 或 XML 那样易于定位数据。首先,我正在尝试提取项目数量。在文本中,子字符串“<code>TOTAL BOXES:”有多个实例。每一个之后,都有一个整数(所以它看起来像这样:“<code>TOTAL BOXES: 3”)
我的方法,如下面的代码所示(一直在底部),一直是:
- 找到关键短语“<code>TOTAL BOXES:”的实例
- 查找“<code>TOTAL BOXES:”的每个实例的索引</li>
- 使用这个子字符串中最后一个字符的索引——在这种情况下是“<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])]