2016-11-15 1 views
0

Ich benutze Scrapy 1.2 mit Xpath (und natürlich: python 3.4), um das Hot 100 Diagramm auf billboard.com zu lesen. Ich bekomme alle 100 Titel für jeden Song, wenn ich die zweite Option im Code verwende. Ich verstehe das wegen der doppelten /; aber ich kann die erste Option nicht funktionieren lassen. Wie kann ich sicherstellen, dass ich nur den richtigen Titel für jedes Lied bekomme?Xpath mit scrapy: Ich bekomme alles hundert mal

class MusicalSpider(scrapy.Spider): 
    name = "musicalspider" 
    allowed_domains = ["billboard.com"] 
    start_urls = ['http://www.billboard.com/charts/hot-100/'] 

    def parse(self, response): 
     songs = response.xpath('//div[@class="chart-data js-chart-data"]/div[@class="container"]/article') 

     for song in songs: 
      item = MusicItem() 
      # first option: 
      item['title'] = song.xpath('div[@class="chart-row__primary"]/div[@class="chart-row__main-display"]/div[@class="chart-row__container"]/div[@class="chart-row__title"]/h2[@class="chart-row__song"]').extract() 
      # second option: 
      item['title'] = song.xpath('//h2[@class="chart-row__song"]').extract() 

      yield item 

Antwort

3

Dies ist ein ziemlich häufiges Problem. Denken Sie daran, Ihre innere Schleife XPath-Ausdrücke mit einem Punkt zu beginnen - dies würde sie kontextspezifische machen:

for song in songs: 
    item = MusicItem() 
    # first option: 
    item['title'] = song.xpath('.//div[@class="chart-row__primary"]/div[@class="chart-row__main-display"]/div[@class="chart-row__container"]/div[@class="chart-row__title"]/h2[@class="chart-row__song"]').extract() 
    # second option: 
    item['title'] = song.xpath('.//h2[@class="chart-row__song"]').extract() 

    yield item 

Mehr unter:


Hier ist die Spinne, die für mich funktioniert:

import scrapy 

class MusicalSpider(scrapy.Spider): 
    name = "musicalspider" 
    allowed_domains = ["billboard.com"] 
    start_urls = ['http://www.billboard.com/charts/hot-100/'] 

    def parse(self, response): 
     songs = response.xpath('//div[@class="chart-data js-chart-data"]/div[@class="container"]/article') 

     for song in songs: 
      item = MusicItem() 
      item['title'] = song.xpath('.//h2[@class="chart-row__song"]/text()').extract_first() 
      yield item 

Es produziert die folgenden Elemente:

{'title': u'Black Beatles'} 
{'title': u'Closer'} 
... 
{'title': u'Hold Up'} 
{'title': u'Gangsta'} 
+0

Nein, beide Optionen geben Sie mir leere Listen – Celebrian

+2

@ user7162453: Antwort im Wesentlichen richtig ist, aber Ihre XPaths zusätzliche Probleme haben können. – kjhughes

+1

@ user7162453 die Idee ist richtig, die XPath-Ausdrücke selbst sollten wahrscheinlich angepasst werden, lass mich das testen. – alecxe

Verwandte Themen