2017-04-09 2 views
-4

Als Anfänger zu scrapy konnte ich nicht herausfinden, warum diese Spinne Daten von einer Website nicht crawlen. Ich habe über stackoverflow nach möglichen Antworten gesucht, aber ich sehe, dass es nicht angemessen adressiert wird. Ich versuche, eine kleine Stadt-Restaurant Liste von der Website zu kratzen. Ich habe keine detaillierten Kenntnisse über die Sicherheitsmerkmale der Website zu scrape.Ist das Problem mit den XPath-Auswahlelementen verbunden? Die Spinne läuft gut, außer es kratzt nichts. Können Sie bitte vorschlagen, warum es nicht kratzt und wie man das Problem löst. Die Spinne hat den folgenden Code:scrapy/Python kriecht, kratzt aber nicht Daten

try: 
    from scrapy.spiders import Spider 
    from urllib.parse import urljoin 
    from scrapy.selector import Selector 
    from scrapy.http import Request 

except ImportError: 
    print ("\nERROR IMPORTING THE NESSASARY LIBRARIES\n") 

#scrapy.optional_features.remove('boto') 


class YelpSpider(Spider): 
    name = 'yelp_spider' 
    allowed_domains=["yelp.com"] 
    headers=['venuename','services','address','phone','location'] 

    def __init__(self): 
     self.start_urls = ['https://www.yelp.com/springfield-il-us'] 

    def start_requests(self): 
     requests = [] 
     for item in self.start_urls: 
      requests.append(Request(url=item, headers={'Referer':'http://www.google.com/'})) 
      return requests 

    def parse(self, response): 
     requests=[] 
     sel=Selector(response) 
     restaurants=sel.xpath('//*[@id="wrap"]/div[4]/div/div[1]/div/div[3]/div[1]/div[1]/h1') 
     items=[] 
     for restaurant in restaurants: 
      item=YelpRestaurantItem() 
      item['venuename']=sel.xpath('//*[@id="wrap"]/div[4]/div/div[1]/div/div[3]/div[1]/div[1]/h1') 
      item['services']=sel.xpath('//*[@id="wrap"]/div[4]/div/div[1]/div/div[3]/div[1]/div[2]/div[2]/span[2]/a[1]') 
      item['address']=sel.xpath('//*[@id="wrap"]/div[4]/div/div[1]/div/div[4]/div[1]/div/div[2]/ul/li[1]/div/strong/address') 
      item['phone']=sel.xpath('//*[@id="wrap"]/div[4]/div/div[1]/div/div[4]/div[1]/div/div[2]/ul/li[3]/span[3]') 
      item['location']=sel.xpath('//*[@id="dropperText_Mast"]') 
      item['url']=response.url 
      items.append(item) 
      yield item 

Mein items.py hat den folgenden Code ein:

import scrapy 

class YelpRestaurantItem(scrapy.Item): 
    # define the fields for your item here like: 
    # name = scrapy.Field() 
    url=scrapy.Field() 
    venuename = scrapy.Field() 
    services = scrapy.Field() 
    address = scrapy.Field() 
    phone = scrapy.Field() 
    location=scrapy.Field() 

scrapy-code-does-not-scrape-any-data

+0

Ich nehme an, dass Sie Probleme mit dem Einzug haben, bitte korrigieren Sie Ihren Code in der Frage. Und haben Sie versucht, Ihren Code zu debuggen? vielleicht etwas in jeder Iteration von "für Restaurant ..." drucken? – eLRuLL

+0

Was versuchen Sie zu kratzen? Die Spinne sucht nach etwas mit einem ID-Attribut, das "wrap" ist, aber wenn ich die Start-URL öffne, finde ich nichts, was dazu passt. – Casper

+0

@Casper, ich versuche Name, Dienste, Adresse, Telefon, Standort zu kratzen. Ich sollte auch sagen, dies ist das erste Mal, dass ich Xpath und Scrapy benutze.Ich habe gerade den xpath für ein Restaurant kopiert, das in Chrome/Developer Tools hervorgehoben wurde. Ich wollte jedoch eine Liste von Restaurantbetrieben in dieser kleinen Stadt hervorheben, nämlich Name, Dienstleistungen, Adresse, Telefon und Standort. – Kaleab

