#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
, чтобы другие могли добиться того же!