Spaces:
Sleeping
Sleeping
import logging | |
import re | |
from bs4 import BeautifulSoup | |
from components.parser.abbreviations import AbbreviationExtractor | |
from components.parser.xml.structures import ParsedText | |
logger = logging.getLogger(__name__) | |
class XMLTextParser: | |
""" | |
Класс для парсинга текста из xml файлов. | |
""" | |
def __init__(self, soup: BeautifulSoup): | |
""" | |
Инициализация парсера. | |
Args: | |
soup: BeautifulSoup - суп, содержащий весь xml документ | |
""" | |
self.soup = soup | |
self.abbreviation_extractor = AbbreviationExtractor() | |
self.abbreviations = [] | |
def parse(self) -> ParsedText: | |
""" | |
Парсинг текстовой информации из xml файла. | |
Returns: | |
ParsedText - структура с текстом, полученным из xml файла | |
""" | |
parsed_text = self._extract_text() | |
# Извлекаем аббревиатуры из текста | |
if parsed_text and parsed_text.content: | |
text_content = parsed_text.to_text() | |
self.abbreviations = self.abbreviation_extractor.extract_abbreviations_from_text(text_content) | |
logger.debug(f"Extracted {len(self.abbreviations)} abbreviations from text") | |
return parsed_text | |
def get_abbreviations(self) -> list: | |
""" | |
Возвращает список аббревиатур, извлеченных из текста. | |
Returns: | |
list: Список аббревиатур | |
""" | |
return self.abbreviations | |
def _extract_text(self) -> ParsedText: | |
""" | |
Извлечение и очистка текста из XML. | |
Returns: | |
ParsedText - структура, содержащая очищенный текст | |
""" | |
# Удаляем все таблицы | |
for table in self.soup.find_all('w:tbl'): | |
table.decompose() | |
# Удаляем бинарные данные | |
for bindata in self.soup.find_all('w:bindata'): | |
bindata.decompose() | |
# Удаляем элементы v:shape (изображения) | |
for shape in self.soup.find_all('v:shape'): | |
shape.decompose() | |
# Удаляем заголовки документа | |
doc_props = self.soup.find('o:documentproperties') | |
if doc_props: | |
doc_props.decompose() | |
# Извлекаем абзацы (теги w:p) | |
paragraphs = [] | |
for p_tag in self.soup.find_all('w:p'): | |
# Собираем все текстовые элементы в этом абзаце | |
paragraph_text_elements = [] | |
for text_tag in p_tag.find_all('w:t'): | |
content = text_tag.get_text() | |
# Пропускаем специальные элементы в фигурных скобках | |
if content and '{' in content and '}' in content: | |
if '{КСС}' in content or content.startswith('{СС_'): | |
continue | |
if content: | |
paragraph_text_elements.append(content) | |
if paragraph_text_elements: | |
# Объединяем текст этого абзаца | |
paragraph_text = ' '.join(paragraph_text_elements) | |
# Очистка текста абзаца | |
paragraph_text = paragraph_text.replace('&', '&') | |
paragraph_text = paragraph_text.replace('<', '<') | |
paragraph_text = paragraph_text.replace('>', '>') | |
paragraph_text = paragraph_text.replace('MS-Word', '') | |
paragraph_text = paragraph_text.replace('См. документ в ', '') | |
paragraph_text = paragraph_text.replace( | |
'------------------------------------------------------------------', '' | |
) | |
# Удаление фигурных скобок и их содержимого | |
paragraph_text = re.sub( | |
r'\{[\.\,\#\:\=A-Za-zа-яА-Я\d\/\s\"\-\/\?\%\_\.\&\$]+\}', '', paragraph_text | |
) | |
# Форматирование текста абзаца | |
paragraph_text = re.sub(r'[\t ]+', ' ', paragraph_text) | |
paragraph_text = paragraph_text.strip() | |
if paragraph_text: # Добавляем только непустые абзацы | |
paragraphs.append(paragraph_text) | |
return ParsedText(content=paragraphs) | |