2016-02-09 16 views
14

私は\ r \ n \ t文字をスクラピースパイダーでストリップしようとしています。治療中のストリップ n t r

私は新しい行でいっぱいであり、私が望むことをしない "記述"オブジェクトを持っています:各記述をタイトルに一致させます。

マップ(unicode.strip())で試しましたが、実際には動作しません。病院に新しいことは、別の簡単な方法があるかどうか、または地図の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() 

しかし、それはエラーが発生しました。何が最善の方法ですか?

+0

こんにちは、「実際には機能しません」とはどういう意味ですか? 'strip()'は先頭と末尾の文字しか考慮しないので、文字列の中にあるものを取り除きたい場合は別の方法が必要です。それがあなたの問題なら、 're re(' [\ r \ n \ t] '、' '、' Hel \ nlo \ r! –

+0

私は 'ItemLoader'のhttp://doc.scrapy.org/en/latest/topics/loaders.htmlをチェックアウトして' Item'sの入力と出力を管理することをお勧めします – Granitosaurus

+0

QuentinPradetありがとう、実際にはポール答えはよかった、私はそれを知らなかった。そしてGranitosaurus私はその感謝を勉強します –

答えて

13

unicode.stripは始まりに過ぎないと文字列

リターンの終わり削除先頭と末尾の文字と文字列のコピーに空白文字を扱っています。 \n\r、または中央に\t

ありません。

あなたが(正規表現モジュールを使用して)、文字列内のこれらの文字を削除するには、カスタムメソッドを使用し、あるいは XPath's normalize-space()

先頭と末尾の空白を除去することにより正規化空白で引数の文字列を返すを使用することができますいずれか

空白文字のシーケンスを単一のスペースで置換する

例パイソンシェルセッション:

>>> 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"] 
>>> 
+0

私は空間全体を正規化したい: response.xpath( '。')。extract() これは動作するが、normalize-spaceを使う: response.xpath( 'normalize-space (。) ')。extract() のようなhtmlタグは削除されます、なぜですか? – Baks

+0

@Baks、['normalize-space(。)'](https://www.w3.org/TR/xpath/#function-normalize-space)は、スペース正規化[文字列値](https:// www.w3.org/TR/xpath/#element-nodes)。これは、子孫テキストノードの連結です。_ "要素ノードの文字列値は、すべてのテキストの文字列値の連結です要素ノードのノード子孫をドキュメント順に並べ替えます。 "_ –

4

ポールtrmbrthはin his answer

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

はあなたが望むものである可能性が高いとおり。しかし、normalize-spaceは、文字列に含まれる空白を1つのスペースに圧縮します。 \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()) 
+0

パーフェクト。私はこれについて知らなかったし、正規表現なしですべての空白問題を解決した。 – Echelon

+0

div.xpath( 'normalize-space(.// p [@ class = "クラス名"])')。extract() 私のために働いた、ありがとう。 –

3

を私のpython、scrapy初心者だけど、今日は同様の問題を持っていた、以下のモジュールの助けを借りてこれを解決/ function w3lib.html.replace_escape_charsアイテムローダーのデフォルト入力プロセッサーを作成しましたが、それは問題なく動作します。これを特定の処理にバインドすることができます。フィールド()も、cssセレクタとcsvフィードエクスポートでうまく動作します。

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