2016-09-29 6 views
0

Я бегу scrapy от python script.Scrapy - обработка деталей трубопроводом

мне сказали, что в scrapy, responses построены в parse() и дальнейшей обработке в pipeline.py.

это как мой framework установлено до сих пор:

питон скрипт

def script(self): 

     process = CrawlerProcess(get_project_settings()) 

     response = process.crawl('pitchfork_albums', domain='pitchfork.com') 

     process.start() # the script will block here until the crawling is finished 

пауков

class PitchforkAlbums(scrapy.Spider): 
    name = "pitchfork_albums" 
    allowed_domains = ["pitchfork.com"] 
    #creates objects for each URL listed here 
    start_urls = [ 
        "http://pitchfork.com/reviews/best/albums/?page=1", 
        "http://pitchfork.com/reviews/best/albums/?page=2", 
        "http://pitchfork.com/reviews/best/albums/?page=3"     
    ] 
    def parse(self, response): 

     for sel in response.xpath('//div[@class="album-artist"]'): 
      item = PitchforkItem() 
      item['artist'] = sel.xpath('//ul[@class="artist-list"]/li/text()').extract() 
      item['album'] = sel.xpath('//h2[@class="title"]/text()').extract() 

     yield item 

items.py

class PitchforkItem(scrapy.Item): 

    artist = scrapy.Field() 
    album = scrapy.Field() 

settings.py

ITEM_PIPELINES = { 
    'blogs.pipelines.PitchforkPipeline': 300, 
} 

pipelines.py

class PitchforkPipeline(object): 

    def __init__(self): 
     self.file = open('tracks.jl', 'wb') 

    def process_item(self, item, spider): 
     line = json.dumps(dict(item)) + "\n" 
     self.file.write(line) 
     for i in item: 
      return i['album'][0] 

, если я просто return item в pipelines.py, я получаю данные, как так (один response для каждой html страницы) :

{'album': [u'Sirens', 
      u'I Had a Dream That You Were Mine', 
      u'Sunergy', 
      u'Skeleton Tree', 
      u'My Woman', 
      u'JEFFERY', 
      u'Blonde/Endless', 
      u' A Mulher do Fim do Mundo (The Woman at the End of the World) ', 
      u'HEAVN', 
      u'Blank Face LP', 
      u'blackSUMMERS\u2019night', 
      u'Wildflower', 
      u'Freetown Sound', 
      u'Trans Day of Revenge', 
      u'Puberty 2', 
      u'Light Upon the Lake', 
      u'iiiDrops', 
      u'Teens of Denial', 
      u'Coloring Book', 
      u'A Moon Shaped Pool', 
      u'The Colour in Anything', 
      u'Paradise', 
      u'HOPELESSNESS', 
      u'Lemonade'], 
'artist': [u'Nicolas Jaar', 
      u'Hamilton Leithauser', 
      u'Rostam', 
      u'Kaitlyn Aurelia Smith', 
      u'Suzanne Ciani', 
      u'Nick Cave & the Bad Seeds', 
      u'Angel Olsen', 
      u'Young Thug', 
      u'Frank Ocean', 
      u'Elza Soares', 
      u'Jamila Woods', 
      u'Schoolboy Q', 
      u'Maxwell', 
      u'The Avalanches', 
      u'Blood Orange', 
      u'G.L.O.S.S.', 
      u'Mitski', 
      u'Whitney', 
      u'Joey Purp', 
      u'Car Seat Headrest', 
      u'Chance the Rapper', 
      u'Radiohead', 
      u'James Blake', 
      u'White Lung', 
      u'ANOHNI', 
      u'Beyonc\xe9']} 

, что я хотел бы сделать в pipelines.py, чтобы иметь возможность получать индивидуальные songs для каждого item, например, так:

[u'Sirens'] 

пожалуйста, помогите?

+0

Можете ли вы предоставить большую ясность в выходной части? –

ответ

3

Предлагаю вам построить хорошо структурированный item в пауке. В рабочем режиме Scrapy Framework паук используется для построения хорошо сформированного элемента, например, parse html, заполнения экземпляров элементов, а конвейер используется для выполнения операций над элементом, например, элементом фильтра, элементом хранения.

Для вашего приложения, если я правильно понимаю, каждый элемент должен быть записью для описания альбома. Поэтому, когда вы обрабатываете html, вам лучше создать такой предмет, вместо того, чтобы массировать все в элемент.

Так что в вашем spider.py, parse функции, вы должны

  1. Помещенный yield item заявление в петле for, НЕ СНАРУЖИ. Таким образом, каждый альбом будет генерировать элемент.
  2. Будьте осторожны с относительным выбором xpath в Scrapy. Если вы хотите использовать относительный селектор xpath для указания self-and-descendant, используйте .// вместо //, а для указания self используйте ./ вместо /.
  3. Идеально название альбома должно быть скаляром, альбом должен быть списком, поэтому попробуйте extract_first, чтобы название альбома было скаляром.

    def parse(self, response): 
    for sel in response.xpath('//div[@class="album-artist"]'): 
        item = PitchforkItem() 
        item['artist'] = sel.xpath('./ul[@class="artist-list"]/li/text()').extract_first() 
        item['album'] = sel.xpath('./h2[@class="title"]/text()').extract() 
        yield item 
    

Надеется, что это было бы полезно.

+0

, если я помещаю его в 'for loop', я получаю избыточный' output', тот же 'n' перечисляет повторное время' n times'. но как я могу «перебирать», чтобы изолировать ** одну ** дорожку? –

+0

Ваш селектор xpath неверен, удалите '//' и повторите попытку! Я исправляю решение. Вот пример моего текущего результата: '{'album': [u'Sirens '],' artist ': [u'Nicolas Jaar'}} {'album': [u'I Hed Dream That Вы были шахтой '],' художник ': [u'Hamilton Leithauser', u'Rostam ']} {' альбом ': [u'Sunergy'], 'artist': [u'Kaitlyn Aurelia Smith ',' u'Suzanne Ciani ']} ' – rojeeer

+0

В идеале название альбома должно быть скаляром, а художник должен быть списком. Вы можете сделать немного больше изменений, например: 'item ['album'] = sel.xpath ('h2 [@ class =" title "]/text()'). Extract() [0]' – rojeeer

Смежные вопросы