将PDF表格作为文本导入时处理空白单元格

2024-09-26 22:42:59 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试通过Python从PDF导入基于表的数据。我尝试了两种不同的软件包:tabla pypdfminer

作为构建一个火车旅行路线生成器的练习的一部分,我首先尝试从VR(芬兰铁路)网站下载PDF时间表数据 here:

这是其中一个页面的示例:enter image description here

方法1:使用pdfminer3获取逐行文本,该文本使用不同SO样本的混合体(非常感谢!):

from pdfminer3.pdfinterp import PDFResourceManager, PDFPageInterpreter
from pdfminer3.converter import TextConverter
from pdfminer3.layout import LAParams
from pdfminer3.pdfpage import PDFPage
from io import StringIO

def convert_pdf_to_txt(path, pages):
    rsrcmgr = PDFResourceManager()
    retstr = StringIO()
    codec = 'utf-8'

    laparams=LAParams(all_texts=True, detect_vertical=False, 
                      line_overlap=0.5, char_margin=1000.0, #set char_margin to a large number
                      line_margin=0.5, word_margin=0.1,
                      boxes_flow=1 )
    device = TextConverter(rsrcmgr, retstr, codec=codec, laparams=laparams)
    fp = open(path, 'rb')
    interpreter = PDFPageInterpreter(rsrcmgr, device)
    password = ""
    maxpages = 0
    caching = True
    pagenos=set(pages)

    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

timetable = 'Timetable.pdf'
txt = convert_pdf_to_txt(timetable,pages=[3])

for s in txt.split('\n'):
    print(s)

输出的问题是,空白单元格的间距转换为文本字符串中项目之间的单个空格。因此,第二个表的第一行显示为:

Helsinki 5:02 6:28 8:36 9:36 10:36 10:36 11:36 11:36 12:36 13:36 ...

如表中所示,6:28和8:36列车之间没有间隔。任何空格(无论多宽)都会转换为文本中的单个空格。我在LAParams()中尝试了不同的boxes_flow参数值,但没有效果

方法2:使用表格

import tabula

timetable = 'Timetable.pdf'
dfs = tabula.read_pdf(timetable, pages=4,stream=True,guess=True,multiple_tables=True,pandas_options={'header':None})

for df in dfs:
    print(df.head(4))

这里的问题是:(a)没有检测到所有的表,然后没有按照正确的顺序,以及(b)检测到的表中的某些行完全丢失。这是第二个时间表部分输出的开始:

         0    1    2     3     4   ...     16     17     18     19     20
0     Turku  NaN  NaN  5:10  6:10  ...  16:10  17:10  17:10  18:10  20:30
1  Kupittaa    o  NaN  5:14  6:14  ...  16:14  17:14  17:14  18:14  20:34
2  Kupittaa  NaN  NaN  5:16  6:16  ...  16:16  17:16  17:16  18:16  20:38
3      Salo    o  NaN  5:46  6:46  ...  16:46  17:46  17:46  18:46  21:08

[4 rows x 21 columns]
现在这很好,因为它尊重空白单元格。我并不介意tabla忽略了其他一些文本,因为我可以使用方法1和pdfminer恢复这些文本。这里的问题是Turku satamaTurku的原始表的前两行完全丢失。我尝试了guessmultiple_tables参数的各种组合

如果我运行TABLA的GUI版本,也无法准确地“自动检测”表。但是,如果我在每个页面上手动定义每个单独表的区域,那么我可以准确地提取数据,尽管这将是一个漫长的过程

我愿意接受任何一种方法的建议,或者完全不同的方法我会很满意一次性过程(例如在其他情况下,在MS Word中打开PDF,并保存为文本已经成功,但在这种情况下不存在;复制和粘贴到Excel也不尊重空白单元格)。p>


Tags: 数据方法frommargin文本importtxttrue

热门问题