Friday, February 3, 2012

lxml в Python

http://python.su/forum/viewtopic.php?id=8188


  • Web
  •  > HTML5LIB, lxml и HTML прошу помощи [RSS Feed]

#1 2010-08-05 13:12:15


dmnBrest
Питонер
Откуда: Брест
Зарегистрирован: 2010-08-05
Сообщений: 23
Профиль  Вебсайт

HTML5LIB, lxml и HTML прошу помощи

Добрый день форумчане!!!! Мне просто необходим ваш совет. Уже ноли в кровь сбил в поисках по нету и чтению инглиш документации.
Но так ничего и не понял sad

есть такая прекрасная библиотека html5lib (только создатели пожалели сил и времени на документирование).
есть задача парсить html страницы вытянутые с помощью curl (вытягивать из них ссылки, элементы и их содержимое)
пробовал с помощью beautifilsoup - все получается.
по совету интернет общественности переключился на html5lib и завис.

все бы хорошо, можно использовать данную библиотеку для создания дерева beautifulsoup и работать как и раньше. Вот только моя натура не дает мне покоя. Создатель html5lib недвусмысленно напоминает, что дерево данного типа не будет поддерживаться в дальнейшем, посему вариантом остается lxml.

Вот тут вся и проблема!!! Как решать задачи парсинга html связкой html5lib и lxml. Так ничего внятного из документации по тому же lxml я не понял. Мот у кого есть рабочие примеры??? Или посоветуйте может что-то революционно-продвинутое.

Главный момент здесь - html5lib smile

Если хочешь чтобы все работало, делай это сам!
http://sanaDG.ru
Неактивен
 

#2 2010-08-05 19:38:03


bw
Питонер
Откуда: Усть-Илимск
Зарегистрирован: 2007-09-26
Сообщений: 796
Профиль  Вебсайт

Re: HTML5LIB, lxml и HTML прошу помощи

Абсолютно никаких сложностей у подавляющего большинства, ни html5lib, ни lxml не вызвали, вот все в недоумении и молчат. Нет документации, читаем примеры, нет или недостаточно примеров читаем исходники, только так, полной, исчерпывающей документации никогда не будет. Возможно вы занимаетесь не своим делом, может вам лучше вернуться к PHP?

Код:

import urllib2
import html5lib

builder = html5lib.getTreeBuilder('lxml')
parser  = html5lib.HTMLParser(builder, namespaceHTMLElements = False)
doc     = parser.parse(urllib2.urlopen('http://python.org/').read())
..bw
Неактивен
 

#3 2010-08-06 00:12:53


dmnBrest
Питонер
Откуда: Брест
Зарегистрирован: 2010-08-05
Сообщений: 23
Профиль  Вебсайт

Re: HTML5LIB, lxml и HTML прошу помощи

bw написал:

Абсолютно никаких сложностей у подавляющего большинства, ни html5lib, ни lxml не вызвали, вот все в недоумении и молчат. Нет документации, читаем примеры, нет или недостаточно примеров читаем исходники, только так, полной, исчерпывающей документации никогда не будет. Возможно вы занимаетесь не своим делом, может вам лучше вернуться к PHP?

..bw
Bw, приятно что мои вопросы хотя бы у вас вызвали какие-то чувства.
Буду предельно откровенен раз уж у Нас с вами завязался диалог. На питоне я всего пару недель отроду. Освоить данный язык меня подтолкнула необходимость создания универсального парсера сайтов. Возможностей PHP для этого увы не хватает из-за его скриптовой направленности и ограниченности во времени работы и выделяемых ресурсах. К тому же порядок отображения информации через браузеры с их заморочками сразу оттолкнуло меня в сторону от этого языка. Хотя есть примеры и очень даже удачные по парсингу сайтов. Выбрал я питон, только потому что один авторитетный журнал отвел целый раздел по этому языку с описанием в красках его преимуществ (теперь я понимаю что это сугубо выкупленные разделы на правах рекламы).

но все не так плохо!!! smile Язык питон действительно классная штука и позволяет решать поистине огромный перечень задач. Так что я рад что я с вами и прошу не отсылать лесом к своим болотам!

А по поводу вашего bw ответа. Ваши 5 строчек кода абсолютно не ответили на мой вопрос. Как мне добраться до отдельного элемента и получить его содержимое или изменить его ....   

