2016-09-29 50 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