2016-07-17 7 views
0

Die folgende Spinne mit festen start_urls Arbeiten bestanden:In scrapy ‚start_urls‘ definiert nicht, wenn sie als Eingabeargument

import scrapy 
from scrapy.spiders import CrawlSpider, Rule 
from scrapy.linkextractors import LinkExtractor 

class NumberOfPagesSpider(CrawlSpider): 
    name = "number_of_pages" 
    allowed_domains = ["funda.nl"] 

    # def __init__(self, place='amsterdam'): 
    #  self.start_urls = ["http://www.funda.nl/koop/%s/" % place] 

    start_urls = ["http://www.funda.nl/koop/amsterdam/"] 

    le_maxpage = LinkExtractor(allow=r'%s+p\d+' % start_urls[0]) 

    rules = (Rule(le_maxpage, callback='get_max_page_number'),) 

    def get_max_page_number(self, response): 
     links = self.le_maxpage.extract_links(response) 
     max_page_number = 0             # Initialize the maximum page number 
     for link in links: 
      if link.url.count('/') == 6 and link.url.endswith('/'):   # Select only pages with a link depth of 3 
       page_number = int(link.url.split("/")[-2].strip('p'))  # For example, get the number 10 out of the string 'http://www.funda.nl/koop/amsterdam/p10/' 
       if page_number > max_page_number: 
        max_page_number = page_number       # Update the maximum page number if the current value is larger than its previous value 
     filename = "max_pages.txt"       # File name with as prefix the place name 
     with open(filename,'wb') as f: 
      f.write('max_page_number = %s' % max_page_number)    # Write the maximum page number to a text file 

Wenn ich es von scrapy crawl number_of_pages laufen, schreibt es eine TXT-Datei wie erwartet. Allerdings, wenn ich es ändern in den Linien durch Kommentierung und die start_urls = Linie Kommentierung aus, und versuchen Sie es mit einem benutzerdefinierten Eingabeargument zu laufen,

scrapy crawl number_of_pages -a place=amsterdam 

ich die folgende Fehlermeldung erhalten:

le_maxpage = LinkExtractor(allow=r'%s+p\d+' % start_urls[0]) 
NameError: name 'start_urls' is not defined 

Also nach dem Spider, start_urls ist nicht definiert, obwohl in dem Code ist es vollständig in der Initialisierung bestimmt. Wie kann ich diese Spinne mit start_urls durch ein Eingabeargument definiert arbeiten?

Antwort

2

Ihre le_maxpage ist eine Klassenvariable. Wenn Sie das Argument an __init__ übergeben, erstellen Sie eine Instanzenvariable start_urls.

Sie verwendet start_urls in le_maxpage, so dass für die le_maxpage Variable zu arbeiten, muss es eine Klassenstufe Variable start_urls benannt sein.

Um dieses Problem zu beheben, müssen Sie Ihre Variablen auf Klassenebene auf Instanzenebene verschieben, dh sie im Block __init__ definieren.

+0

Hi masnun, ich habe versucht, einfach die Zeilen 'le_maxpage' und' rules' zu Tabs zu bewegen, so dass sie sich innerhalb des Blocks '__init__' befinden, und dies bewirkt, dass die Spinne läuft. Es erzeugt jedoch die Datei 'max_pages.txt' nicht wie zuvor. Es scheint, als würde der 'Callback' niemals auftreten? –

+0

Weil deine Regeln jetzt nicht gesetzt sind. Sie können den Callback-Namen in 'Parse 'ändern und es sollte funktionieren. – masnun

1

Nach der Antwort von masnun konnte ich das beheben. Ich liste den aktualisierten Code der Vollständigkeit halber auf.

import scrapy 
from scrapy.spiders import CrawlSpider, Rule 
from scrapy.linkextractors import LinkExtractor 

class NumberOfPagesSpider(CrawlSpider): 
    name = "number_of_pages" 
    allowed_domains = ["funda.nl"] 

    def __init__(self, place='amsterdam'): 
     self.start_urls = ["http://www.funda.nl/koop/%s/" % place] 
     self.le_maxpage = LinkExtractor(allow=r'%s+p\d+' % self.start_urls[0]) 
     rules = (Rule(self.le_maxpage,),) 

    def parse(self, response): 
     links = self.le_maxpage.extract_links(response) 
     max_page_number = 0             # Initialize the maximum page number 
     for link in links: 
      if link.url.count('/') == 6 and link.url.endswith('/'):   # Select only pages with a link depth of 3 
       page_number = int(link.url.split("/")[-2].strip('p'))  # For example, get the number 10 out of the string 'http://www.funda.nl/koop/amsterdam/p10/' 
       if page_number > max_page_number: 
        max_page_number = page_number       # Update the maximum page number if the current value is larger than its previous value 
     filename = "max_pages.txt"       # File name with as prefix the place name 
     with open(filename,'wb') as f: 
      f.write('max_page_number = %s' % max_page_number)    # Write the maximum page number to a text file 

Beachten Sie, dass die Rule braucht nicht einmal ein callback weil parse wird immer dann aufgerufen.

Verwandte Themen