Scrapy 忽略了部分文本

Posted

技术标签:

【中文标题】Scrapy 忽略了部分文本【英文标题】:Scrapy is ignoring part of the text 【发布时间】:2022-01-22 06:02:01 【问题描述】:

我正在尝试使用 Scrapy 从网站上抓取文本并构建文本数据集及其一些功能。对于每个包含文本的元素,我将保存文本本身、元素类型和其他一些内容。它在大多数情况下都可以正常工作,但它不会抓取嵌套元素后面的部分文本。

输入示例:

<p>
  First part of text
  <b>
    Nested text
  </b>
  Second part of text
</p>

输出(只是一个例子,实际上输出保存到csv):

text: First part of text, element: p
text: Nested text, element: b

预期输出(只是一个例子,实际上输出保存到 csv):

text: First part of text, element: p
text: Nested text, element: b
text: Second part of text, element: p

我负责抓取文本的部分代码:

for element in response.xpath('//*[normalize-space(text())]'):
    ...
    text_normalized = element.xpath('normalize-space(./text())').get()
    ...

如何获得文本的第二部分?期望一个元素可以包含多个嵌套元素,并且文本本身可以分成多于 2 个部分。

【问题讨论】:

与您的问题没有直接关系,因为您决定使用 xpath,但考虑使用 beautifulsoup。将它与scrapy一起使用也是标准的,scrapy的文档本身建议在某些时候使用beautifulsoup。我自己使用网络抓取,它提供了一组功能来更好地处理这种确切的情况。它比使用 xpath 本身更强大 例如,有一些函数可以让你递归地找到 ,而不是只找到你正在搜索的元素的直接 b。您还可以对之前找到的元素执行搜索。您还可以浏览子元素、父元素、“兄弟”元素并执行搜索。挺好用的 【参考方案1】:

如果您将 // 与 text node 一起使用,它将以列表形式返回所有文本,之后您可以使用 .join 方法或列表切片。

text_normalized = element.xpath('normalize-space(.//p//text())').getall()

scrapy shell 上的实现

In [1]: from scrapy.selector import Selector

In [2]: %paste
doc='''
<p>
  First part of text
  <b>
    Nested text
  </b>
  Second part of text
</p>
'''

## -- End pasted text --

In [3]: sel = Selector(text=doc)

In [4]: sel.xpath('//p//text()').getall()
Out[4]: 
['\n  First part of text\n  ',
 '\n    Nested text\n  ',
 '\n  Second part of text\n']

In [5]: sel.xpath('//p//text()').get()
Out[5]: '\n  First part of text\n  '

In [6]: 

In [6]: p_text=sel.xpath('//p//text()').getall()[0]

In [7]: p_text
Out[7]: '\n  First part of text\n  '

In [8]: p_text=sel.xpath('//p//text()').getall()[0].strip()

In [9]: p_text
Out[9]: 'First part of text'

In [10]: b_text=p_text=sel.xpath('//p//text()').getall()[1].strip()

In [11]: b_text
Out[11]: 'Nested text'

In [12]: p-text1=b_text=p_text=sel.xpath('//p//text()').getall()[2].strip()
  File "<ipython-input-12-6baa2c054111>", line 1
    p-text1=b_text=p_text=sel.xpath('//p//text()').getall()[2].strip()
    ^
SyntaxError: cannot assign to operator


In [13]:  p_text1=b_text=p_text=sel.xpath('//p//text()').getall()[2].strip()

In [14]: p_text1
Out[14]: 'Second part of text'

【讨论】:

以上是关于Scrapy 忽略了部分文本的主要内容,如果未能解决你的问题,请参考以下文章

使用 Scrapy 在 Python 中选择部分文本字段

MongoDB 匹配部分文本忽略重音符号(变音符号)

在 Scrapy 中连接 Xpath 嵌套文本

scrapy爬虫部分

scrapy框架

Linux文本命令