Scrapy, un framework Python pour l'exploration de sites Web, a la capacité de redémarrer, c'est-à-dire d'interrompre pendant l'exécution, puis de reprendre à partir de la suite précédente. Ceci est utile lorsque vous visitez un grand nombre de pages et effectuez un scraping chronophage.
Voici la documentation officielle. Jobs: pausing and resuming crawls
J'ai préparé l'araignée suivante pour essayer la fonction. http://quotes.toscrape.com 6 Téléchargez simplement la page et enregistrez le contenu.
toscrape-restart.py
import scrapy
import json
import time
class QuotesSpider(scrapy.Spider):
name = "toscrape-restart"
custom_settings = {
#Ne pas demander en parallèle
"CONCURRENT_REQUESTS": 1,
#Définissez des intervalles sur les demandes pour les rendre plus faciles à interrompre
"DOWNLOAD_DELAY": 10,
# http://quotes.toscrape.robots sur com.N'obtenez pas de txt car il n'existe pas
"ROBOTSTXT_OBEY": False,
}
def start_requests(self):
#Maintenir l'état entre les lots (voir ci-dessous)
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()
)
L'araignée ci-dessus peut être démarrée avec la commande suivante.
scrapy crawl toscrape-restart
Ce sera une exécution normale. Pour le rendre redémarrable, définissez JOBDIR comme suit.
scrapy crawl toscrape-restart -s JOBDIR=crawls/restart-1
Cela créera un répertoire crawls / restart-1
qui stocke les informations pour les redémarrages et vous permettra de redémarrer. (S'il n'y a pas de répertoire, Scrapy le créera, vous n'avez donc pas besoin de le préparer à l'avance)
Démarrez-le avec la commande ci-dessus et interrompez-le avec Ctrl-C
pendant l'exécution. Par exemple, si vous l'arrêtez immédiatement après avoir obtenu la première page, la sortie sera la suivante.
$ scrapy crawl toscrape-restart -s JOBDIR=crawls/restart-1
(Omis)
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:
(Omis)
Il a été interrompu lorsque j'ai reçu la deuxième page. Après avoir interrompu de cette manière, vous pouvez reprendre en exécutant la même commande que la première.
$ scrapy crawl toscrape-restart -s JOBDIR=crawls/restart-1
(Omis)
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:
(Omis)
Les 1ère et 2ème pages étaient affichées comme "Requête en double filtrée" et n'ont pas été récupérées. Après cela, la troisième page et les suivantes qui n'ont pas été acquises avant l'interruption l'ont été normalement.
Le redémarrage Scrapy a la capacité de transmettre des informations entre les démarrages en utilisant state
.
Les informations peuvent être stockées dans l'état spider et référencées au prochain démarrage.
Plus précisément, il peut être stocké dans l'utilisation suivante dans le premier toscrape-restart.py
.
self.state["state_key1"] = {"key": "value"}
self.state["state_key2"] = 0
Puisque «state» est un «type dict», vous pouvez effectuer des opérations sur le dictionnaire. Dans l'exemple ci-dessus, la valeur "{" key ":" value "}" est stockée dans la clé "state_key1", et la valeur "0" est stockée dans la clé "state_key2". Quand je l'exécute, cela ressemble à ceci:
$ scrapy crawl toscrape-restart -s JOBDIR=crawls/restart-1
(Omis)
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:
(Omis)
Le journal INFO «Aucun» est affiché sur la première ligne. Ceci est produit par self.logger.info (self.state.get (" state_key1 "))
, et rien n'est produit car rien n'est stocké dans state
au premier démarrage.
Dans le processus suivant, les informations ont été stockées dans "état" puis interrompues.
Puis réessayez.
$ scrapy crawl toscrape-restart -s JOBDIR=crawls/restart-1
(Omis)
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:
(Omis)
Après le redémarrage, le journal INFO de {'key': 'value'}
est affiché sur la première ligne.
Vous pouvez voir que les informations stockées avant l'interruption peuvent être référencées au moment de la réexécution.
Le plan est comme décrit ci-dessus, mais je noterai d'autres choses que j'ai vérifiées et remarquées.
Si vous utilisez une méthode de démarrage redémarrable, un répertoire dont le nom est passé en argument au démarrage sera créé. À l'intérieur de ce répertoire se trouvent un répertoire appelé «requests.queue» et des fichiers appelés «requests.seen» et «spider.state».
Parmi ceux-ci, je n'ai pas vérifié à quoi sert requests.queue
...
spider.state
est le fichier dans lequel l'état
de la section précédente est stocké. Il s'agit d'un fichier pickle et vous pouvez vérifier son contenu avec la commande suivante.
python -m pickle spider.state
Avec le modèle de l'exemple de la section précédente, la sortie ressemble à ceci, et vous pouvez voir que les informations sont certainement stockées.
{'state_key1': {'key': 'value'}, 'state_key2': 0}
D'autre part, «requests.seen» contient une chaîne hachée. Je ne l'ai pas recherché très précisément non plus, mais il semble que ce soit exactement comme le nom «vu», et l'URL du site qui a obtenu les informations lors de l'exécution est enregistrée. Il semble que le site enregistré ici soit ignoré lors de la réexécution.
Si vous terminez le grattage jusqu'à la fin sans interrompre pendant l'exécution, la réexécution se terminera sans rien faire car toutes les URL ont été acquises. Cela ne semble pas prendre de soin, comme l'écrasement de JOBDIR. Vous devez supprimer le JOBDIR ou modifier l'argument.
Recommended Posts