2011-01-24 9 views
28

Sto cercando di ottenere i collegamenti da una pagina con xpath. Il problema è che voglio solo i collegamenti all'interno di una tabella, ma se applico l'espressione xpath sull'intera pagina, catturerò i collegamenti che non desidero.Python: utilizzo di xpath localmente/su un elemento specifico

Ad esempio:

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

Il problema è che applica l'espressione all'intero documento. Ho individuato l'elemento che voglio, per esempio:

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/')]") 

ma che sembra essere l'esecuzione della query in tutto il documento, così come lo sono ancora catturare il link al di fuori del tavolo. This page dice che "Quando xpath() viene utilizzato su un elemento, l'espressione XPath viene valutata rispetto all'elemento (se relativo) o rispetto all'albero radice (se assoluto):". Quindi, quello che uso è un'espressione assoluta e ho bisogno di renderlo relativo? È così?

Fondamentalmente, come posso procedere a filtrare solo gli elementi che esistono all'interno di questa tabella?

risposta

47

Il tuo xpath inizia con una barra (/) ed è quindi assoluto. Aggiungere un punto (.) di fronte per renderlo relativo all'elemento corrente cioè

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

Se aggiungo il punto, tuttavia, non sembra eseguire la ricerca in modo ricorsivo (come in, ricerca solo su quell'elemento). Almeno questo è quello che mi sembra, dal momento che il filtro non funziona più dopo averlo reso relativo. C'è un modo per farlo cercare da quell'elemento al di là invece di cercare solo in esso? –

+0

@pvt pns Questo è un indicatore forte qualcos'altro è sbagliato. Puoi caricare e collegare a un esempio completo? Se non vuoi farlo, puoi anche contattarmi direttamente (clicca sul mio nome per vedere le opzioni di contatto) – phihag

+0

@phihag: Hai scritto * Aggiungi un "." (punto) in primo piano per renderlo relativo *. Puoi anche usare 'descendant :: a [contains (@href, ...)]' come espressione relativa. –

0

Un'altra opzione sarebbe quella di chiedere direttamente per gli elementi all'interno del vostro tavolo. Per esempio:

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

Dove **criteria** è necessaria se ci sono molte tabelle presenti nella pagina. Alcuni possibili criteri sarebbero filtrare in base all'ID o alla classe della tabella. Ad esempio:

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