online div xpath web-scraping scrapy scrapy-spider

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"))] porque NO-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>&nbsp;</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>''] >>>