Как определить разрывы страниц с помощью python-docx из docx

#python #parsing #docx #page-break #python-docx

#python #синтаксический анализ #docx #разрыв страницы #python-docx

Вопрос:

У меня есть несколько файлов .docx, которые содержат несколько похожих блоков текста: файлы docx, содержащие более 300 пресс-релизов по 1-2 страницы каждый, которые необходимо разделить на отдельные текстовые файлы. Единственный последовательный способ определить различия между статьями заключается в том, что между 2 статьями всегда и только разрыв страницы.

Однако я не знаю, как находить разрывы страниц при преобразовании охватывающих документов Word в текст, и информация о разрыве страницы теряется после преобразования с использованием моего текущего скрипта

Я хочу знать, как сохранить ЖЕСТКИЕ разрывы страниц при преобразовании файла .docx в .txt. Для меня не имеет значения, как они выглядят в текстовом файле, если они однозначно идентифицируются при последующем сканировании текстового файла

Вот скрипт, который я использую для преобразования файлов docx в txt:

 def docx2txt(file_path):
    document = opendocx(file_path)
    text_file = open("%s.txt" % file_path[:len(file_path)-5], "w")
    paratextlist = getdocumenttext(document)
    newparatextlist = []
    for paratext in paratextlist:
        newparatextlist.append(paratext.encode("utf-8"))
    text_file.write('nn'.join(newparatextlist))
    text_file.close()
  

Комментарии:

1. Вероятно, нет способа сделать это с помощью python-docx из коробки, но сохраните образец файла docx в виде ZIP-файла (чтобы открыть необработанные XML-файлы, из которых состоит документ), и копайтесь, пока не увидите что-то похожее на разрыв страницы. Затем вы можете добавить функцию в свою установку python-docx для обработки их при чтении файла. Исходные файлы python-docx хорошо документированы, и это не слишком сложно после небольшого изучения

2. Даже если вы хотите усложнить задачу, вы можете сохранить docx как HTML, а затем разделить все на разрывы страниц.

Ответ №1:

Жесткий разрыв страницы появится как <w:br> элемент в run element ( <w:r> ), что-то вроде этого:

 <w:p>
  <w:r>
    <w:t>some text</w:t>
    <w:br w:type="page"/>
  </w:r>
</w:p>
  

Таким образом, одним из подходов было бы заменить все эти вхождения отдельной строкой текста, например, «{{foobar}}».

Реализация этого была бы примерно такой:

 from lxml import etree
from docx import nsprefixes

page_br_elements = document.xpath(
    "//w:p/w:r/w:br[@w:type='page']", namespaces={'w': nsprefixes['w']}
)
for br in page_br_elements:
    t = etree.Element('w:t', nsmap={'w': nsprefixes['w']})
    t.text = '{{foobar}}'
    br.addprevious(t)
    parent = br.getparent()
    parent.remove(br)
  

У меня нет времени проверять это, поэтому вы можете столкнуться с некоторыми отсутствующими импортами или чем-то еще, но все, что вам нужно, уже должно быть в модуле docx. Остальное lxml — это вызовы метода для _Element.

Дайте мне знать, как вы идете, и я могу настроить это, если это необходимо.

Комментарии:

1. Дорогой @scanny, похоже, что в этом коде используется более старая версия python-docx. Есть ли способ сделать это с помощью новой библиотеки python-docx? учитывая, что обе версии, похоже, плохо сосуществуют, мне пришлось удалить старую.

2. Лучше задайте этот вопрос в качестве нового вопроса. Если вы пометите это с python-docx помощью, я это увижу.

3. Спасибо @scanny, мне удалось использовать этот код с помощью простого трюка. Я только что создал виртуальную среду со старой библиотекой python docx внутри и вызывал ее python в любое время, когда мне нужен этот скрипт.

4. @XAnguera Не могли бы вы указать версию python-docx , чтобы другие могли добиться того же!