И ИЗВИНИТЕ. Пишу из дома и на домашнем компе только поставил пакеты (без ручного рукоделия). HTML5lib ведет себя по другому sad (без ошибок). Наверное произошел тот случай, BW, с пакетами (установленные вручную/с помощью setuptools), который мы обсудили ранее. Завтра буду на работе все сносить и ставить заново, как положено sad

Возможно причина моих вопросов именно в кривой установке пакетов модулей. Буду исправляться.

Если хочешь чтобы все работало, делай это сам!
http://sanaDG.ru
Неактивен
 

#4 2010-08-10 14:16:29


dmnBrest
Питонер
Откуда: Брест
Зарегистрирован: 2010-08-05
Сообщений: 23
Профиль  Вебсайт

Re: HTML5LIB, lxml и HTML прошу помощи

И все же возвращаясь к теме. Не могу разобраться. Вот пара строчек над которыми уже давно ломаю голову:

Код:

import html5lib

f = content  #находится текст загруженной ранее страницы
docc = html5lib.parse(f, treebuilder="lxml")

print docc
Выдает :   <lxml.etree._ElementTree object at 0x01122648>

Методом долгих манипуляций и подгрузки самого lxml получилось увидеть html страницы:

Код:

import html5lib
import lxml.etree as etree

f = content
docc = html5lib.parse(f, treebuilder="lxml")

print etree.tostring(docc)
А КАК ДАЛЬШЕ? КАК ОБРАТИТЬСЯ К ЭЛЕМЕНТУ по id или собрать и вывести все ссылки???
И почему нужно подгружать сам lxml? Разве в html5lib нет всех нужных инструментов чтобы работать с этим деревом???

Если хочешь чтобы все работало, делай это сам!
http://sanaDG.ru
Неактивен
 

#5 2010-08-10 15:11:00


kivsiak
Питонер
Зарегистрирован: 2007-10-22
Сообщений: 12
Профиль

Re: HTML5LIB, lxml и HTML прошу помощи

Вы не совсем правильно понимаете что такое html5lib. Это хреновина которая позволит из кусков невалидного, с точки зрения xml кода, посторить древо документа. Само древо может быть представлено в разных формах. Одной из форм и является lxml.etree. Соответственно html5lib не предоставляет инструментов работы с деревом и курить в вашем случае надо доку lxml.etree.
Неактивен
 

#6 2010-08-10 17:08:43


dmnBrest
Питонер
Откуда: Брест
Зарегистрирован: 2010-08-05
Сообщений: 23
Профиль  Вебсайт

Re: HTML5LIB, lxml и HTML прошу помощи

OOO. Теперь ближе к телу smile

И все же можно увидеть пример рабочего скрипта или хотя бы полурабочего на тему моего последнего вопроса относительно тегов и порядка их извлечения?

А то эту документацию я уже раскурил вдоль и поперек и нифига не понял:
нашел:
     |  find(...)
     |      find(self, path)
     |     
     |      Finds the first matching subelement, by tag name or path.

и куда мне его присобачить???

docc.find('a')

выдает красивое "None"
Отредактированно dmnBrest (2010-08-10 17:15:52)

Если хочешь чтобы все работало, делай это сам!
http://sanaDG.ru
Неактивен
 

#7 2010-08-10 17:30:25


kivsiak
Питонер
Зарегистрирован: 2007-10-22
Сообщений: 12
Профиль

Re: HTML5LIB, lxml и HTML прошу помощи

dmnBrest написал:

OOO. Теперь ближе к телу smile

И все же можно увидеть пример рабочего скрипта или хотя бы полурабочего на тему моего последнего вопроса относительно тегов и порядка их извлечения?

выдает красивое "None"
Думать и писать код за вас я могу, но это будет стоить 25$/h. Могу посоветовать разобраться с тем как работают xpath выражения, и как их применять в libxml.
Неактивен
 

#8 2010-08-10 18:22:02


dmnBrest
Питонер
Откуда: Брест
Зарегистрирован: 2010-08-05
Сообщений: 23
Профиль  Вебсайт

Re: HTML5LIB, lxml и HTML прошу помощи

Спасибо за предложение, но с кодом я пожалуй как-то сам. А на счет совета по поводу xpath - стоит конечно покопаться, но наверное я оставлю это на потом.

