Scrapy:使用xpath选择具有不间断空格的标记

时间:2016-02-12 13:39:54

标签: xpath web-scraping scrapy scrapy-spider

在我的scrapy蜘蛛中,我想只选择带有文字内容的<p>

item['Description'] = response.xpath('//*[@id="textepresentation"]//p[string(.)]').extract()

它工作正常,但不幸的是,这样做,我也得到空<p>空间

u'<p>\xa0</p>',

如何避免使用xpath选择带有不间断空格的<p>

2 个答案:

答案 0 :(得分:2)

你可以使用XPath's normalize-space()字符串函数和几个谓词:

  • [normalize-space()]以便您获得具有非空字符串表示的元素,不包括前导和尾随空格
  • [not(contains(normalize-space(), "\u00a0"))]因为未删除NO-BREAK SPACE(请参阅this other answer where I checked which ones work,您可能需要添加其他字符进行测试)

样品:

>>> 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>']
>>> 

编辑:

关于@Kimmy的答案,这里有一个带有1个谓词的替代品,对于其他空格字符也是如此:

  • 获取未被normalize-space()
  • 取代的空格字符
  • 并将其与&#39;进行XPath translate()通话。 &#39;
  • 规范化空间,修剪前导和尾随

这就是:

>>> 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>']
>>> 

答案 1 :(得分:0)

//p[translate(string(.),"\xa0","")]