参考文章:
pdfminer官方文档
pdfminer源码
pdfminer
pdf文件一整页(含有5张三线表, 15条直线)
获取所有直线对象,并获得其相应的Y轴坐标(5张表,共15条直线)
利用pdfminer库能获取单页PDF页面中的所有对象:包括
失败方案:先前在测试时首先想到 对获取到每个内存中的对象筛选出LTLine即可获得内存对象。
失败原因:某些直线并不会被识别成LTLine,就算获得的坐标也并不符合PDF原输入文件的相应位置。
可行方案:对识别出的所有对象,筛选出 LTRect矩形对象 。
原因分析:直线可以被pdfminer识别成LTRect矩形对象,可以将直线看做高度非常小的一种特殊矩形(实际测试数据三线表直线对象高度大约为0.6~0.8左右,可以认为<2)。
利用 直线可以被看做高度小于2的矩形 的特点 设置过滤条件
(1) pdfminer相关初始化操作
fp = open(path, 'rb')
# 创建pdf文档对象,并获取所有页面pages
parser = PDFParser(fp)
document = PDFDocument(parser)
pages = PDFPage.create_pages(document)
# 断言文档对象可提取
assert document.is_extractable
# 设置参数并获得pdf解释器
rsrcmgr = PDFResourceManager()
laparams = LAParams()
device = PDFPageAggregator(rsrcmgr, laparams=laparams)
interpreter = PDFPageInterpreter(rsrcmgr, device)
(2) 获取 *** 单页 *** 所有pdfminer扫描得到的内存对象的集合:layout布局对象
for eachPage in pages:
interpreter.process_page(eachPage)
layout = device.get_result()
(3) 对 *** 单页 *** 获得的 layout布局对象 中筛选 LTRect对象 并过滤 LTRect对象 , 同时记录Y轴坐标
coordinateY = []
for each in layout:
# 利用LTRect对象来检测直线
if type(each) == LTRect:
# 将高度 > 2的矩形过滤,(测试数据可推测直线会被扫描成高度接近1的矩形)
if each.height > 2:
continue
# 解决同一直线被分段扫描检测为多段直线的问题(同一个Y坐标,但是宽度不一致,其总和为原始直线)
if each.bbox[1]not in coordinateY:
coordinateY.append(each.bbox[1])
其某层父类为:LTComponent
其拥有一个bbox绑定盒子对象,其记录了该LTComponent对象的左下角和右上角坐标 (x0, y0, x1, y1)
在获取所有LTRect对象时,可能会出现如下情况:
原本pdf中三线表的一条直线,可能被分为三段子直线,其Y轴坐标一致,但是每条直线的width(即每条直线的宽度或称之为长度)不一致,但是 三段子直线的总长度和 = 原直线长度
即(x轴方向的总长度): Line = subLine[0] + subLine[1] + subLine[2]