2016-08-08 53 views
0

Ich baue einen rekursiven Webspider mit einem optionalen Login. Ich möchte die meisten Einstellungen dynamisch über eine JSON-Konfigurationsdatei vornehmen.scrapy InitSpider: Regeln in __init__ setzen?

In meiner __init__ Funktion, ich lese diese Datei und versuchen, alle Variablen zu füllen, funktioniert jedoch nicht mit Rules.

class CrawlpySpider(InitSpider): 

... 

#---------------------------------------------------------------------- 
def __init__(self, *args, **kwargs): 
    """Constructor: overwrite parent __init__ function""" 

    # Call parent init 
    super(CrawlpySpider, self).__init__(*args, **kwargs) 

    # Get command line arg provided configuration param 
    config_file = kwargs.get('config') 

    # Validate configuration file parameter 
    if not config_file: 
     logging.error('Missing argument "-a config"') 
     logging.error('Usage: scrapy crawl crawlpy -a config=/path/to/config.json') 
     self.abort = True 

    # Check if it is actually a file 
    elif not os.path.isfile(config_file): 
     logging.error('Specified config file does not exist') 
     logging.error('Not found in: "' + config_file + '"') 
     self.abort = True 

    # All good, read config 
    else: 
     # Load json config 
     fpointer = open(config_file) 
     data = fpointer.read() 
     fpointer.close() 

     # convert JSON to dict 
     config = json.loads(data) 

     # config['rules'] is simply a string array which looks like this: 
     # config['rules'] = [ 
     # 'password', 
     # 'reset', 
     # 'delete', 
     # 'disable', 
     # 'drop', 
     # 'logout', 
     # ] 

     CrawlpySpider.rules = (
      Rule(
       LinkExtractor(
        allow_domains=(self.allowed_domains), 
        unique=True, 
        deny=tuple(config['rules']) 
       ), 
       callback='parse', 
       follow=False 
      ), 
     ) 

Scrapy kriecht noch an den Seiten, die in config['rules'] vorhanden sind und deshalb trifft auch die logout Seite. Die angegebenen Seiten werden nicht abgelehnt. Was fehlt mir hier?

Update:

ich bereits versucht haben, durch CrawlpySpider.rules = ... sowie self.rules = ... innerhalb __init__ Einstellung. Beide Varianten funktionieren nicht.

  • Spider: InitSpider
  • Regeln: LinkExtractor
  • Vor Crawl: vor Doing Login

kriechen ich auch versuchen, dass

in meiner parse Funktion zu verweigern
# Dive deeper? 
    # The nesting depth is now handled via a custom middle-ware (middlewares.py) 
    #if curr_depth < self.max_depth or self.max_depth == 0: 
    links = LinkExtractor().extract_links(response) 
    for link in links: 
     for ignore in self.ignores: 
      if (ignore not in link.url) and (ignore.lower() not in link.url.lower()) and link.url.find(ignore) == -1: 
       yield Request(link.url, meta={'depth': curr_depth+1, 'referer': response.url}) 

Antwort

0

Sie sind Festlegen eines Klassenattributs, für das ein Instanzattribut festgelegt werden soll:

# this: 
CrawlpySpider.rules = (
# should be this: 
self.rules = (
<...> 
+0

Ich habe das auch ausprobiert und es hat nicht funktioniert. Ich habe diese Information zu meiner Frage hinzugefügt. – cytopia

+0

InitSpider scheint nicht so etwas wie '_compile_rules' zu haben (wie auch CrawlSpider). Offenbar sieht es so aus, als ob InitSpider nicht einmal Regeln hat, da es nur von Spider erbt. CrawlSpider implementiert all dies. – cytopia