NavigableString
NavigableString — это класс (тип данных) в библиотеке Beautiful Soup для языка программирования Python, представляющий собой текстовый узел (строку) внутри HTML- или XML-документа. Объекты этого класса содержат фрагменты текста, расположенные между тегами или внутри них, и являются основным способом доступа к текстовому содержимому при парсинге веб-страниц и XML-файлов.
Общая характеристика
Beautiful Soup — популярная библиотека Python для извлечения данных из HTML и XML-документов. Она создаёт объектное дерево документа, где каждый элемент (тег, атрибут, текст) представлен соответствующим объектом. Текстовое содержимое, не являющееся тегом, представляется объектом класса NavigableString. Этот класс наследуется от встроенного в Python класса str и от PageElement — базового класса для всех элементов дерева Beautiful Soup.
Основные свойства NavigableString:
- Неизменяемость: объект нельзя изменить напрямую (как строку Python), но можно заменить на новый с помощью метода
replace_with(). - Навигация: объект имеет атрибуты
parent,next_sibling,previous_sibling,next_element,previous_element, позволяющие перемещаться по дереву документа. - Преобразование в строку: при преобразовании в строку (например, через
str()) возвращается сам текст; при преобразовании в Unicode (в Python 2) — аналогично. - Поддержка методов строк: как наследник
str,NavigableStringподдерживает все методы строк Python (.strip(),.split(),.find(),.replace()и т. д.), но с оговоркой — они возвращают обычные строки, а не объектыNavigableString.
Отличие от других типов в Beautiful Soup
В Beautiful Soup существуют три основных типа объектов:
Tag— представляет HTML/XML-тег (например,<div>,<a>). Имеет атрибутыname,attrs, а также доступ к вложенным тегам и тексту.NavigableString— представляет текст внутри тега.Comment— подклассNavigableString, представляющий HTML-комментарии (<!-- ... -->). Отличается тем, что при выводе в HTML-формате не включает обрамляющие символы комментария.
Кроме того, существует CData (подкласс NavigableString) для секций CDATA в XML, и ProcessingInstruction — для инструкций обработки.
Доступ к тексту через NavigableString
Текст внутри тега можно получить несколькими способами:
- Атрибут
.stringу объектаTag— возвращаетNavigableString, если тег содержит только один текстовый узел (без вложенных тегов). Если внутри есть другие теги, возвращаетNone. - Метод
.get_text()(или.text) — возвращает весь текст внутри тега, объединяя все дочерниеNavigableString(включая текст из вложенных тегов) в одну строку. Результат — обычная строка, а неNavigableString. - Итерация по содержимому тега — через
.childrenили.contentsможно получить список дочерних элементов, среди которых будут какTag, так иNavigableString.
Пример: ```python from bs4 import BeautifulSoup
html = "<p>Привет, <b>мир</b>!</p>" soup = BeautifulSoup(html, 'html.parser') p_tag = soup.p
.string — None, так как внутри есть вложенный тег <b>
print(p_tag.string) # None
.get_text() — объединённый текст
print(p_tag.get_text()) # "Привет, мир!"
Доступ к отдельным NavigableString
for child in p_tag.children: if isinstance(child, NavigableString): print(repr(child)) # "Привет, " и "!" ```
Навигация по дереву
Объекты NavigableString участвуют в навигации по дереву документа:
parent— родительский тег (объектTag).next_sibling/previous_sibling— следующий/предыдущий соседний элемент (может бытьTagилиNavigableString).next_element/previous_element— следующий/предыдущий элемент в порядке обхода документа (все элементы, включая вложенные).
Пример: ``python html = "<p>Текст1<b>Текст2</b>Текст3</p>" soup = BeautifulSoup(html, 'html.parser') text1 = soup.p.contents[0] # NavigableString "Текст1" print(text1.next_sibling) # <b>Текст2</b> print(text1.next_sibling.next_sibling) # "Текст3" ``
Изменение текста
Хотя NavigableString неизменяем, его можно заменить другим текстом с помощью метода replace_with(): ``python text = soup.p.contents[0] text.replace_with("Новый текст") print(soup.p) # <p>Новый текст<b>Текст2</b>Текст3</p> ``
Метод возвращает заменённый объект (старый NavigableString).
Особенности при работе с XML
В XML-документах NavigableString работает аналогично, но учитывает особенности XML:
- Секции CDATA представляются как
CData(подклассNavigableString). - Пространства имён не влияют на текстовые узлы.
Практические примеры
Извлечение всех текстовых узлов из документа
```python from bs4 import BeautifulSoup, NavigableString
html = "<div>Текст1<p>Текст2</p>Текст3</div>" soup = BeautifulSoup(html, 'html.parser') texts = [s for s in soup.descendants if isinstance(s, NavigableString)] print(texts) # ["Текст1", "Текст2", "Текст3"] ```
Очистка текста от лишних пробелов
``python for text in soup.find_all(text=True): cleaned = text.strip() if cleaned: text.replace_with(cleaned) ``
Поиск по тексту
```python
Найти все теги, содержащие определённый текст
tags = soup.find_all(string="искомый текст")
tags — список NavigableString
```
Ограничения и особенности
NavigableStringне может быть использован как аргумент для методовfind_all()напрямую (для поиска по тексту используется параметрstring).- При сравнении
NavigableStringс обычной строкой Python сравнение происходит как строк (посколькуNavigableStringнаследуетstr). - В версиях Beautiful Soup 4.x объекты
NavigableStringподдерживают Unicode, но в Python 2 требовали явного преобразования. - При выводе в HTML-формате (через
prettify()илиstr())NavigableStringотображается как есть, без дополнительных тегов.
История версий
- В Beautiful Soup 3 (устаревшая) текстовые узлы представлялись классом
NavigableText, который был предкомNavigableString. - Начиная с Beautiful Soup 4 (выпущена в 2012 году) класс называется
NavigableStringи наследуется отstr(в Python 3) илиunicode(в Python 2). - В версии 4.9.0 (2020 год) была добавлена поддержка секций CDATA в XML через подкласс
CData.
Источники
- Richardson, L. Beautiful Soup Documentation (официальная документация библиотеки).
- Beautiful Soup 4.12.0 Release Notes (2023).
- Python Software Foundation. Python Language Reference (раздел о строковых типах).
- Stack Overflow — обсуждения особенностей
NavigableString(2009–2024).
BFOmetr — база данных и аналитика по компаниям России.
На главную BFOmetr →