Antwort

0

Ihre Importe hier, dass auch nicht funktioniert hat, aber das könnte sein ein Konfigurationsproblem auf meiner Seite. Ich denke, die Schaber unten tut, was Sie suchen:

import scrapy 

class YelpSpider(scrapy.Spider): 
    name = 'yelp_spider' 
    allowed_domains=["yelp.com"] 
    headers=['venuename','services','address','phone','location'] 

    def __init__(self): 
     self.start_urls = ['https://www.yelp.com/search?find_desc=&find_loc=Springfield%2C+IL&ns=1'] 

    def start_requests(self): 
     requests = [] 
     for item in self.start_urls: 
      requests.append(scrapy.Request(url=item, headers={'Referer':'http://www.google.com/'})) 
      return requests 

    def parse(self, response): 
     for restaurant in response.xpath('//div[@class="biz-listing-large"]'): 
      item={} 
      item['venuename']=restaurant.xpath('.//h3[@class="search-result-title"]/span/a/span/text()').extract_first() 
      item['services']=u",".join(line.strip() for line in restaurant.xpath('.//span[@class="category-str-list"]/a/text()').extract()) 
      item['address']=restaurant.xpath('.//address/text()').extract_first() 
      item['phone']=restaurant.xpath('.//span[@class="biz-phone"]/text()').extract_first() 
      item['location']=response.xpath('.//input[@id="dropperText_Mast"]/@value').extract_first() 
      item['url']=response.url 
      yield item 

Einige Erklärung:

ich die Start-URL geändert haben. Diese URL bietet tatsächlich einen Überblick über alle Restaurants, während die andere nicht (oder zumindest nicht von meinem Standort aus gesehen).

Ich habe die Pipeline entfernt, da sie nicht in meinem System definiert war und ich konnte es nicht mit der nicht vorhandenen Pipeline im Code ausprobieren.

Die Parse-Funktion ist die, an der ich die wirklichen Änderungen vorgenommen habe. Die von Ihnen definierten XPaths waren nicht sehr klar. Jetzt läuft der Code über jedes gelistete Restaurant.

response.xpath('//div[@class="biz-listing-large"]') 

Dieser Code erfasst alle Daten des Restaurants. Ich habe dies in einer for-Schleife verwendet, so dass wir Aktionen für jedes Restaurant durchführen können. Diese Daten sind in der Variablen restaurant verfügbar.

Also wenn ich Daten aus einem Restaurant extrahieren möchte, verwende ich diese Variable. Außerdem müssen wir den xpath mit einer . starten, weil das Skript sonst vom Anfang der Webseite an beginnt (was dasselbe wäre wie die Verwendung der Antwort).

Um die XPaths in meiner Antwort zu verstehen, könnte ich Ihnen das erklären, aber es gibt eine Menge Dokumentation, die sie wahrscheinlich besser erklären können als ich.

Some documentation

And some more

Bitte beachte, dass ich Restaurant für die meisten Werte von item verwendet haben. Werte von Ort und URL sind nicht wirklich Restaurant Daten, sondern befinden sich an anderer Stelle auf der Webseite. Aus diesem Grund verwenden diese Werte response anstelle von restaurant.

+0

Vielen Dank für Ihre engagierte Antwort, es hat funktioniert, obwohl es "Telefon" und "Adresse" nicht kratzen, kann Syntaxfehler sein? – Kaleab

+0

Haben Sie Änderungen am Code vorgenommen? Wenn ich den Crawler hier laufen lasse, werden alle definierten Eigenschaften des Elements zurückgegeben. – Casper

+0

Der Code wird wie vorgeschlagen verwendet. Er füllt die anderen Felder mit Ausnahme von 'Telefon' und 'Adresse'. – Kaleab

Verwandte Themen