[PYTHON] Starten Sie mit Scrapy neu

Scrapy, ein Python-Framework zum Crawlen von Websites, kann neu gestartet, dh während der Ausführung unterbrochen und dann von der vorherigen Fortsetzung fortgesetzt werden. Dies ist nützlich, wenn Sie eine große Anzahl von Seiten besuchen und zeitaufwändiges Scraping durchführen.

Unten finden Sie die offizielle Dokumentation. Jobs: pausing and resuming crawls

Funktionsübersicht

Ich habe die folgende Spinne vorbereitet, um die Funktion auszuprobieren. http://quotes.toscrape.com 6 Laden Sie einfach die Seite herunter und protokollieren Sie den Inhalt.

toscrape-restart.py


import scrapy
import json
import time


class QuotesSpider(scrapy.Spider):
    name = "toscrape-restart"

    custom_settings = {
        #Nicht parallel anfordern
        "CONCURRENT_REQUESTS": 1,
        #Legen Sie Intervalle für Anforderungen fest, damit diese leichter unterbrochen werden können
        "DOWNLOAD_DELAY": 10,
        # http://quotes.toscrape.Roboter auf com.Erhalten Sie txt nicht, da es nicht existiert
        "ROBOTSTXT_OBEY": False,
    }

    def start_requests(self):
        #Zustand zwischen Chargen beibehalten (siehe unten)
        self.logger.info(self.state.get("state_key1"))
        self.state["state_key1"] = {"key": "value"}
        self.state["state_key2"] = 0

        urls = [
            "http://quotes.toscrape.com/page/1/",
            "http://quotes.toscrape.com/page/2/",
            "http://quotes.toscrape.com/page/3/",
            "http://quotes.toscrape.com/page/4/",
            "http://quotes.toscrape.com/page/5/",
            "http://quotes.toscrape.com/page/6/",
        ]
        for url in urls:
            yield scrapy.Request(url=url, callback=self.parse)

    def parse(self, response):
        self.logger.info(
            "first quote author: " + response.css("small.author::text").get()
        )

Die obige Spinne kann mit dem folgenden Befehl gestartet werden.

scrapy crawl toscrape-restart

Dies ist eine normale Ausführung. Stellen Sie JOBDIR wie folgt ein, um es neu zu starten.

scrapy crawl toscrape-restart -s JOBDIR=crawls/restart-1

Dadurch wird ein Verzeichnis "crawls / restart-1" erstellt, in dem Informationen für Neustarts gespeichert werden und ein Neustart möglich ist. (Wenn kein Verzeichnis vorhanden ist, erstellt Scrapy es, sodass Sie es nicht im Voraus vorbereiten müssen.) Beginnen Sie mit dem obigen Befehl und unterbrechen Sie ihn während der Ausführung mit "Strg-C". Wenn Sie beispielsweise sofort nach dem Abrufen der ersten Seite anhalten, lautet die Ausgabe wie folgt.

$ scrapy crawl toscrape-restart -s JOBDIR=crawls/restart-1

(Weggelassen)

2020-03-24 14:43:04 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://quotes.toscrape.com/page/1/> (referer: None)
2020-03-24 14:43:04 [toscrape-restart] INFO: first quote author: Albert Einstein
^C2020-03-24 14:43:06 [scrapy.crawler] INFO: Received SIGINT, shutting down gracefully. Send again to force 
2020-03-24 14:43:06 [scrapy.core.engine] INFO: Closing spider (shutdown)
2020-03-24 14:43:18 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://quotes.toscrape.com/page/2/> (referer: None)
2020-03-24 14:43:18 [toscrape-restart] INFO: first quote author: Marilyn Monroe
2020-03-24 14:43:19 [scrapy.statscollectors] INFO: Dumping Scrapy stats:

(Weggelassen)

Es wurde unterbrochen, als ich die zweite Seite bekam. Nachdem Sie auf diese Weise unterbrochen haben, können Sie fortfahren, indem Sie denselben Befehl wie den ersten ausführen.

