2009-10-16 2 views
1

Рассмотрят следующий фрагмент кода:Weird поведения LXML

import lxml.html 

html = '<div><br />Hello text</div>' 
doc = lxml.html.fromstring(html) 
text = doc.xpath('//text()')[0] 
print lxml.html.tostring(text.getparent()) 
#prints <br>Hello text 

Я ожидал увидеть '<div><br />Hello text</div>', потому что br не может быть вложенным текстом и «сам-закрыто» (я имею в виду />). Как сделать lxml справиться с этим?

ответ

8

HTML не имеет самозакрывающихся тегов. Это xml вещь.

import lxml.etree 

html = '<div><br />Hello text</div>' 
doc = lxml.etree.fromstring(html) 
text = doc.xpath('//text()')[0] 
print lxml.etree.tostring(text.getparent()) 

печатает

<br/>Hello text 

Обратите внимание, что текст не внутри тега. lxml имеет концепцию «tail».

>>> print text.text 
None 
>>> print text.tail 
Hello text 
2

Когда вы имеете дело с действительным XHTML, вы можете использовать etree вместо html.

import lxml.etree 

html = '<div><br />Hello text</div>' 
doc = lxml.etree.fromstring(html) 
text = doc.xpath('//text()')[0] 
print lxml.etree.tostring(text.getparent()) 

Fun вещь, вы можете использовать, как правило, это конвертировать HTML в XHTML:

import lxml.etree 
import lxml.html 

html = '<div><br>Hello text</div>' 
doc = lxml.html.fromstring(html) 
text = doc.xpath('//text()')[0] 
print lxml.etree.tostring(text.getparent()) 

Выход: "<br/>Hello text"