簡體   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