$ scrapy crawl toscrape-restart -s JOBDIR=crawls/restart-1

(Weggelassen)

2020-03-24 14:46:07 [scrapy.dupefilters] DEBUG: Filtered duplicate request: <GET http://quotes.toscrape.com/page/1/> - no more duplicates will be shown (see DUPEFILTER_DEBUG to show all duplicates)
2020-03-24 14:46:10 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://quotes.toscrape.com/page/3/> (referer: None)
2020-03-24 14:46:10 [toscrape-restart] INFO: first quote author: Pablo Neruda
2020-03-24 14:46:21 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://quotes.toscrape.com/page/4/> (referer: None)
2020-03-24 14:46:21 [toscrape-restart] INFO: first quote author: Dr. Seuss
2020-03-24 14:46:35 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://quotes.toscrape.com/page/5/> (referer: None)
2020-03-24 14:46:35 [toscrape-restart] INFO: first quote author: George R.R. Martin
2020-03-24 14:46:47 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://quotes.toscrape.com/page/6/> (referer: None)
2020-03-24 14:46:47 [toscrape-restart] INFO: first quote author: Jane Austen
2020-03-24 14:46:47 [scrapy.core.engine] INFO: Closing spider (finished)
2020-03-24 14:46:47 [scrapy.statscollectors] INFO: Dumping Scrapy stats:

(Weggelassen)

Die 1. und 2. Seite wurden als "Gefilterte doppelte Anforderung" angezeigt und nicht abgerufen. Danach wurden die dritte und die folgenden Seiten, die vor der Unterbrechung nicht erfasst wurden, normal erfasst.

Zustand zwischen Chargen beibehalten

Scrapy-Neustart hat die Fähigkeit, Informationen zwischen Booten mit "state" zu übertragen. Informationen können im Spider-Status gespeichert und beim nächsten Start referenziert werden. Insbesondere kann es in der folgenden Verwendung in der ersten "toscrape-restart.py" gespeichert werden.

self.state["state_key1"] = {"key": "value"}
self.state["state_key2"] = 0

Da "state" ein "dict type" ist, können Sie Operationen am Wörterbuch ausführen. Im obigen Beispiel ist der Wert "{" Schlüssel ":" Wert "}" im Schlüssel "state_key1" und der Wert "0" im Schlüssel "state_key2" gespeichert. Wenn ich es starte, sieht es so aus:

$ scrapy crawl toscrape-restart -s JOBDIR=crawls/restart-1

(Weggelassen)

2020-03-24 15:19:54 [toscrape-restart] INFO: None
2020-03-24 15:19:55 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://quotes.toscrape.com/page/1/> (referer: None)
2020-03-24 15:19:55 [toscrape-restart] INFO: first quote author: Albert Einstein
^C2020-03-24 15:19:56 [scrapy.crawler] INFO: Received SIGINT, shutting down gracefully. Send again to force 
2020-03-24 15:19:56 [scrapy.core.engine] INFO: Closing spider (shutdown)
2020-03-24 15:20:06 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://quotes.toscrape.com/page/2/> (referer: None)
2020-03-24 15:20:07 [toscrape-restart] INFO: first quote author: Marilyn Monroe
2020-03-24 15:20:07 [scrapy.statscollectors] INFO: Dumping Scrapy stats:

(Weggelassen)

Das INFO-Protokoll "Keine" wird in der ersten Zeile ausgegeben. Dies wird von "self.logger.info (self.state.get (" state_key1 "))" ausgegeben, und es wird nichts ausgegeben, da beim ersten Start nichts in "state" gespeichert wird. Im nachfolgenden Prozess wurden die Informationen im "Zustand" gespeichert und dann unterbrochen. Dann versuchen Sie es erneut.

$ scrapy crawl toscrape-restart -s JOBDIR=crawls/restart-1

(Weggelassen)

