首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >与Scrapy一起使用规范化空间

与Scrapy一起使用规范化空间
EN

Stack Overflow用户
提问于 2015-11-24 21:21:09
回答 3查看 5.5K关注 0票数 4

下面是我正在处理的一个文档的模拟:

代码语言:javascript
复制
<div>
<h4>Area</h4>
  <span class="aclass"> </span>
  <span class="bclass">
        <strong>Address:</strong>
  10 Downing Street

  London

  SW1
  </span>
</div>

我收到的地址如下:

代码语言:javascript
复制
response.xpath(u".//h4[. = 'Area']/following-sibling::span[contains(.,'Address:')]/text()").extract()

回传

代码语言:javascript
复制
[u'\r\n  \t', u'\r\n  10 Downing Street\r\n\r\n  London     \r\n  \r\n  SW1\r\n  ']

我试着用正规化的空间来清理它。我试着把它放在我能想到的每一个位置,但是它要么告诉我有语法错误,要么返回一个空字符串。

更新以补充说,我试图在不过多更改选择器的情况下使其工作。例如,我有类似的情况,它们没有<strong>标记。在我准备的示例中,选择器太复杂了,但是在实时版本中,我必须走一条相当复杂的路才能到达地址。

关于可能重复的,我按照可能重复的通知添加了/normalize-space(.),给出了如下内容:

代码语言:javascript
复制
(u".//h4[. = 'Area']/following-sibling::span[contains(.,'Address:')]/text()/normalize-space(.)").extract()

这会产生ValueError: Invalid XPath:错误。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-11-24 21:29:37

代码语言:javascript
复制
"normalize-space(//strong[contains(text(), 'Address:')]/following-sibling::node())"
票数 3
EN

Stack Overflow用户

发布于 2015-11-24 21:33:46

您可以定位strong元素,获取以下文本同级并将其规范化:

代码语言:javascript
复制
In [1]: response.xpath(u"normalize-space(.//strong[. = 'Address:']/following-sibling::text())").extract()
Out[1]: [u'10 Downing Street London SW1']

或者,您可以查看物品装载机以及输入和输出处理器。我经常使用Join()TakeFirst()MapCompose(unicode.strip)来清理从额外的换行符或空格中提取的数据。

票数 4
EN

Stack Overflow用户

发布于 2017-09-30 09:50:37

由于您正在使用Scrapy,所以可以使用Python liner简化您的XPath:

代码语言:javascript
复制
" ".join(s.split()) # where `s` is your string

使用上面的内容,您可以从您的normalize-space表达式中省略XPath,而是使用刮擦输入处理器创建一个可重用的清除函数,如下所示:

代码语言:javascript
复制
import scrapy
from scrapy.loader.processors import MapCompose
from w3lib.html import remove_tags

def normalize_space(value):
    return " ".join(value.split())

class Product(scrapy.Item):
    name = scrapy.Field(
        input_processor=MapCompose(remove_tags, normalize_space),
    )

或者,您也可以在刮痕装载机中使用Python表达式,如下所示:

代码语言:javascript
复制
import scrapy
from scrapy.loader import ItemLoader
from scrapy.loader.processors import Compose

class ProductLoader(ItemLoader):
    name_in = Compose(lambda s: " ".join(s.split()))

在一个相关的问题上,一条龙的功劳归汤姆的回答所有。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33904058

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档