2016-09-29 28 views
0

我從python script運行scrapyScrapy - 用管道加工物品

有人告訴我,在scrapy,responses建在parse()和進一步處理在pipeline.py

這是我的framework怎麼是迄今爲止設置:

python腳本

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 itempipelines.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做的是能夠爲每個item獲取個人songs,就像這樣:

[u'Sirens'] 

請幫助?

+0

您能否提供更清晰的輸出部分? –

回答

3

我建議你在蜘蛛中構建結構良好的item。在Scrapy Framework工作流程中,spider用於構建格式良好的項目,例如解析html,填充項目實例和管道用於對項目執行操作,例如篩選項目,存儲項目。

對於您的應用程序,如果我理解正確,每個項目應該是一個條目來描述一個相冊。因此,在製作html時,最好製作這種類型的項目,而不是將所有內容都集中到項目中。

spider.pyparse功能

所以,你應該

  1. yield item聲明中for循環,不在外面。這樣,每張專輯將生成一個項目。
  2. 請注意Scrapy中的相對xpath選擇器。如果要使用相對xpath選擇器指定自我和後代,請使用.//而不是//,並指定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循環中',我得到一個多餘的'output',同樣的'n'列出重複次數'n次'。但我怎麼'迭代'爲了隔離**一個**軌道? –

+0

您的xpath選擇器不正確,請移除'//'並重試!我重新編輯解決方案。這裏是我的跑步結果的樣本:'{'專輯':[u'Sirens'],'藝術家':[u'Nicolas Jaar']} {'album':[u'I'a Dream that你是我的'],'藝術家':[u'Hamilton Leithauser',u'Rostam']} {'album':[u'Sunergy'],'artist':[u'Kaitlyn Aurelia Smith', u'Suzanne Ciani']} ' – rojeeer

+0

理想情況下,專輯標題應該是標量,藝術家應該是一個列表。你可以做一些修改來完成,例如'item ['album'] = sel.xpath('h2 [@ class =「title」]/text()')。extract()[0]' – rojeeer