问题描述
我正在尝试通过 Python 从 PDF 导入基于表格的数据。我尝试了两种不同的软件包:tabula-py 和 pdfminer。
作为构建用于搭乘火车环游芬兰的行程生成器的练习的一部分,我首先尝试从 VR(芬兰铁路)网站下载 PDF 时间表数据 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_flow
中 LAParams()
参数的不同值,但没有帮助。
方法 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 satama
和 Turku
的原始表的前两行完全丢失了。我为 guess
和 multiple_tables
参数尝试了各种组合。
如果我运行 tabula 的 GUI 版本,也无法准确地“自动检测”表格。但是如果我在每个页面上手动定义每个单独表格的区域,那么我可以准确地提取数据,尽管这将是一个漫长的过程。
我愿意接受任何一种方法的建议,或者完全不同的方法!我对一次性过程很满意(例如,在其他情况下,在 MS Word 中打开 PDF,然后保存因为文本已经成功,但在这种情况下不是;复制和粘贴到 Excel 也不考虑空白单元格)。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)