У меня есть этот файл PDF, который имеет эти "длинные" пробелы (выделены желтым цветом на изображении ниже). Моя цель - обнаружить их, чтобы я мог разделить сегменты текста вокруг этих пробелов.
Пока что мои испытания не были полностью безуспешными. так как XML возвращает атрибут «ограничивающий прямоугольник» (пример: bbox="68.031,553.639,76.375,566.366"
), который имеет четыре значения (x1, y1, x2, y2), я мог узнать более или менее расстояние, которое я искал, делая x1 - х1 предыдущего элемента. Но вывод невелик, и я уверен, что есть более простой ответ на мою проблему, чем тот, который у меня есть.
Вывод, который я получаю, не сохраняет пробелов и не учитывает разрывы строк. Но даже не учитывает разрывы абзацев (изображение ниже):
Которые должны учитывать не x1 атрибута bbox
, но, вероятно, позиция у, но я не знаю, как с этим справиться.
Это мой код:
import lxml.etree as etree
parser = etree.XMLParser(remove_blank_text=True)
tree = etree.parse('fe3.xml', parser)
root = tree.getroot()
# Get the first BBox value as float
# Return null if not found
def getBBoxFirstValue(line):
if line is not None:
bb = line.attrib.get('bbox')
if bb is not None:
try:
return float(bb.split(",")[0])
except ValueError:
pass
return None
new_line = None
previous_bb = None
for x in tree.xpath('//text'):
# Get current bb value
bb = getBBoxFirstValue(x)
# Check current and past values aren't empty
if bb is not None and previous_bb is not None:
#print(bb, previous_bb, (bb-previous_bb))
#print(abs(bb-previous_bb))
# If distance with preview bb > 10
if (bb - previous_bb) > 20 or (bb - previous_bb) < -1000:
# If new_line isn't empty: it's inserted into parent tag at position of current tag
if new_line is not None:
x.getparent().insert(x.getparent().index(x), new_line)
# A new "new_line" element is created
new_line = etree.Element("new_line")
# If the new line isn't not (e.g. one distance > 10 has been already found)
if new_line is not None:
new_line.append(x)
# Keep latest non empty BBox 1st value
if bb is not None:
previous_bb = bb
# Add last new_line element if not null
if new_line is not None:
tree.xpath('//text')[-1].getparent().append(new_line)
newtree = etree.tostring(root, encoding='utf-8', pretty_print=True)
#newtree = newtree.decode("UTF-8")
print(newtree)
with open("output.xml", "wb") as f:
f.write(newtree)
Мой входной файл находится здесь: ссылка
Вывод, который я получаю здесь: ссылка
РЕДАКТИРОВАТЬ:
Для пояснения, ввод XML выглядит так:
Рассмотрим текстовые теги, имеющие атрибуты "bbox
"
<pages>
<page>
<textbox>
<textline>
<text> a </text>
<text> b </text>
<text> c </text>
</textline>
<textline>
<text> d </text>
</textbox>
<textbox>
<textline>
<text> e </text>
<text> f </text>
</textline>
</textbox>
</page>
</pages>
Вывод, который я хотел бы получить:
<pages>
<page>
<textbox>
<textline>
<new_line>
<text> a </text>
<text> b </text>
</new_line>
<new_line>
<text> c </text>
</new_line>
</textline>
<textline>
<new_line>
<text> d </text>
</new_line>
</textbox>
<textbox>
<textline>
<new_line>
<text> e </text>
<text> f </text>
</new_line>
</textline>
</textbox>
</page>
</pages>
Но вывод, который я получаю:
<pages>
<page>
<textbox>
<textline>
<new_line>
<text> a </text>
<text> b </text>
</new_line>
</textline>
<textline>
<new_line>
<text> c </text>
<text> d </text>
</new_line>
</textbox>
<textbox>
<textline>
<new_line>
<text> e </text>
<text> f </text>
</new_line>
</textline>
</textbox>
</page>
</pages>
Итак, что происходит с моим кодом, так это то, что «текстовое поле» не сохраняется должным образом.