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

问题描述

我正在尝试通过 Python 从 PDF 导入基于表格的数据。我尝试了两种不同的软件包:tabula-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 列车之间没有间隔,如表中所示。无论多宽的任何空格都将转换为文本中的单个空格。我已经尝试了 Boxes_flowLAParams() 参数的不同值,但没有帮助。

方法 2: 使用 tabula-py

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]

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

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

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

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...