2020-03-24 15:29:31 [toscrape-restart] INFO: {'key': 'value'}
2020-03-24 15:29:31 [scrapy.dupefilters] DEBUG: Filtered duplicate request: <GET http://quotes.toscrape.com/page/1/> - no more duplicates will be shown (see DUPEFILTER_DEBUG to show all duplicates)
2020-03-24 15:29:31 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://quotes.toscrape.com/page/3/> (referer: None)
2020-03-24 15:29:32 [toscrape-restart] INFO: first quote author: Pablo Neruda
2020-03-24 15:29:42 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://quotes.toscrape.com/page/4/> (referer: None)
2020-03-24 15:29:42 [toscrape-restart] INFO: first quote author: Dr. Seuss
2020-03-24 15:29:56 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://quotes.toscrape.com/page/5/> (referer: None)
2020-03-24 15:29:56 [toscrape-restart] INFO: first quote author: George R.R. Martin
2020-03-24 15:30:10 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://quotes.toscrape.com/page/6/> (referer: None)
2020-03-24 15:30:10 [toscrape-restart] INFO: first quote author: Jane Austen
2020-03-24 15:30:10 [scrapy.core.engine] INFO: Closing spider (finished)
2020-03-24 15:30:10 [scrapy.statscollectors] INFO: Dumping Scrapy stats:

(Weggelassen)

Nach dem Neustart wird in der ersten Zeile das INFO-Protokoll von "{" key ":" value "}" ausgegeben. Sie können sehen, dass die vor der Unterbrechung gespeicherten Informationen zum Zeitpunkt der erneuten Ausführung referenziert werden können.

Andere Dinge sind mir aufgefallen

Der Umriss ist wie oben beschrieben, aber ich werde andere Dinge notieren, die ich überprüft und bemerkt habe.

Rolle von JOBDIR

Wenn Sie eine neu startbare Startmethode verwenden, wird ein Verzeichnis mit dem Namen erstellt, der beim Start als Argument übergeben wird. In diesem Verzeichnis befinden sich ein Verzeichnis mit dem Namen "request.queue" und Dateien mit dem Namen "request.seen" und "spider.state". Von diesen habe ich nicht überprüft, wofür request.queue verwendet wird ...

spider.state ist die Datei, in der der state aus dem vorherigen Abschnitt gespeichert ist. Es handelt sich um eine Pickle-Datei, deren Inhalt Sie mit dem folgenden Befehl überprüfen können.

python -m pickle spider.state

Mit dem Muster im Beispiel im vorherigen Abschnitt sieht die Ausgabe folgendermaßen aus, und Sie können sehen, dass die Informationen sicher gespeichert sind.

{'state_key1': {'key': 'value'}, 'state_key2': 0}

Andererseits enthält "request.seen" eine Hash-Zeichenfolge. Ich habe es auch nicht sehr genau nachgeschlagen, aber es scheint, dass es genau so ist wie der Name "gesehen", und die URL der Site, die die Informationen während der Ausführung erhalten hat, wird aufgezeichnet. Es scheint, dass die hier aufgezeichnete Site bei erneuter Ausführung übersprungen wird.

Nach Abschluss erneut ausführen

Wenn Sie das Scraping bis zum Ende abschließen, ohne die Ausführung zu unterbrechen, wird die erneute Ausführung beendet, ohne dass etwas unternommen wird, da alle URLs erfasst wurden. Es scheint sich nicht darum zu kümmern, wie JOBDIR zu überschreiben. Sie müssen das JOBDIR löschen oder das Argument ändern.

Recommended Posts

Starten Sie mit Scrapy neu
Schaben mit kratzender Schale
Probleme bei der Installation von Scrapy
Festliches Scraping mit Python, Scrapy
Einfaches Web-Scraping mit Scrapy
Wie fange ich mit Scrapy an?
Machen Sie Scrapy exe mit Pyinstaller
Ramen-Kartenerstellung mit Scrapy und Django
Sammeln Sie Informationen zu Längen- und Breitengraden des Speichers mit Scrapy + Splash ②
Spinne nicht gefunden erscheint beim Crawlen mit Scrapy
Sammeln Sie Informationen zu Breiten- und Längengraden des Speichers mit Scrapy + Splash ①