2016-07-23 9 views
0

Ich arbeite an einem Scraping-Projekt mit Scrapy. Ich plane, einen Cache (Wörterbuch) der Gegenstände, die geschabt werden, unter Verwendung einiger der Gegenstandeigenschaften (abhängig von einigen Kriterien) zu implementieren, und dieser Zwischenspeicher wird schließlich als eine Akte auf der Scheibe gespeichert. Wenn scrapy gestartet wird, kann ich die Funktion spider_closed in piple.py verwenden, um den Cache aus der Datei zu laden und den geänderten Cache während des Schließens von scrapy (mit der Funktion spider_closed) zurück in die Datei zu laden. Während die Objekte gecrackt werden, wird der Cache geändert. Elemente werden zum Cache hinzugefügt, wenn die Elemente eindeutig sind. In pipelines.py, kann ich eine Variable myCache erstellen Sie den Cache aus dem Cache-Datei zu laden:Scrapy Pass Objekt von der Pipeline zu Spider

mycache = load_from(cache_file) 

Aber ich weiß nicht, wie myCache von pipelines.py zu mySpider.py passieren, so dass sie beide teilen eine einzelne Kopie von Mycache.

Irgendwelche Vorschläge?

Antwort

3
class CustomPipeline(object): 

    def __init__(self, spider): 
     # the spider now contains a cache object 
     spider.mycache = TheCacheObject() 

    @classmethod 
    def from_crawler(cls, crawler): 
     return cls(crawler.spider) 

    def process_item(self, item, spider): 
     spider.mycache = do_your_thing 
2

Was Sie sagen, ist möglich, aber es ist schlechtes Design. Ich weiß nicht, welche Aktionen Sie gemäß diesem Cache durchführen werden, aber was auch immer es ist, es sollte innerhalb dieser spezifischen Pipeline gemacht werden. Ein Konzept von Pipelines ist, dass jeder Pipeline-Schritt potentiell von vorherigen Schritten abhängt, aber nicht von irgendwelchen Schritten danach. Es ist ein bisschen so, als würde ich sagen, dass ich erst entscheiden werde, wenn ich die Zukunft kenne. Nicht gut! Außerdem ist es eine gute Design-Praxis, eine Pipeline-Stufe zu deaktivieren und den Rest des Systems zu arbeiten. Vor allem in Ihrem Fall, wo was Sie tun, ist Caching ... naja ... Caches sollten immer Leistungsoptimierungen sein und nicht die Funktionalität beeinträchtigen. Wie können Sie die Cache-Pipeline deaktivieren, ohne Ihre arme Spinne zu brechen?

Wie dem auch sei - ich verstehe, dass Pipelines nur Item s und ein möglicher Grund verarbeiten, die Sie vielleicht machen wollen einen Item Cache zurück zu Ihrer Spinne füttern, weil Sie Maßnahmen ergreifen wollen oder Request s beeinflussen. Dafür gibt es Spider Middleware s. Sie können z.B. trage sowohl Item s als auch Request s. Ich würde erwarten, dass, wenn Ihr Cache nicht vollständig mit einem Spider implementiert werden kann, es vollständig mit einem Spider Middleware implementiert werden kann.

class MyMiddleware(object): 
    def process_spider_output(self, response, result, spider): 
     for x in result: 
      if not isinstance(x, Request): 
       # Pass-throug all items 
       yield x 
      else: 
       if x.url not in self.urls_cache: 
        yield x 

SPIDER_MIDDLEWARES = { 
    'project.middlewares.MyMiddleware: 100, 
} 
Verwandte Themen