获取每个段落文本的正确xpath/css是什么?

0 投票
2 回答
1279 浏览
提问于 2025-04-17 22:28

首先,我创建了一个HtmlResponse,并使用scrapy来读取它:

from scrapy.http import HtmlResponse
from scrapy.selector import Selector

body = """
<div class="a">
  <p>
      text1<br> text2
  </p>
</div>
<div class="a">
    <p>
         text3
    </p>
</div>
 """
response = HtmlResponse(url='http://example.com/', body=body)
sel = Selector(response)

现在,我想从这个HTML中提取文本,但我得到的是一个包含两个元素的列表。我到目前为止尝试了这个:

 sel.xpath('//div[@class="a"]/p/text()').extract()
 # [u'\n      text1', u' text2\n  ', u'\n         text3\n    ']

正如你所注意到的,我得到了三个文本元素,而实际上只有两个段落?我该怎么做才能只得到两个文本元素呢?

  [u'text1 text2',u'text3']

请注意,我更倾向于不使用BeautifulSoup,因为这里对性能有要求。

2 个回答

0

我用了一种理解的方法来解决这个问题,也许其他人会有更好的办法:

[''.join(x.xpath('./text()').extract()) for x in sel.xpath('//div[@class="a"]/p')]

## [u'\n      text1 aa\n  ', u'\n         text3\n    ']
2

使用CSS选择器(包括Scrapy的::text扩展):

>>> from scrapy.http import HtmlResponse
>>> from scrapy.selector import Selector
>>> 
>>> body = """
... <div class="a">
...   <p>
...       text1<br> text2
...   </p>
... </div>
... <div class="a">
...     <p>
...          text3
...     </p>
... </div>
...  """
>>> response = HtmlResponse(url='http://example.com/', body=body)
>>> sel = Selector(response)
>>> [u''.join(paragraph.css('::text').extract()).strip() for paragraph in sel.css('div.a > p')]
[u'text1 text2', u'text3']
>>> 

撰写回答