繁体   English   中英

在scrapy中去除\\n \\t \\r

[英]Strip \n \t \r in scrapy

我试图用一个爬虫蜘蛛去除 \\r \\n \\t 字符,然后制作一个 json 文件。

我有一个充满新行的“描述”对象,它没有做我想要的:将每个描述与标题匹配。

我尝试使用 map(unicode.strip()) 但它并没有真正起作用。 作为scrapy的新手,我不知道是否有另一种更简单的方法或者map unicode是如何真正工作的。

这是我的代码:

def parse(self, response):
    for sel in response.xpath('//div[@class="d-grid-main"]'):
        item = xItem()
        item['TITLE'] = sel.xpath('xpath').extract()
        item['DESCRIPTION'] = map(unicode.strip, sel.xpath('//p[@class="class-name"]/text()').extract())

我也试过:

item['DESCRIPTION'] = str(sel.xpath('//p[@class="class-name"]/text()').extract()).strip()

但它引发了一个错误。 最好的方法是什么?

unicode.strip只处理字符串开头和结尾的空白字符

返回删除前导和尾随字符的字符串副本。

中间没有\\n\\r\\t

您可以使用自定义方法删除字符串中的那些字符(使用正则表达式模块),甚至可以使用XPath 的normalize-space()

返回带有通过去除前导和尾随空格并用单个空格替换空格字符序列而标准化的空格的参数字符串。

示例 python shell 会话:

>>> text='''<html>
... <body>
... <div class="d-grid-main">
... <p class="class-name">
... 
...  This is some text,
...  with some newlines \r
...  and some \t tabs \t too;
... 
... <a href="http://example.com"> and a link too
...  </a>
... 
... I think we're done here
... 
... </p>
... </div>
... </body>
... </html>'''
>>> response = scrapy.Selector(text=text)
>>> response.xpath('//div[@class="d-grid-main"]')
[<Selector xpath='//div[@class="d-grid-main"]' data=u'<div class="d-grid-main">\n<p class="clas'>]
>>> div = response.xpath('//div[@class="d-grid-main"]')[0]
>>> 
>>> # you'll want to use relative XPath expressions, starting with "./"
>>> div.xpath('.//p[@class="class-name"]/text()').extract()
[u'\n\n This is some text,\n with some newlines \r\n and some \t tabs \t too;\n\n',
 u"\n\nI think we're done here\n\n"]
>>> 
>>> # only leading and trailing whitespace is removed by strip()
>>> map(unicode.strip, div.xpath('.//p[@class="class-name"]/text()').extract())
[u'This is some text,\n with some newlines \r\n and some \t tabs \t too;', u"I think we're done here"]
>>> 
>>> # normalize-space() will get you a single string on the whole element
>>> div.xpath('normalize-space(.//p[@class="class-name"])').extract()
[u"This is some text, with some newlines and some tabs too; and a link too I think we're done here"]
>>> 

我是一个 python,scrapy 新手,我今天遇到了类似的问题,在以下模块/函数w3lib.html.replace_escape_chars的帮助下解决了这个问题我为我的项目加载器创建了一个默认的输入处理器,它没有任何问题,您也可以将其绑定到特定的 scrapy.Field() 上,它与 css 选择器和 csv 提要导出一起使用的好处是:

from w3lib.html import replace_escape_chars
yourloader.default_input_processor = MapCompose(relace_escape_chars)

正如paul trmbrth在他的回答中所暗示的那样,

div.xpath('normalize-space(.//p[@class="class-name"])').extract()

很可能就是你想要的。 但是, normalize-space也将包含在字符串中的空格压缩为一个空格。 如果您只想删除\\r\\n\\t而不打扰其他空格,您可以使用translate()来删除字符。

trans_table = {ord(c): None for c in u'\r\n\t'}
item['DESCRIPTION] = ' '.join(s.translate(trans_table) for s in sel.xpath('//p[@class="class-name"]/text()').extract())

这仍然会留下不在集合\\r\\n\\t前导和尾随空格。 如果您还想摆脱它,只需插入对strip()的调用:

item['DESCRIPTION] = ' '.join(s.strip().translate(trans_table) for s in sel.xpath('//p[@class="class-name"]/text()').extract())

从 alibris.com 中提取价格的最简单示例是

response.xpath('normalize-space(//td[@class="price"]//p)').get()

当我使用scrapy抓取网页时,遇到同样的问题,我有两种方法可以解决这个问题。 首先使用replace()函数。 AS“response.xpath”返回列表格式,但替换函数仅操作字符串格式。所以我使用for循环将列表的每个项目作为字符串获取,替换每个项目中的'\\n''\\t',然后追加到新列表。

import re
test_string =["\n\t\t", "\n\t\t\n\t\t\n\t\t\t\t\t", "\n", "\n", "\n", "\n", "Do you like shopping?", "\n", "Yes, I\u2019m a shopaholic.", "\n", "What do you usually shop for?", "\n", "I usually shop for clothes. I\u2019m a big fashion fan.", "\n", "Where do you go shopping?", "\n", "At some fashion boutiques in my neighborhood.", "\n", "Are there many shops in your neighborhood?", "\n", "Yes. My area is the city center, so I have many choices of where to shop.", "\n", "Do you spend much money on shopping?", "\n", "Yes and I\u2019m usually broke at the end of the month.", "\n", "\n\n\n", "\n", "\t\t\t\t", "\n\t\t\t\n\t\t\t", "\n\n\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\t"]
print(test_string)
        # remove \t \n    
a = re.compile(r'(\t)+')     
b = re.compile(r'(\n)+')
text = []
for n in test_string:
    n = a.sub('',n)
    n = b.sub('',n)
    text.append(n)
print(text)
        # remove all ''
while '' in text:
    text.remove('')
print(text)

第二种方法使用map()和strip。map()函数直接处理列表,得到原始格式。python2中使用'Unicode',python3中改为'str',如下:

text = list(map(str.strip, test_string))
print(text)

strip 函数只删除字符串开头和结尾的\\n\\t\\r,而不是字符串中间的。它与remove 函数不同。

如果您想保留列表而不是所有联合字符串,则无需添加额外的步骤,您只需调用getall()代替get()

response.xpath('normalize-space(.//td[@class="price"]/text())').getall()

此外,您应该在最后添加text()

希望它可以帮助任何人!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM