August 7

Конструирование и разбор XML-документов с Python lxml

Когда скорость встречается с мощью в Python, именно lxml занимает лидирующую позицию. Если вы серьезно настроены на сбор данных или эффективную обработку XML, этот инструмент должен быть в вашем арсенале.
Перейдём к делу. Этот урок проведёт вас через весь рабочий процесс lxml — от установки до продвинутых техник парсинга с использованием XPath и CSS-селекторов. Никакой воды. Только практические знания, чтобы вы парсили и собирали данные как профи.

Почему lxml так хорош?

В основе lxml — простота Python и скорость C. Он построен на проверенных временем библиотеках libxml2 и libxslt. Что это значит? Молниеносный разбор и мощные возможности для манипуляций с XML/HTML в удобном, питоновском стиле.

Почему стоит выбрать lxml, а не другие?

Скорость: справляется с большими файлами и десятками страниц без проблем.

Продвинутые возможности: полная поддержка XPath 1.0, XSLT-преобразования, валидация по XML Schema — того, чего нет в стандартном xml.etree.

Гибкость: отлично работает как с чётким XML, так и с хаотичным, “грязным” HTML.

Если ваш проект требует точности и скорости — особенно при парсинге множества страниц или обработке больших XML-файлов — lxml будет лучшим выбором. Многие инструменты, например Scrapy и BeautifulSoup, используют lxml под капотом не случайно.

Установка lxml

Установить lxml просто. Запустите в терминале:

pip install lxml

Если у вас Python 3:

pip3 install lxml

Особенности по платформам:

Windows: Обычно всё идёт гладко — pip скачивает готовый бинарник. Если проблемы — обновите pip или установите Microsoft Visual C++ Build Tools.

Linux: Возможно, придётся предварительно поставить libxml2-dev, libxslt-dev и python3-dev: sudo apt install libxml2-dev libxslt-dev python3-dev

macOS: Командная строка Xcode (xcode-select --install) и Homebrew помогут с зависимостями.

Если используете Conda:

conda install lxml

Проверьте установку:

>>> import lxml
>>> from lxml import etree
>>> print(lxml.__version__)

Если версия выводится без ошибок — готовы к работе.

Первый парсинг XML

Начнём с простого примера:

from lxml import etree

xml_data = "<root><child>Hello</child></root>"
root_element = etree.fromstring(xml_data)

print(root_element.tag)        # root
print(root_element[0].tag)     # child
print(root_element[0].text)    # Hello

Что происходит:

etree.fromstring() строит дерево из строки XML.

Элементы можно перебирать как список (root_element[0]).

Теги и текст доступны как свойства.

Вот и всё — XML распарсен! Для работы с файлами используйте etree.parse() вместо fromstring().

Создание XML и HTML-деревьев

Нужно создавать XML на лету? lxml упрощает задачу:

from lxml import etree

root = etree.Element("books")

book1 = etree.SubElement(root, "book")
book1.text = "Clean Code"
book1.set("id", "101")

book2 = etree.SubElement(root, "book")
book2.text = "Introduction to Algorithms"
book2.set("id", "102")

print(etree.tostring(root, pretty_print=True, encoding='unicode'))

Вывод:

<books>
  <book id="101">Clean Code</book>
  <book id="102">Introduction to Algorithms</book>
</books>

Ключевые моменты:

.Element() создаёт корневой элемент.

.SubElement() добавляет дочерние элементы.

.text задаёт внутренний текст.

.set() добавляет атрибуты.

Как собирать конструктор — шаг за шагом.

Парсинг HTML и XML

HTML часто бывает грязным и невалидным. XML — строгий и корректный.

Для чистого XML используйте: etree.fromstring() или etree.parse().

Для неидеального HTML — lxml.html.fromstring() или etree.HTML().
HTML-парсеры автоматически добавляют теги <html><body>, чтобы “исправить” структуру.

Извлечение нужных данных

После парсинга наступает этап извлечения. XPath — мощный язык запросов для точной навигации и фильтрации узлов.
Пример: получить все URL ссылок в <nav>:

links = doc.xpath('//nav//a/@href')

А тексты ссылок?

link_texts = doc.xpath('//nav//a/text()')

Основы XPath:

/ — от корня.

// — поиск на любом уровне.

[условие] — фильтр по атрибутам или содержимому.

text() — текст узла.

@attr — значение атрибута.

Можно комбинировать запросы для точного выбора.
Если предпочитаете CSS-селекторы — lxml поддерживает их через cssselect.

Пример веб-скрапинга с lxml

Шаг 1: Получаем HTML страницы

import requests

url = "http://books.toscrape.com/"
response = requests.get(url)
html_content = response.content

Шаг 2: Парсим HTML

from lxml import html

doc = html.fromstring(html_content)

Шаг 3: Извлекаем названия и цены книг

books = []
for book in doc.xpath('//article[@class="product_pod"]'):
    title = book.xpath('.//h3/a/text()')[0]
    price = book.xpath('.//p[@class="price_color"]/text()')[0]
    books.append({"title": title, "price": price})

print(books)

Итоги

lxml — это мощный и быстрый инструмент для работы с XML и HTML в Python. Его скорость и универсальность делают его отличным выбором для сложных структур данных, парсинга и веб-скрапинга. С lxml вы получите точное и надёжное извлечение данных каждый раз.