Иногда бывает нужно вытащить из странички в интернете какую либо информацию, при этом сделать это быстро и без идиотств вроде навигации по 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 просто море, так что стоит ознакомиться.
http://habrahabr.ru/blogs/python/127584/
с кучей дополнительных возможностей
Хорошее решение, согласен.
Кому нужно «грабить» сайты — больше подойдет, наверное.
Сентябрь 30, 2011 в 05:08 ????
Не понял?
А как реализовать работу через proxy?
Сам lxml насколько я понимаю не умеет этого. Но можно поступить иначе.
Любым доступным методом скачиваем, через прокси, файлик который нужно распарсить. Например тем — же https://pypi.python.org/pypi/requests. Имея уже загруженные данные, скармливаем их в lxml через document_fromstring. Все будет работать.
Да, кстати. Этот метод более правильный, так как можно организовать скачивание файлов в много потоков. Через метод parse — такого не удастся сделать, так как качаться будет в один поток.