Для решения моих задач вполне хватает beautifulsoup, а lxml это всего лишь дань моему любопытству. Прогрессивный народ голосует в пользу второго, но "почему", никто об этом не говорит.
Анализируя материал в инете у меня сложилось мнение, что для задач парсинга html библиотека lxml подходит в меньшей мере (больше для xml), чем скажем тот beautifulsoup, только вот этот, второй, давно не поддерживается автором.
Кроме того использование внутренних средств beautifulsoup для разбора невалидного кода тоже далеко не лучший вариант.

Поэтому остается использовать связку html5lib и beautifulsoup, несмотря на грозные предупреждения автора первого продукта о выходе данного метода из моды.

Если хочешь чтобы все работало, делай это сам!
http://sanaDG.ru
Неактивен
 

#9 2010-08-11 03:44:04


pyuser
Питонер
Откуда: г. Чита
Зарегистрирован: 2007-05-13
Сообщений: 434
Профиль

Re: HTML5LIB, lxml и HTML прошу помощи

dmnBrest написал:

А на счет совета по поводу xpath - стоит конечно покопаться, но наверное я оставлю это на потом.
Зря Вы так пренебрежительно к XPATH относитесь sad. Параметр path в функции find как раз таки по правилам XPATH и строится.

Вывод всех ссылок будет выглядеть примерно так:

Код:

parser = html5lib.HTMLParser(tree=html5lib.getTreeBuilder("lxml"))
dom = parser.parse(content)

find_a = etree.XPath(".//html:a", namespaces={"html": "http://www.w3.org/1999/xhtml"})
for node in find_a(dom):
    href = node.get("href")
    if href:
        print(href)
Неактивен
 

#10 2010-08-11 09:46:00


dmnBrest
Питонер
Откуда: Брест
Зарегистрирован: 2010-08-05
Сообщений: 23
Профиль  Вебсайт

Re: HTML5LIB, lxml и HTML прошу помощи

Все начинает проясняться smile))  Спасибо

На beautifulsoup данный код выглядит немного приятнее:

Код:

import html5lib

...

f = content
docc = html5lib.parse(f, treebuilder="beautifulsoup")

find_a = docc.findAll('a')  # как-то приятнее для глаза
for i in find_a:
    print i['href']
Но прелесть lxml и недостаток beautifulsoup заключается в строчке кода:

... namespaces={"html": "http://www.w3.org/1999/xhtml"} ...

Если хочешь чтобы все работало, делай это сам!
http://sanaDG.ru
Неактивен
 

#11 2010-08-12 09:46:13


dmnBrest
Питонер
Откуда: Брест
Зарегистрирован: 2010-08-05
Сообщений: 23
Профиль  Вебсайт

Re: HTML5LIB, lxml и HTML прошу помощи

Спасибо lorien!!!
Поистине полный и понятный ответ.
Буду рыть во втором направлении  - xpath.

Если хочешь чтобы все работало, делай это сам!
http://sanaDG.ru
Неактивен
 

#12 2010-08-12 10:45:57


dmnBrest
Питонер
Откуда: Брест
Зарегистрирован: 2010-08-05
Сообщений: 23
Профиль  Вебсайт

Re: HTML5LIB, lxml и HTML прошу помощи

Нашел очень интересный и понятный материал (на русском) для начала работы с lxml. Может кому будет полезен.

http://ru.wikisource.org/wiki/Погружени … лгрим)/XML           (про саму библиотеку там написано чуть ниже)
Отредактированно dmnBrest (2010-08-12 11:04:43)

Если хочешь чтобы все работало, делай это сам!
http://sanaDG.ru
Неактивен
 

#13 2010-08-12 11:04:04


dmnBrest
Питонер
Откуда: Брест
Зарегистрирован: 2010-08-05
Сообщений: 23
Профиль  Вебсайт

Re: HTML5LIB, lxml и HTML прошу помощи

И сразу назрел вопрос!

Как указать lxml дефолтный неймспейс?  (eсли я буду работать только с html)

Что-то похожее уже поднималось в нете:
http://softwaremaniacs.org/forum/python/19595/

Если хочешь чтобы все работало, делай это сам!
http://sanaDG.ru
Неактивен
 

#14 2010-08-12 14:11:31


kivsiak
Питонер
Зарегистрирован: 2007-10-22
Сообщений: 12
Профиль

Re: HTML5LIB, lxml и HTML прошу помощи

Угу. Я этот вопрос и  подымал. Ответ - никак.
Но вопрос этот возник в контексте работы с html5lib. Посмотрев на исходники обнаружил что проблему с неймспейсами создаю себе сам:

Код:

