Scrapy CrawlSpider - Fehler bei start_urls

Sep 23 2020

Ich benutze CrawlSpidermit Regel linksxtractor das hat errback.

Ich benutze es parse_start_url, um das analysieren zu können, start_urlsaber ich brauche es auch errbackfür sie.

class CS(CrawlSpider):
    name = "CS"
    rules = (Rule(LinkExtractor(allow=[], deny=[]), follow=True, callback='my_parse', errback='my_errback'),)           
    custom_settings = {
        'DEPTH_LIMIT': 3,
        #etc
    }
    
    start_urls = ['url']
    allowed_domains = ['domain']
    
    def my_errback(self, failure):
        # log all failures
    
    def parse_start_url(self, response):
        return self.my_parse(response)

    def my_parse(self, response):
        # parse responses

Das Problem, mit dem ich konfrontiert bin, ist, dass der Errback NUR für die extrahierten Links und NICHT für die start_urls aufgerufen wird.

Ich kann die Methode start_requests (wie unten beschrieben) nicht verwenden, da ich CrawlSpider und Regeln verwende. Wenn ich das tue, werden nur die start_urls abgekratzt:

def start_requests(self):
            for u in self.start_urls:
                yield scrapy.Request(u, callback=self.my_parse,
                                        errback=self.my_errback)

Antworten

J_Z Sep 24 2020 at 07:20

Das ist die Antwort: https://stackoverflow.com/a/34345668/13903397

Grundsätzlich müssen wir start_requestsden Callback-Parameter verwenden, aber entfernen. Auf diese Weise wird die Standardeinstellung self.parse aufgerufen und die Regeln werden eingehalten.

class CS(CrawlSpider):
    name = "CS"
    rules = (Rule(LinkExtractor(allow=[], deny=[]), follow=True, callback='my_parse', errback='my_errback'),)           
    custom_settings = {
        'DEPTH_LIMIT': 3,
        #etc
    }
    
    start_urls = ['url']
    allowed_domains = ['domain']

    def start_requests(self):
        for u in self.start_urls:
            yield scrapy.Request(u, errback=self.my_errback)
    
    def my_errback(self, failure):
        # log all failures
    
    def parse_start_url(self, response):
        return self.my_parse(response)

    def my_parse(self, response):
        # parse responses