2016-02-09 18 views
14

Próbuję usunąć \ r \ n \ t znaków z pająka scrapy, tworząc plik json.Strip n t r w scrapy

Mam obiekt "description", który jest pełen nowych linii i nie robi tego, co chcę: dopasowanie każdego opisu do tytułu.

Próbowałem z mapą (unicode.strip()), ale tak naprawdę nie działa. Będąc nowicjuszem w scrapy, nie wiem, czy jest inny prostszy sposób lub jak naprawdę działa kod Unicode.

To jest mój kod:

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

Próbowałem również z:

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

Ale podniesiony błąd. Jaki jest najlepszy sposób?

+0

Witam, co masz na myśli mówiąc "to tak naprawdę nie działa"? 'strip()' uwzględnia tylko znaki wiodące i końcowe, więc jeśli chcesz usunąć wszystko, co znajduje się wewnątrz łańcucha, potrzebujesz innego sposobu. 'import re' i' re.sub ('[\ r \ n \ t]', '', 'Hel \ nlo \ r!') 'może pomóc, jeśli to jest twój problem. –

+0

Proponuję wypróbować 'ItemLoader's http://doc.scrapy.org/en/latest/topics/loaders.html, które pozwolą Ci zarządzać wejściami i wyjściami Twojego produktu' Item's – Granitosaurus

+0

QuentinPradet dzięki, w rzeczywistości Paulowi odpowiedź była dobra, nie wiedziałem o tym. I Granitosaurus Będę studiować, że dzięki –

Odpowiedz

13

unicode.strip dotyczy wyłącznie białych znaków na początku i końcu ciągów

zwrócić kopię napisu z wiodących i końcowych znaków usunięte.

nie z \n, \r lub \t w środku.

Można użyć metody niestandardowej w celu usunięcia tych znaków wewnątrz łańcucha (za pomocą zwykłego modułu wyrażenie), lub nawet użyć XPath's normalize-space()

zwraca łańcuch argumentów ze spacjami znormalizowaną przez odpędzenie początkowe i końcowe spacje i zastępowanie sekwencji białych znaków pojedynczym odstępem.

Przykład python shell sesja:

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

Chcę znormalizować przestrzeń całego ciała: response.xpath ('.'). Extract() To działa, ale przy użyciu normalize-space: response.xpath ('normalize-space (.) "). extract() Tagi html jak są usuwane, dlaczego? – Baks

+0

@Baks, ['normalize-space (.)'] (Https://www.w3.org/TR/xpath/#function-normalize-space) zwraca znormalizowaną przestrzeń [wartość łańcucha] (https: // www.w3.org/TR/xpath/#element-nodes) węzła kontekstu, który jest konkatenacją węzłów tekstowych potomków: _ "Wartością łańcuchową węzła elementu jest łączenie wartości ciągu wszystkich tekstów węzeł potomny węzła elementu w porządku dokumentu. "_ –

4

jak Paul trmbrth sugeruje in his answer,

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

może być to, co chcesz. Jednakże, normalize-space również kondensuje białą przestrzeń zawartą w łańcuchu w jedną przestrzeń. Jeśli chcesz tylko usunąć \r, \n i \t bez zakłócania innych odstępów, możesz użyć translate() do usunięcia znaków.

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

ten będzie nadal pozostawić początkowe i końcowe białe znaki, które nie są w zestawie \r, \n lub \t. Jeśli chcesz się pozbyć, że po prostu wstawić wywołanie strip():

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

Idealny. Nigdy o tym nie wiedziałem i rozwiązał wszystkie moje problemy z białymi znakami bez wyrażeń regularnych. – Echelon

+0

div.xpath ('normalize-space (.// p [@ class = "class-name"])'). Extract() pracował dla mnie, dziękuję. –

3

Jestem python, scrapy początkujących, miałem podobny problem dzisiaj rozwiązać ten z pomocą poniższego modułu/function w3lib.html.replace_escape_chars Stworzyłem domyślny procesor wejściowy dla mojego programu ładującego elementy i działa bez żadnych problemów, możesz to powiązać z konkretnym scrapy.Field() również i dobrze działa z selektorami css i eksportem csv:

from w3lib.html import replace_escape_chars 
yourloader.default_input_processor = MapCompose(relace_escape_chars) 
Powiązane problemy