2011-10-26 3 views
1

Я пытаюсь разобрать некоторый html, и у меня есть некоторые проблемы с этим маленьким html-кодом.Parse html with lxml (tag h3)

XML:

<div> 
    <p><span><a href="../url"></a></span></p> 
    <h3 class="header"><a href="../url">Other</a></h3> 
    <a href="../url">Other</a><br> 
    <a class="aaaaa" href="../url">Indice</a> 
    <p></p>    
</div> 

код:

import urllib 
from lxml import etree 
import StringIO 
resultado=urllib.urlopen('trozo.html') 
html = resultado.read() 
parser= etree.HTMLParser() 
tree=etree.parse(StringIO.StringIO(html),parser) 
xpath='/div/h3' 
html_filtrado=tree.xpath(xpath) 
print html_filtrado 

Когда я печатаю код он появляется [], и я полагаю, что он должен быть список с <h3 class="header"><a href="../url">Other</a></h3> в нем. Если бы у меня был этот список, я бы выполнил etree.tostring (html_filtrado), чтобы увидеть <h3 class="header"><a href="../url">Other</a></h3>.

Так как же получить этот код?

<h3 class="header"><a href="../url">Other</a></h3> 

или только ../url? который я хочу!

Спасибо

+0

что вы Размещенное ** не ** XML соответствует, ''
без закрывающего тега является незаконным XML, 'lxml' является первым и для большинства в разборе библиотеки XML, чтобы включить сломанный HTML, вам нужно установить несколько флагов в синтаксическом анализаторе. Попробуйте вместо этого использовать парсер HTML или конвертировать HTML в XHTML. –

+0

Но я разбираю много страниц без проблем, с
!! Итак, какие флаги мне нужно использовать? Потому что мне очень нравится этот парсер, это действительно быстро! – dani

ответ

3

Дело в том, что etree.HTMLParser(), когда получает HTML, он создает полный HTML DOM дерево. Таким образом, вместо того, что вы хотели, если вы используете etree.tostring (дерево) вы получите

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd"> 
<html><body><div> 
<p><span><a href="../url"/></span></p> 
<h3 class="header"><a href="../url">Other</a></h3> 
<a href="../url">Other</a><br/><a class="aaaaa" href="../url">Indice</a> 
<p/>    

Таким образом, правильный XPath будет '/ html/тела/дел/h3'

+0

Не работает! :(Это часть большого документа, а xpath - «/html/body/......./div/h3». И это не работает. Это проблема с h3. Потому что я могу читать до div. И тогда он не переделывает тэг h3. – dani

+0

Не могли бы вы пробовать весь документ? Очевидно, этой части недостаточно, чтобы узнать, в чем проблема с вашей структурой.Конечно, вы можете придерживаться второго ответа на этот вопрос, но это не оптимально :) Или, по сути, может случиться так, что HTMLParser() по умолчанию исправляет разбитый HTML, поэтому, если он сломан и затем исправлен, он может содержат дополнительные HTML-теги, попробуйте использовать to_string() и снова посмотрите на структуру. –

+0

Вы правы! Парсер изменил структуру! – dani

4

Запрос XPath в вашем примере не совсем прав.

Чтобы получить список всех h3 тегов в div теги, вы должны использовать это:

elements = tree.xpath('//div/h3') 
etree.tostring(elements[0]) 

Который должен дать:

'<h3 class="header"><a href="../url">Other</a></h3>\n' 

Чтобы получить список всех href атрибутов a тегов в пределах h3 тегов, вы можете использовать что-то вроде этого:

tree.xpath('//h3/a/@href') 

Что дает:

['../url'] 
+0

Большое вам спасибо !!!!! Это подходит для меня!! Я думаю, что мне нужно больше узнать о xpath. спасибо – dani