2016-02-09 20 views
14

Sto provando a spogliare \ r \ n \ t caratteri con uno spider rognoso, facendo quindi un file json.Strip n t r in scrapy

Ho un oggetto "description" che è pieno di nuove righe e non fa ciò che voglio: abbinare ciascuna descrizione a un titolo.

Ho provato con map (unicode.strip()) ma in realtà non funziona. Essendo nuovo di scrapy, non so se c'è un altro modo più semplice o come la mappa unicode funzioni davvero.

Questo è il mio codice:

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()) 

ho provato anche con:

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

Ma è sollevato un errore. Qual è il modo migliore?

+0

Ciao, cosa intendi per "non funziona davvero"? 'strip()' considera solo i caratteri iniziali e finali, quindi se si desidera rimuovere qualsiasi cosa all'interno della stringa è necessario un altro modo. 'import re' e' re.sub ('[\ r \ n \ t]', '', 'Hel \ nlo \ r!') 'potrebbe aiutarti se questo è il tuo problema. –

+0

Suggerisco di eseguire il checkout di 'ItemLoader's http://doc.scrapy.org/en/latest/topics/loaders.html che consente di gestire l'input e l'output di' Item's – Granitosaurus

+0

QuentinPradet grazie, in effetti, paul's la risposta era buona, non lo sapevo. E Granitosauro Lo studio grazie –

risposta

13

unicode.strip si occupa solo con i caratteri di spazio bianco all'inizio e alla fine di stringhe

ritorno una copia della stringa con i caratteri iniziali e finali rimossi.

non con \n, \r o \t nel mezzo.

È possibile utilizzare un metodo personalizzato per rimuovere tali caratteri nella stringa (utilizzando il modulo espressione regolare), o anche utilizzare XPath's normalize-space()

restituisce la stringa di argomento con spazi normalizzato mediante stripping spazi iniziali e finali e sostituendo sequenze di caratteri di spazi bianchi con un singolo spazio.

Esempio sessione di shell Python:

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

Voglio normalizzare-spazio intero corpo: response.xpath ('.'). Extract() Questo funziona, ma usando lo spazio di normalizzazione: response.xpath ('normalize-space (.) '). extract() tag html come vengono rimossi, perché? – Baks

+0

@Baks, ['normalize-space (.)'] (Https://www.w3.org/TR/xpath/#function-normalize-space) restituisce il valore [valore stringa] normalizzato dallo spazio (https: // www.w3.org/TR/xpath/#element-nodes) del nodo di contesto, che è una concatenazione di nodi di testo discendenti: _ "Il valore di stringa di un nodo di elemento è la concatenazione dei valori di stringa di tutto il testo discendenti nodo del nodo elemento nell'ordine del documento. "_ –

4

come Paul trmbrth suggerisce in his answer,

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

è probabile che sia quello che vuoi. Tuttavia, normalize-space condensa anche gli spazi bianchi contenuti nella stringa in un unico spazio. Se si desidera solo rimuovere \r, \n e \t senza disturbare gli altri spazi bianchi, è possibile utilizzare translate() per rimuovere i caratteri.

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()) 

Questo sarà ancora lasciare spazi bianchi iniziali e finali che non è nel set \r, \n o \t. Se anche voi volete essere liberarsi di quel basta inserire una chiamata a strip():

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

Perfetto. Non ho mai saputo di questo e ha risolto tutti i miei problemi di spazio bianco senza regex. – Echelon

+0

div.xpath ('normalize-space (.// p [@ class = "nome-classe"])'). Extract() ha funzionato per me, grazie. –

3

Sono un pitone, Scrapy newbie, ho avuto un problema simile oggi, risolto questo con l'aiuto di modulo successivo/function w3lib.html.replace_escape_chars Ho creato un processore di input predefinito per il mio programma di caricamento degli oggetti e funziona senza problemi, è possibile associarlo allo scrapy specifico.Anche Field() e la cosa buona funziona con selettori CSS e esportazioni di feed CSV:

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