Простой и быстрый парсинг HTML на Питоне


Иногда бывает нужно вытащить из странички в интернете какую либо информацию, при этом сделать это быстро и без идиотств вроде навигации по DOM документу по уровням. Решать эту задачу можно несколькими способами, в народе обычно практикуют XPath для этого. Но мне этот подход не нравится.

Для Python есть библиотека lxml для работы с XML, XHTML, HTML. Как характеризуют свою библиотеку сами авторы:

lxml is a Pythonic binding for the libxml2 and libxslt libraries. It is unique in that it combines the speed and feature completeness of these libraries with the simplicity of a native Python API, mostly compatible but superior to the well-known ElementTree API.

Да, это простой биндинг двух известных библиотек.

Но вернемся к задачи парсинга HTML. В в lxml реализован метода .cssselect(expression) знакомый всем программистам кто работал с фреймворком jQuery для JavaScript. Этот метод работает поверх XPath, тоесть трансформирует ваш запрос в «стиле jQuery» в понятный для XPath синтаксис.

Работать с этим методом очень просто. Например нам надо собрать все ссылки с главной страницы Хабра.

from lxml.html import parse
# Получаем страничку
page = parse('http://habrahabr.ru/').getroot()
# Ищем все теги <a> с css классом topic
hrefs = page.cssselect("a.topic")
for row in hrefs:
    # Получаем атрибут href
    print row.get("href")

Вот и весь код собственно. Очень коротки и, по моему, красиво получается. К слову говоря, возможностей у библиотеки lxml просто море, так что стоит ознакомиться.

Простой и быстрый парсинг HTML на Питоне: 6 комментариев

    • Сам lxml насколько я понимаю не умеет этого. Но можно поступить иначе.
      Любым доступным методом скачиваем, через прокси, файлик который нужно распарсить. Например тем — же https://pypi.python.org/pypi/requests. Имея уже загруженные данные, скармливаем их в lxml через document_fromstring. Все будет работать.
      Да, кстати. Этот метод более правильный, так как можно организовать скачивание файлов в много потоков. Через метод parse — такого не удастся сделать, так как качаться будет в один поток.

Оставьте комментарий