Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/287.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python-删除对象中的选项卡和新行_Python_Python 2.7_Scrapy_Scrapy Pipeline - Fatal编程技术网

Python-删除对象中的选项卡和新行

Python-删除对象中的选项卡和新行,python,python-2.7,scrapy,scrapy-pipeline,Python,Python 2.7,Scrapy,Scrapy Pipeline,只是一个scrapy.org的新用户和Python的新手。我在品牌和标题属性(JAVA OOP术语)中有此值,其中包含选项卡空间和新行。我们如何修剪它,使下面的2个对象属性具有这个普通字符串值 item['brand'] = "KORAL ACTIVEWEAR" item['title'] = "Boom Leggings" 下面是数据结构 {'store_id': 870, 'sale_price_low': [], 'brand': [u'\n KORAL A

只是一个scrapy.org的新用户和Python的新手。我在品牌标题属性(JAVA OOP术语)中有此值,其中包含选项卡空间和新行。我们如何修剪它,使下面的2个对象属性具有这个普通字符串值

item['brand'] = "KORAL ACTIVEWEAR"
item['title'] = "Boom Leggings"
下面是数据结构

{'store_id': 870, 'sale_price_low': [], 'brand': [u'\n                KORAL ACTIVEWEAR\n              '], 'currency': 'AUD', 'retail_price': [u'$140.00'], 'category': [u'Activewear'], 'title': [u'\n                Boom Leggings\n              '], 'url': [u'/boom-leggings-koral-activewear/vp/v=1/1524019474.htm?folderID=13331&fm=other-shopbysize-viewall&os=false&colorId=68136'], 'sale_price_high': [], 'image_url': [u'  https://images-na.sample-store.com/images/G/01/samplestore/p/prod/products/kacti/kacti3025868136/kacti3025868136_q1_2-0._SH20_QL90_UY365_.jpg\n'], 'category_link': 'https://www.samplestore.com/clothing-activewear/br/v=1/13331.htm?baseIndex=500', 'store': 'SampleStore'}
通过使用regex搜索方法,我可以调整价格,只获取数字和小数,我认为如果有价格逗号分隔符,这可能是错误的

price = re.compile('[0-9\.]+')
item['retail_price'] = filter(price.search, item['retail_price'])

看起来,至少在本例中,您需要做的就是去除
品牌
标题
值边缘的所有空白。您不需要正则表达式,只需调用
strip
方法即可

但是,您的
品牌
不是一个字符串;这是一个字符串列表(即使列表中只有一个字符串)。因此,如果您尝试将其剥离,或者在其上运行正则表达式,您将从尝试将该列表视为字符串中得到一个
AttributeError
TypeError

要解决此问题,您需要使用
map
函数或列表理解功能在所有字符串上映射
strip

item['brand'] = [brand.strip() for brand in item['brand']]
item['title'] = map(str.strip, item['title'])
…两者中哪一个你更容易理解


如果您有其他嵌入空格的示例,并且您希望将每一个空格都转换为一个空格字符,那么您需要对正则表达式使用
sub
方法:

item['brand'] = [re.sub(ur'\s+', u' ', brand.strip() for brand in item['brand']]
注意
u
前缀。在Python 2中,需要一个
u
前缀来生成
unicode
文本,而不是
str
(编码字节)文本。对Unicode字符串使用Unicode模式很重要,即使模式本身并不关心任何非ASCII字符。(如果所有这些看起来都是毫无意义的痛苦和bug磁铁的话,那就是;这就是Python 3存在的主要原因。)


至于
零售价格
,同样的基本观察结果也适用。同样,它是一个字符串列表,而不仅仅是一个字符串。再说一次,你可能不需要正则表达式。假设价格始终是一个后跟数字的
$
(或其他单字符货币标记),只需将
$
切掉,然后在其上调用
float
Decimal

item['retail_price'] = [float(price[1:]) for price in item['retail_price']]
…但是如果您的示例看起来不同,价格的两边都有任意的额外字符,您可以在此处使用
re.search
,但您仍然需要映射它,并使用Unicode模式

您还需要从搜索中获取匹配的
,并以某种方式处理空/无效字符串(对于搜索,它们将返回
None
,并且您无法将其转换为
浮点
)。您必须决定如何处理它,但从您尝试使用
filter
来看,您似乎只想跳过它们。这非常复杂,我会分多个步骤来完成:

prices = item['price']
matches = (re.search(r'[0-9.]+', price) for price in prices)
groups = (match.group() for match in matches if match)
item['price'] = map(float, validmatches)

…或者可以将其包装在函数中。

至少在本例中,您需要做的是去除
品牌
标题
值边缘的所有空白。您不需要正则表达式,只需调用
strip
方法即可

但是,您的
品牌
不是一个字符串;这是一个字符串列表(即使列表中只有一个字符串)。因此,如果您尝试将其剥离,或者在其上运行正则表达式,您将从尝试将该列表视为字符串中得到一个
AttributeError
TypeError

要解决此问题,您需要使用
map
函数或列表理解功能在所有字符串上映射
strip

item['brand'] = [brand.strip() for brand in item['brand']]
item['title'] = map(str.strip, item['title'])
…两者中哪一个你更容易理解


如果您有其他嵌入空格的示例,并且您希望将每一个空格都转换为一个空格字符,那么您需要对正则表达式使用
sub
方法:

item['brand'] = [re.sub(ur'\s+', u' ', brand.strip() for brand in item['brand']]
注意
u
前缀。在Python 2中,需要一个
u
前缀来生成
unicode
文本,而不是
str
(编码字节)文本。对Unicode字符串使用Unicode模式很重要,即使模式本身并不关心任何非ASCII字符。(如果所有这些看起来都是毫无意义的痛苦和bug磁铁的话,那就是;这就是Python 3存在的主要原因。)


至于
零售价格
,同样的基本观察结果也适用。同样,它是一个字符串列表,而不仅仅是一个字符串。再说一次,你可能不需要正则表达式。假设价格始终是一个后跟数字的
$
(或其他单字符货币标记),只需将
$
切掉,然后在其上调用
float
Decimal

item['retail_price'] = [float(price[1:]) for price in item['retail_price']]
…但是如果您的示例看起来不同,价格的两边都有任意的额外字符,您可以在此处使用
re.search
,但您仍然需要映射它,并使用Unicode模式

您还需要从搜索中获取匹配的
,并以某种方式处理空/无效字符串(对于搜索,它们将返回
None
,并且您无法将其转换为
浮点
)。您必须决定如何处理它,但从您尝试使用
filter
来看,您似乎只想跳过它们。这非常复杂,我会分多个步骤来完成:

prices = item['price']
matches = (re.search(r'[0-9.]+', price) for price in prices)
groups = (match.group() for match in matches if match)
item['price'] = map(float, validmatches)

…或者可以将其包装到函数中。

您可以定义一个如下的方法,该方法接受一个对象并返回所有的叶子

import six

def normalize(obj):
    if isinstance(obj, six.string_types):
        return ' '.join(obj.split())
    elif isinstance(obj, list):
        return [normalize(x) for x in obj]
    elif isinstance(obj, dict):
        return {k:normalize(v) for k,v in obj.items()}
    return obj
这是一个递归方法,不会修改原始对象,而是返回规范化对象。您还可以使用它来规范化字符串

对于您的示例项

>> item = {'store_id': 870, 'sale_price_low': [], 'brand': [u'\n                KORAL ACTIVEWEAR\n              '], 'currency': 'AUD', 'retail_price': [u'$140.00'], 'category': [u'Activewear'], 'title': [u'\n                Boom Leggings\n              '], 'url': [u'/boom-leggings-koral-activewear/vp/v=1/1524019474.htm?folderID=13331&fm=other-shopbysize-viewall&os=false&colorId=68136'], 'sale_price_high': [], 'image_url': [u'  https://images-na.sample-store.com/images/G/01/samplestore/p/prod/products/kacti/kacti3025868136/kacti3025868136_q1_2-0._SH20_QL90_UY365_.jpg\n'], 'category_link': 'https://www.samplestore.com/clothing-activewear/br/v=1/13331.htm?baseIndex=500', 'store': 'SampleStore'}

>> print (normalize(item))
>> {'category': [u'Activewear'], 'store_id': 870, 'sale_price_low': [], 'title': [u'Boom Leggings'], 'url': [u'/boom-leggings-koral-activewear/vp/v=1/1524019474.htm?folderID=13331&fm=other-shopbysize-viewall&os=false&colorId=68136'], 'brand': [u'KORAL ACTIVEWEAR'], 'currency': 'AUD', 'image_url': [u'https://images-na.sample-store.com/images/G/01/samplestore/p/prod/products/kacti/kacti3025868136/kacti3025868136_q1_2-0._SH20_QL90_UY365_.jpg'], 'category_link': 'https://www.samplestore.com/clothing-activewear/br/v=1/13331.htm?baseIndex=500', 'sale_price_high': [], 'retail_price': [u'$140.00'], 'store': 'SampleStore'}

您可以定义一个如下的方法,它接受一个对象并返回所有的叶子

import six

def normalize(obj):
    if isinstance(obj, six.string_types):
        return ' '.join(obj.split())
    elif isinstance(obj, list):
        return [normalize(x) for x in obj]
    elif isinstance(obj, dict):
        return {k:normalize(v) for k,v in obj.items()}
    return obj
这是一种递归方法,不修改原始值