Открыть сервис

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 →