div - Scrapy: Seleccione la etiqueta con espacio no disruptivo con xpath
xpath online (2)
En mi araña de scrapy, quiero seleccionar solo <p>
con contenido de texto:
item[''Description''] = response.xpath(''//*[@id="textepresentation"]//p[string(.)]'').extract()
Funciona bien, pero desafortunadamente, al hacer esto, también me llego vacío <p>
con espacio sin interrupciones
u''<p>/xa0</p>'',
¿Cómo evitar seleccionar <p>
con espacio no disruptivo con xpath?
//p[translate(string(.),"/xa0","")]
Puede usar la función de cadena normalize-space()
XPath para esto con un par de predicados:
-
[normalize-space()]
para que pueda obtener elementos con representación de cadena no vacía, excluyendo el espacio en blanco inicial y posterior -
[not(contains(normalize-space(), "/u00a0"))]
porqueNO-BREAK SPACE
no se elimina (mira esta otra respuesta donde verifiqué cuáles funcionan , es posible que quieras agregar otros caracteres para probar)
Muestra:
>>> import scrapy
>>> selector = scrapy.Selector(text=u''''''
... <html>
... <p> </p>
... <p>something</p>
... <p> </p>
... <p><a href="http://example.com">some link</a></p>
... </html>
... '''''')
>>> selector.xpath(u''''''
... //p[normalize-space()]
... [not(contains(normalize-space(), "/u00a0"))]
... '''''').extract()
[u''<p>something</p>'', u''<p><a href="http://example.com">some link</a></p>'']
>>>
Editar:
siguiendo la respuesta de @ Kimmy, aquí hay una alternativa con 1 predicado, para otros personajes de espacio en blanco también:
- tomar caracteres de espacio en blanco que no reemplazan por
normalize-space()
- y ponerlos en una llamada XPath
translate()
con '''' - normaliza los espacios, recortando los principales y finales
Aquí va:
>>> chars = ''''''
... #CHARACTER TABULATION
... #LINE FEED
... #LINE TABULATION
... #FORM FEED
... #CARRIAGE RETURN
... #SPACE
... #NEXT LINE
... NO-BREAK SPACE
... OGHAM SPACE MARK
... MONGOLIAN VOWEL SEPARATOR
... EN QUAD
... EM QUAD
... EN SPACE
... EM SPACE
... THREE-PER-EM SPACE
... FOUR-PER-EM SPACE
... SIX-PER-EM SPACE
... FIGURE SPACE
... PUNCTUATION SPACE
... THIN SPACE
... HAIR SPACE
... ZERO WIDTH SPACE
... ZERO WIDTH NON-JOINER
... ZERO WIDTH JOINER
... LINE SEPARATOR
... PARAGRAPH SEPARATOR
... NARROW NO-BREAK SPACE
... MEDIUM MATHEMATICAL SPACE
... WORD JOINER
... IDEOGRAPHIC SPACE
... ZERO WIDTH NO-BREAK SPACE
... ''''''
>>> import unicodedata
>>> wsp = [unicodedata.lookup(c)
... for c in chars.splitlines()
... if c.strip() and not c.startswith(''#'')]
>>>
>>> # somehow NEXT LINE (U+0085) does not work with unicodedata
... wsp.append(u''/u0085'')
>>>
>>> selector.xpath(u''''''
... //p[normalize-space(translate(., "%(in)s", "%(out)s"))]
... '''''' % {''in'': ''''.join(wsp),
... ''out'': '' ''*len(wsp)
... }).extract()
[u''<p>something</p>'', u''<p><a href="http://example.com">some link</a></p>'']
>>>