Xpath: funzioni
Abbiamo parlato della parentele nella parte 1,
e delle abbreviazioni nella parte 2,
vediamo come utilizzare le funzioni messe a disposizione da Xpath.
Funzioni generiche
facciamo sempre riferimento al body:
<A-TAG class="a-class">A-text <B-TAG class="b-class">B-text</B-TAG> <B-TAG id="1">B-text <C-TAG class="c-class" id="3">C-text</C-TAG> <C-TAG class="c-class" id="4">C-text <D-TAG>D-text</D-TAG> </C-TAG> </B-TAG> <B-TAG id="2">B-text <C-TAG id="5">C-text <D-TAG>D-text</D-TAG> <D-TAG id="6">D-text <E-TAG>E-text</E-TAG> <E-TAG>E-text <F-TAG>F-text</F-TAG> </E-TAG> </D-TAG> </C-TAG> </B-TAG> <B-TAG attr="b-attr">B-text <C-TAG>C-text <D-TAG>D-text</D-TAG> </C-TAG> </B-TAG> </A-TAG>
1. count()
Ritorna il numero dei nodi in un node-set:
>>> selector = Selector(text=body) >>> selector.xpath('count(//b-tag)') [<Selector xpath='count(//b-tag)' data=u'4.0'>] >>> selector.xpath('count(//f-tag)') [<Selector xpath='count(//f-tag)' data=u'1.0'>]
per comodità di lettura useremo il metodo extract_first() dell’ oggetto selector:
>>> selector.xpath('count(//b-tag)').extract_first() u'4.0' >>> selector.xpath('count(//f-tag)').extract_first() u'1.0'
2. id()
Seleziona gli elementi in base al loro ID univoco:
id(’id_1’)
>>> selector.xpath('id(1)') [<Selector xpath='id(1)' data=u'<b-tag id="1">B-text\n\n <c-tag cla'>]
3. last()
Ritorna gli ultimi elementi di quel tipo:
>>> selector.xpath('//b-tag[last()]') [<Selector xpath='//b-tag[last()]' data=u'<b-tag attr="b-attr">B-text\n\n <c-'>]
Come si nota mancano i primi 3 b-tag.
>>> response.xpath('//foo[last()]') [<Selector xpath='//foo[last()]' data=u'<foo>\n <bar attr="z">z text</bar>'>]
4. name()
Ritorna il nome di un nodo:
>>> for n, s in enumerate(selector.xpath('//b-tag[name()]')): print n, s ... 0 <Selector xpath='//b-tag[name()]' data=u'<b-tag class="b-class">B-text</b-tag>'> 1 <Selector xpath='//b-tag[name()]' data=u'<b-tag id="1">B-text\n\n <c-tag cla'> 2 <Selector xpath='//b-tag[name()]' data=u'<b-tag id="2">B-text\n\n <c-tag id='> 3 <Selector xpath='//b-tag[name()]' data=u'<b-tag attr="b-attr">B-text\n\n <c-'>
5. position()
Ritorna la posizione nella lista nodi del nodo che viene processato:
>>> for pos in range(1, 5): ... print pos, selector.xpath('//b-tag[position() = %s]' % pos) ... 1 [<Selector xpath='//b-tag[position() = 1]' data=u'<b-tag class="b-class">B-text</b-tag>'>] 2 [<Selector xpath='//b-tag[position() = 2]' data=u'<b-tag id="1">B-text\n\n <c-tag cla'>] 3 [<Selector xpath='//b-tag[position() = 3]' data=u'<b-tag id="2">B-text\n\n <c-tag id='>] 4 [<Selector xpath='//b-tag[position() = 4]' data=u'<b-tag attr="b-attr">B-text\n\n <c-'>]
6. contains()
Ritorna gli elementi per i quali la stringa passata come primo argomento, contiene la stringa
passata come secondo argomento
>>> for n, s in enumerate(selector.xpath('//*[contains(name(), "b-tag")]')): print n, s ... 0 <Selector xpath='//*[contains(name(), "b-tag")]' data=u'<b-tag class="b-class">B-text</b-tag>'> 1 <Selector xpath='//*[contains(name(), "b-tag")]' data=u'<b-tag id="1">B-text\n\n <c-tag cla'> 2 <Selector xpath='//*[contains(name(), "b-tag")]' data=u'<b-tag id="2">B-text\n\n <c-tag id='> 3 <Selector xpath='//*[contains(name(), "b-tag")]' data=u'<b-tag attr="b-attr">B-text\n\n <c-'>
In questo caso abbiamo filtrato tutti gli elementi i quali nomi (name()) contengono la stringa “b-tag”.
E’ possibile filtrare anche per attributo:
>>> for n, s in enumerate(selector.xpath('//b-tag[contains(@class, "b")]')): print n, s... 0 <Selector xpath='//b-tag[contains(@class, "b")]' data=u'<b-tag class="b-class">B-text</b-tag>'>
7. starts-with()
Ritorna gli elementi per i quali la stringa passata come primo argomento, comincia con la stringa
passata come secondo argomento
>>> for n, s in enumerate(selector.xpath('//*[starts-with(name(), "f")]')): print n, s ... 0 <Selector xpath='//*[starts-with(name(), "f")]' data=u'<f-tag>F-text</f-tag>'>
ci sono molte altre funzioni utilizzabili:
8. normalize-space()
Rimuove gli spazi ad inizio e fine stringa e sostituisce tutti gli spazi all’interno della stringa
con uno spazio solo:
>>> selector = scrapy.Selector(text='<bar name="bar1"> A text spaced </bar><bar name="bar2"> Another text</bar>') >>> selector.xpath('normalize-space(//bar)').extract() [u'A text spaced'] >>> selector.xpath('normalize-space(//bar[@name="bar2"])').extract() [u'Another text']
Funziona chiaramente anche sugli attributi:
>>> selector = scrapy.Selector(text='<bar name=" bar 1"> A text spaced </bar><bar name="bar2"> Another text</bar>') >>> selector.xpath('normalize-space(//bar/attribute::name)').extract() [u'bar 1']
9. string()
Converte un argomento del nodo in oggetto, in stringa:
>>> selector = scrapy.Selector(text='<bar name=" bar 1"> A text spaced </bar><bar name="bar2"> Another text</bar>') >>> selector.xpath('string(//bar[1]/@name)').extract() [u' bar 1']
10. substring(string, start, n_chars)
Ritorna la parte di stringa specificata dal primo argomento (string),
partendo dall’indice indicato nel secondo argomento (start) e ritornando la
quantità di caratteri indicati dal terzo argomento (n_chars)
>>> selector = scrapy.Selector(text='<bar name=" bar 1"> A text spaced </bar><bar name="bar2"> Another text</bar>') >>> selector.xpath('//bar[1]/text()').extract_first() u' A text spaced ' >>> selector.xpath('substring(//bar[1]/text(), 5, 4)').extract_first() u'text'
11. substring-after(string, prefix)
Ritorna la parte di stringa “string” che viene dopo la parte di stringa passata come
secondo argomento (prefix).
>>> selector = scrapy.Selector(text='<bar>string substring</bar>') >>> selector.xpath('substring-after(//bar/text(), "string")').extract_first() u' substring'
12. substring-before(string, siffix)
Ritorna la parte di stringa “string” che viene prima della parte di stringa passata come
secondo argomento (suffix).
>>> selector.xpath('substring-before(//bar/text(), "substring")').extract_first() u'string '
13. translate(string, string_chars, new_chars)
Esegue una sostituzione carattere per carattere di una stringa (string), sostituendo i caratteri
della stringa stessa (string_chars) con quelli nuovi (new_chars):
>>> selector = scrapy.Selector(text='<bar>abcd</bar>') >>> selector.xpath('translate(//bar/text(), "bc", "yz")').extract_first() u'ayzd'
Funzioni numeriche
1. ceiling()
Ritorna il primo intero maggiore del numero dato:
>>> selector.xpath('ceiling(3.141)').extract_first() u'4.0'
2. floor()
Ritorna il primo intero minore del numero dato:
>>> selector.xpath('floor(3.141)').extract_first() u'3.0'
3. number()
Converte l’argomento passato in ingresso in numero quando possibile, o,
in caso contrario, in NAN:
>>> selector.xpath('number(100)').extract_first() u'100.0' >>> selector.xpath('number(a)').extract_first() u'nan'
4. round()
Arrotonda il numero dato all’intero subito inferiore:
>>> selector.xpath('floor(1.999)').extract_first() u'1.0'
5. sum()
Ritorna il totale da un insieme di numeri:
>>> selector = scrapy.Selector(text='<bar>1</bar><bar>2</bar>') >>> selector.xpath('sum(//bar/text())').extract_first() u'3.0'
6. not()
Ritorna gli elementi che non soddisfano un certo parametro:
>>> selector = scrapy.Selector(text='<bar name="bar1">1</bar><bar>2</bar>') >>> selector.xpath('//bar[not(@name)]').extract() [u'<bar>2</bar>']
In questo caso abbiamo selezionato gli elementi che NON hanno un attributo
Questo è quanto. Un buon punto di partenza per utilizzare xpath.
link utili:
parte 1. xpath: Appunti
parte 2. abbreviazioni
scrapy
xpath syntax
Commenti recenti