2011-01-24 10 views
28

Estoy tratando de obtener los enlaces de una página con xpath. El problema es que solo quiero los enlaces dentro de una tabla, pero si aplico la expresión xpath en toda la página capturaré enlaces que no quiero.Python: Usando xpath localmente/en un elemento específico

Por ejemplo:

tree = lxml.html.parse(some_response) 
links = tree.xpath("//a[contains(@href, 'http://www.example.com/filter/')]") 

El problema es que la expresión se aplica a todo el documento. Localicé el elemento que quiera, por ejemplo:

tree = lxml.html.parse(some_response) 
root = tree.getroot() 
table = root[1][5] #for example 
links = table.xpath("//a[contains(@href, 'http://www.example.com/filter/')]") 

pero que parece ser la realización de la consulta en todo el documento, así, ya que todavía estoy capturando los enlaces fuera de la mesa. This page dice que "Cuando se usa xpath() en un Elemento, la expresión XPath se evalúa contra el elemento (si es relativo) o contra el árbol raíz (si es absoluto):". Entonces, ¿qué uso es una expresión absoluta y necesito hacerlo relativo? ¿Es asi?

Básicamente, ¿cómo puedo hacer para filtrar solo los elementos que existen dentro de esta tabla?

Respuesta

47

Su xpath comienza con una barra inclinada (/) y es por lo tanto absoluta. Añadir un punto (.) delante para que sea en relación con el elemento actual es decir,

links = table.xpath(".//a[contains(@href, 'http://www.example.com/filter/')]") 
+0

Si agrego el punto, sin embargo, no parece buscar recursivamente (como en, solo busca en ese elemento). Al menos eso es lo que me parece, ya que el filtro ya no funciona después de hacerlo relativo. ¿Hay alguna manera de hacer que busque más allá de ese elemento en lugar de buscar solo en él? –

+0

@pvt pns Ese es un indicador fuerte de que algo más está mal. ¿Puedes subir y vincular a un ejemplo completo? Si no quiere hacer eso, también puede contactarme directamente (haga clic en mi nombre para ver las opciones de contacto) – phihag

+0

@phihag: Usted escribió * Agregue un "." (punto) al frente para hacerlo relativo *. También puede usar 'descenddant :: a [contains (@href, ...)]' como una expresión relativa. –

0

Otra opción sería pedir directamente de elementos dentro de su mesa. Por ejemplo:

tree = lxml.html.parse(some_response) 
links = tree.xpath("//table[**criteria**]//a[contains(@href, 'http://www.example.com/filter/')]") 

Dónde **criteria** es necesario si hay muchas tablas en la página. Algunos criterios posibles serían filtrar en función de la id o clase de la tabla. Por ejemplo:

links = tree.xpath("//table[@id='my_table_id']//a[contains(@href, 'http://www.example.com/filter/')]") 
Cuestiones relacionadas