¿Cómo puedo analizar HTML con html5lib y consultar el HTML analizado con XPath?

Estoy tratando de usar html5lib para analizar una página html en algo que puedo consultar con xpath. html5lib tiene documentación casi nula y he pasado demasiado tiempo tratando de resolver este problema. El objective final es sacar la segunda fila de una tabla:

 
Header
Want This

así que vamos a intentarlo:

 >>> doc = html5lib.parse('
Header
Want This
', treebuilder='lxml') >>> doc

Eso se ve bien, veamos que más tenemos:

 >>> root = doc.getroot() >>> print(lxml.etree.tostring(root)) HeaderWant This 

LOL WUT?

seriamente. Estaba planeando usar algún xpath para obtener los datos que quiero, pero eso no parece funcionar. ¿Entonces Que puedo hacer? Estoy dispuesto a probar diferentes bibliotecas y enfoques.

La falta de documentación es una buena razón para evitar una IMO de la biblioteca, sin importar lo interesante que sea. ¿Estás casado con el uso de html5lib? ¿Has mirado lxml.html ?

Aquí hay una manera de hacer esto con lxml:

 from lxml import html tree = html.fromstring(text) [td.text for td in tree.xpath("//td")] 

Resultado:

 ['Header', 'Want This'] 

Lo que desea utilizar es el argumento namespaceHTMLElements , que por alguna razón se establece de manera predeterminada en True.

 doc = html5lib.parse(''' 
Header
Want This
''', treebuilder='lxml', namespaceHTMLElements=False) print lxml.html.tostring(doc)

Sin embargo, es probable que aún sea más fácil usar lxml.html.

Siempre recomiendo probar la librería lxml . Es increíblemente rápido y tiene muchas características.

También tiene soporte para el analizador html5lib si lo necesita: html5parser

 >>> from lxml.html import fromstring, tostring >>> html = """ ...  ...  ...  ...  ... 
Header
Want This
... ... """ >>> doc = fromstring(html) >>> tr = doc.cssselect('table tr')[1] >>> print tostring(tr) Want This

Con BeautifulSoup , puedes hacer eso con

 >>> soup = BeautifulSoup.BeautifulSoup('
Header
Want This
') >>> soup.findAll('td')[1].string u'Want This' >>> soup.findAll('tr')[1].td.string u'Want This'

(Obviamente ese es un ejemplo realmente crudo, pero ya.)

creo que puedes hacer css search en objetos lxml … asi

 elements = root.cssselect('div.content') data = elements[0].text 

Dado que html5lib (de forma predeterminada) crea árboles que contienen (correcta) la información del espacio de nombres que ha especificado (los derechos) espacios de nombres en sus consultas, también.

Ejemplo con una consulta XPath:

 import html5lib inp=''' 
Header
Want This
''' xns = '{http://www.w3.org/1999/xhtml}' d = html5lib.parse(inp) s = d.findall('.//{}td'.format(xns))[-1].text print(s)

Salida:

  Quiero esto 

El mismo resultado sin XPath:

 s = d.find(xns+'body').find(xns+'table').find(xns+'tbody') \ .findall(xns+'tr')[-1].find(xns+'td').text 

Alternativamente, también puede decirle a html5lib que evite agregar información de espacio de nombres durante el análisis:

 d = html5lib.parse(inp, namespaceHTMLElements=False) s = d.findall('.//td')[-1].text print(s) 

Salida:

  Quiero esto 

intenta usar jquery. y puedes recuperar todos los elementos. alternativamente, puedes poner una identificación en tu fila y sacarla.

1) … …

$ (“td”) [1] .innerHTML será lo que quieras

2) … …

$ (“# blah”). text () será lo que quieras