import html5lib
from lxml import etree
tree = html5lib.parse("<a href='aaa'>aaa</a>", treebuilder="lxml")
print etree.tostring(tree.getroot())
и сравнить это с

Код:

import html5lib
from lxml import etree
tree = html5lib.parse("<a href='aaa'>aaa</a>", treebuilder="lxml",  namespaceHTMLElements=False)
print etree.tostring(tree.getroot())
Неактивен
 

#15 2010-08-13 09:43:41


dmnBrest
Питонер
Откуда: Брест
Зарегистрирован: 2010-08-05
Сообщений: 23
Профиль  Вебсайт

Re: HTML5LIB, lxml и HTML прошу помощи

tree = html5lib.parse("<a href='aaa'>aaa</a>", treebuilder="lxml",  namespaceHTMLElements=False)


!!!!!!!!!!!!!!!!  ВОТ ОНО, ТО САМОЕ !!!!!!!!!!!!!!!!
Теперь можно работать с чистым html и не забивать голову всякими xml примочками (префиксами, пространствами имен).

Спасибо, дорогие форумчане!  На этот момент у меня вопросы иссякли smile буду творить.

Если кто занимается вопросом парсинга информации в инете, буду рад с вами сотрудничать! Пишите в личку smile

Если хочешь чтобы все работало, делай это сам!
http://sanaDG.ru
Неактивен
 

#16 2010-12-07 22:13:30


asilyator
Питонер
Зарегистрирован: 2010-10-24
Сообщений: 107
Профиль

Re: HTML5LIB, lxml и HTML прошу помощи

kivsiak написал:

Думать и писать код за вас я могу, но это будет стоить 25$/h. Могу посоветовать разобраться с тем как работают xpath выражения, и как их применять в libxml.

dmnBrest написал:

Для решения моих задач вполне хватает beautifulsoup, а lxml это всего лишь дань моему любопытству. Прогрессивный народ голосует в пользу второго, но "почему", никто об этом не говорит.
Все сходится - чем меньше документации и больше надо трахаться, тем больше цена человека, который умеет с ним работать, ну а каждый хочет набить себе цену smile

dmnBrest написал:

Анализируя материал в инете у меня сложилось мнение, что для задач парсинга html библиотека lxml подходит в меньшей мере (больше для xml), чем скажем тот beautifulsoup, только вот этот, второй, давно не поддерживается автором.
Кроме того использование внутренних средств beautifulsoup для разбора невалидного кода тоже далеко не лучший вариант.
Ну и еще это. Суп у меня, к сожалению, жидко обосрался на первом же реальном документе.

dmnBrest написал:

Поэтому остается использовать связку html5lib и beautifulsoup, несмотря на грозные предупреждения автора первого продукта о выходе данного метода из моды.
о_О а это как?

