2016-07-09 9 views
3

gesetzt habe ich diese Regel für scrapy CrawlSpiderScrapy Regeln funktionieren nicht, wenn process_request und Callback-Parameter

rules = [ 
     Rule(LinkExtractor(
        allow= '/topic/\d+/organize$', 
        restrict_xpaths = '//div[@id= "zh-topic-organize-child-editor"]' 
        ), 
      process_request='request_tagPage', callback = "parse_tagPage", follow = True) 
    ] 

request_tagePage() bezieht sich auf eine Funktion Cookie in Anforderungen hinzufügen und parse_tagPage() bezieht sich auf eine Funktion Zielseiten zu analysieren. Laut documentation sollte CrawlSpider request_tagPage verwenden, um Anfragen zu stellen, und sobald Antworten zurückgegeben werden, ruft es parse_tagPage() auf, um es zu parsen. Allerdings erkannte ich, dass, wenn request_tagPage() verwendet wird, Spider nicht die parse_tagPage() überhaupt anrufen. So in den eigentlichen Code, ich manuell hinzufügen parse_tagPage() Callback-Funktion als Callback in request_tagPage, wie folgt aus:

def request_tagPage(self, request): 
    return Request(request.url, meta = {"cookiejar": 1}, \ # attach cookie to the request otherwise I can't login 
      headers = self.headers,\ 
      callback=self.parse_tagPage) # manually add a callback function. 

Es funktionierte, aber jetzt ist die Spinne nicht Regeln verwenden, um seine Crawling zu erweitern. Es schließt nach dem Crawlen die Links von start_urls. Bevor ich jedoch den parse_tagPage() als Rückruf in request_tagPage() manuell festlegen, funktionieren die Regeln. Also denke ich, dass das vielleicht ein Fehler ist? Ist eine Möglichkeit, request_tagPage() zu aktivieren, die ich anfügen muss, Cookie in der Anfrage, parse_tagPage(), die zum Parsen einer Seite verwendet und rules, die Spinne Crawlen steuert?

+1

Sind Sie sicher, Ihre linkextactor funktioniert auch? Öffnen Sie eine Website über 'scrapy shell url' und importieren Sie LinkExtractor und versuchen Sie es mit den gleichen Argumenten auf dem' response.body'. – Granitosaurus

+0

Es funktioniert. Wenn parse_tagPage() nicht als Rückruffunktion in request_tagPage() verwendet wird, sehe ich von der Konsole aus, dass Spider so durchsucht wird, wie es sein sollte. Von Scrapys [Dokumentation auf Rule-Objekt] (http://doc.scrapy.org/en/latest/topics/spiders.html?highlight=rule#scrapy.spiders.Rule) dachte ich parse_tagPage() als Callback für die Regel ist genug, es stellte sich heraus, Callback-Funktion wurde überhaupt nicht aufgerufen. Also muss ich Callback in die request_tagPage() setzen. Dann wird der Callbback aufgerufen, aber Spider verliert die Fähigkeit, Links zu folgen, außer denen in den start_urls. – Skywalker326

+0

Haben Sie versucht, das brandneue 'Request'-Objekt nicht zu konstruieren, sondern stattdessen' Request.replace() '? Z.B. 'request request.replace (meta = {'cookiejar': 1}, headers = self.headers)'. 'CrawlSpider' behandelt alle Seiten in seinem eigenen' parse() 'Callback, der Crawl-Regeln verarbeitet, so dass das Ändern des Callbacks muanuell nicht als ein guter Weg erscheint. – shirk3y

Antwort

1

Ich habe das Problem gefunden. CrawlSpider verwendet seinen Standardwert parse(), um die Regeln anzuwenden. Also, wenn meine benutzerdefinierte parse_tagPage() aufgerufen wird, gibt es keine weiteren parse() folgt, um weiterhin die Regeln anzuwenden. Lösung ist einfach, den Standard parse() in meine Gewohnheit parse_tagPage() hinzuzufügen. Es sieht nun wie folgt aus:

def parse_tagPage(self, response): 
    # parse the response, get the information I want... 
    # save the information into a local file... 
    return self.parse(response) # simply calls the default parse() function to enable the rules 
2

Anfragen von CrawlSpider Regeln erzeugt internal callbacks and use meta to do their "magic" verwenden.

Ich schlage vor, dass Sie Requests nicht von Grund auf in Ihren Regeln 'process_request Hooks neu erstellen (oder Sie werden wahrscheinlich end-up Reimplementierung, was für Sie bereits tut).

Stattdessen, wenn Sie nur wollen, Cookies und spezielle Header hinzufügen, können Sie .replace() method on the request verwenden, die request_tagPage übergeben wird, so dass die „Magie“ der CrawlSpider erhalten bleibt.

So etwas wie dies genug sein sollte:

def request_tagPage(self, request): 
    tagged = request.replace(headers=self.headers) 
    tagged.meta.update(cookiejar=1) 
    return tagged 
Verwandte Themen