Есть еще вопрос по lxml+html5, предположим, я нашел нужный элемент, а как вывести его путь от корня? В доках нихрена не понятно + они еще и устаревшие (http://codespeak.net/lxml/api/lxml.etre … class.html getpath() и getroot() у меня нет, да и etree.tostring() вместо str(elem) тоже решение спорное).
Неактивен
 

#17 2010-12-08 12:21:59


dmnBrest
Питонер
Откуда: Брест
Зарегистрирован: 2010-08-05
Сообщений: 23
Профиль  Вебсайт

Re: HTML5LIB, lxml и HTML прошу помощи

asilyator написал:

dmnBrest написал:

Поэтому остается использовать связку html5lib и beautifulsoup, несмотря на грозные предупреждения автора первого продукта о выходе данного метода из моды.
о_О а это как?
от Beautifulsoup я отказался smile в последних сообщениях было найдено решение и оно меня вполне удовлетворяет.
Напомню. Я искал возможность разбора html и получения информации из отдельных элементов (тегов). Что-то на подобии jQuery для javascript (поклонником которого я являюсь). Там очень мощный механизм обращения к отдельным элементам. Вот это мне и нужно было только от Python. Решение найдено и пока вполне мне нравится smile

Код:

        tree = html5lib.parse(data, treebuilder="lxml",  namespaceHTMLElements=False)
        root = tree.getroot()
        xpath_abr="//p[contains(., 'ключевое слово') and string-length(text())>'50']" # поиск в тексте абзацев содержащих "ключевое слово" и длиной более 50 символов (и так далее, все зависит от фантазии и знания xpath)
        xpath_me = etree.XPath(xpath_abr.decode('utf8'))
        nodes = xpath_me(root)
        
        for node in nodes:
            if node.text is None: node.text = ''
            print etree.tounicode(node).encode('utf8');

asilyator написал:

Есть еще вопрос по lxml+html5, предположим, я нашел нужный элемент, а как вывести его путь от корня? В доках нихрена не понятно + они еще и устаревшие (http://codespeak.net/lxml/api/lxml.etre … class.html getpath() и getroot() у меня нет, да и etree.tostring() вместо str(elem) тоже решение спорное).
не понял про "...getpath() и getroot() у меня нет..."
но я вижу ответ на ваш вопрос в следующем:

Код:

    import html5lib
    from lxml import etree

    tree = html5lib.parse(page, treebuilder="lxml",  namespaceHTMLElements=False)   #PAGE - html текст страницы
    root = tree.getroot()
    xpath_abr="//a"
    xpath_me = etree.XPath(xpath_abr.decode('utf8'))
    nodes = xpath_me(root)

    for node in nodes:
        print tree.getpath(node)

Код:

/html/body/div[2]/div/div[1]/div/a
/html/body/div[2]/div/div[2]/ul/li[1]/a
/html/body/div[2]/div/div[2]/ul/li[2]/a
/html/body/div[2]/div/div[2]/ul/li[3]/a
/html/body/div[2]/div/div[2]/ul/li[4]/a
/html/body/div[2]/div/div[2]/ul/li[5]/a
/html/body/div[2]/div/div[2]/ul/li[6]/a
/html/body/div[2]/div/div[3]/div/div[2]/div[1]/div[2]/h1/a
/html/body/div[2]/div/div[3]/div/div[2]/div[1]/div[2]/div/a
/html/body/div[2]/div/div[3]/div/div[2]/div[1]/div[3]/div/p[1]/a[1]
/html/body/div[2]/div/div[3]/div/div[2]/div[1]/div[3]/div/p[1]/a[2]
/html/body/div[2]/div/div[3]/div/div[2]/div[1]/div[3]/div/p[1]/a[3]
...

Если хочешь чтобы все работало, делай это сам!
http://sanaDG.ru
Неактивен
 

#18 2011-03-31 02:03:34


asilyator
Питонер
Зарегистрирован: 2010-10-24
Сообщений: 107
Профиль

Re: HTML5LIB, lxml и HTML прошу помощи

А в lxml есть getElementById? Я уже свой велосипед изобрел.
Неактивен
 

#19 2011-03-31 08:44:08


Александр Кошелев
daevaorn
Откуда: Москва
Зарегистрирован: 2007-02-03
Сообщений: 1784
Профиль  Вебсайт

Re: HTML5LIB, lxml и HTML прошу помощи

Код:

>>> doc.xpath('//*[@id="mail"]')
[<Element li at 3061d08>]
Неактивен
 

#20 2011-03-31 21:27:53


asilyator
Питонер
Зарегистрирован: 2010-10-24
Сообщений: 107
Профиль

Re: HTML5LIB, lxml и HTML прошу помощи

А подробные доки по xpath есть?
Неактивен
 

#21 2011-03-31 21:43:54


Александр Кошелев
daevaorn
Откуда: Москва
Зарегистрирован: 2007-02-03
Сообщений: 1784
Профиль  Вебсайт

Re: HTML5LIB, lxml и HTML прошу помощи

XPath стандартизирован W3C. Спики есть у них на сайте.
Неактивен
 

#22 2011-03-31 23:23:24


asilyator
Питонер
Зарегистрирован: 2010-10-24
Сообщений: 107
Профиль

Re: HTML5LIB, lxml и HTML прошу помощи

А что-нибудь менее гиморное есть?
Неактивен
 

#23 2011-04-01 06:38:47


PooH
Питонер
Откуда: Барнаул
Зарегистрирован: 2006-12-05
Сообщений: 1102
Профиль

Re: HTML5LIB, lxml и HTML прошу помощи

asilyator написал:

А что-нибудь менее гиморное есть?
Вот, кто-то обвязку к lxml в стиле jQuery сделал http://packages.python.org/pyquery/
Неактивен
 

#24 2011-04-01 23:55:53


o7412369815963
Питонер
Зарегистрирован: 2009-06-17
Сообщений: 1568
Профиль  Вебсайт

Re: HTML5LIB, lxml и HTML прошу помощи

короткий пример по lxml
Неактивен
 

No comments:

Post a Comment