PC & Mobile

Un tutoriel minimaliste de bout en bout (partie I)

Un tutoriel minimaliste de bout en bout (partie I)


Raclage systématique sur le Web pour les débutants

Photo de Paweł Czerwiński sur Unsplash

Partie I, Partie II, Partie III, Partie IV

Le grattage Web est une compétence importante pour les scientifiques de données. Ces dernières années, j'ai développé un certain nombre de projets de grattage Web ad hoc utilisant Python, BeautifulSoup et Scrapy, et lu quelques livres et des tonnes de didacticiels en ligne. Cependant, je n’ai pas trouvé de tutoriel simple pour débutant qui soit de bout en bout dans le sens où il couvre toutes les bases (donc Minimaliste dans le titre) des étapes et des concepts d’un projet Scrapy Web typique - c’est la raison pour laquelle j’écris ceci et j’espère que le référentiel de code pourra servir de modèle pour vous aider à démarrer vos projets de scraping Web.

Beaucoup de gens demandent: dois-je utiliser BeautifulSoup ou Scrapy? Ce sont des choses différentes: BeautifulSoup est une bibliothèque d’analyse HTML et XML et Scrapy est un framework de scraping Web. Vous pouvez utiliser BeautifulSoup à la place des sélecteurs intégrés à Scrapy si vous le souhaitez, mais comparer BeautifulSoup à Scrapy revient à comparer le clavier Mac à l’iMac ou à une meilleure métaphore, comme indiqué dans la documentation officielle "comme comparer jinja2 à Django" si vous savez ce qu'ils are :) - En bref, vous devriez apprendre Scrapy si vous voulez faire du raclage Web sérieux et systématique.

TL; DR, montre-moi le code:

Dans cette série de tutoriels, je vais couvrir les étapes suivantes:

  1. (Ce tutoriel) Commencez un projet Scrapy à partir de zéro et développez une araignée simple. Une chose importante est l’utilisation de Scrapy Shell pour l’analyse de pages et le débogage, ce qui est l’une des principales raisons pour lesquelles vous devez utiliser Scrapy sur BeautifulSoup.
  2. (Partie II) Présentez Item et ItemLoader et expliquez pourquoi vous souhaitez les utiliser (bien que cela rende votre code plus compliqué au début).
  3. (Partie III) Stockez les données dans une base de données à l'aide de ORM (SQLAlchemy) via des pipelines et montrez comment configurer les relations un à plusieurs et plusieurs à plusieurs les plus courantes.
  4. (Partie IV) Déployez le projet sur Scrapinghub (vous devez payer pour un service tel que des travaux d'analyse planifiés) ou configurez vos propres serveurs entièrement gratuitement à l'aide du formidable projet open source ScrapydWeb et Heroku.

Je peux aussi ajouter du contenu sur des sujets tels que comment télécharger des fichiers et les télécharger sur s3, comment éviter d'être banni, comment gérer du contenu dynamique à l'aide de sélénium, etc. à l'avenir.

Quelques prérequis:

Commençons!

Tout d'abord, créez un nouveau dossier, configurez l'environnement virtuel Python 3 à l'intérieur du dossier et installez Scrapy. Pour faciliter cette étape, j'ai créé un référentiel de démarrage, que vous pouvez copier et dupliquer (voir la documentation de l'environnement virtuel Python3 si nécessaire):

$ git clone https://github.com/yourusername/scrapy-tutorial-starter.git
$ cd scrapy-tutorial-starter
$ python3.6 -m venv venv
$ source venv / bin / activate
pip install -r Requirements.txt

Votre dossier devrait ressembler à ceci et je suppose que nous travaillons toujours dans un environnement virtuel. Notez que nous n’avons jusqu’à présent qu’un seul paquet dans le fichier Requirements.txt

courir scrapy startproject tutorial pour créer un projet scrapy vide et votre dossier se présente comme suit:

Deux dossiers «tutoriels» identiques ont été créés. Nous n’avons pas besoin du dossier «tutorial» de premier niveau - supprimez-le et déplacez le dossier «tutorial» de deuxième niveau avec son contenu d’un niveau supérieur. Je sais que c’est confus, mais c’est tout ce que vous avez à faire avec la structure des dossiers. Maintenant, votre dossier devrait ressembler à:

Ne vous inquiétez pas des fichiers générés automatiquement, nous y reviendrons plus tard. Ce tutoriel est basé sur le tutoriel officiel Scrapy. Par conséquent, le site Web que nous allons explorer est http://quotes.toscrape.com, ce qui est assez simple: il existe des pages de citations avec des auteurs et des tags:

Lorsque vous cliquez sur l'auteur, vous accédez à la page de détail de l'auteur avec son nom, son anniversaire et sa biographie.

Maintenant, créez un nouveau fichier nommé “quotes-spider.py” dans le dossier “spider” avec le contenu suivant:

Vous venez de créer une araignée nommée “quotes”, qui envoie une demande à http://quotes.toscrape.com et obtient la réponse du serveur. Cependant, l'araignée ne fait rien jusqu'à présent lors de l'analyse de la réponse et envoie simplement une chaîne à la console. Lançons cette araignée: citations raclées , vous devriez voir le résultat comme:

Analysons ensuite la réponse, c’est-à-dire la page HTML à l’adresse http://quotes.toscrape.com à l’aide de Scrapy Shell, en exécutant:

$ shell scrapy http://quotes.toscrape.com/...2019-08-21 20:10:40 [scrapy.core.engine] INFO: Araignée ouverte2019-08-21 20:10:41 [scrapy.core.engine] DÉBOGAGE: rampé (404)  (référant: aucun)2019-08-21 20:10:41 [scrapy.core.engine] DÉBOGAGE: rampé (200)  (référant: aucun)[s]  Objets Scrapy disponibles:[s]      module scrapy scrapy (contient scrapy.Request, scrapy.Selector, etc.)[s]      chenille    [s]      article       {}[s]      demande    [s]      réponse   <200 http://quotes.toscrape.com/>[s]      paramètres   [s]      araignée     [s]  Raccourcis utiles:[s]      chercher (url[, redirect=True]) Récupérer l'URL et mettre à jour les objets locaux (par défaut, les redirections sont suivies)[s]      fetch (req) Récupère un scrapy.Request et met à jour des objets locaux[s]      shelp () Shell aide (imprimer cette aide)[s]      view (response) Voir la réponse dans un navigateur>>>

Vous pouvez sélectionner des éléments à l'aide du sélecteur Xpath ou du sélecteur CSS. Chrome DevTools est souvent utilisé pour analyser la page (nous ne couvrirons pas les détails du sélecteur. Veuillez lire les documents pour savoir comment les utiliser):

Par exemple, vous pouvez tester le sélecteur et voir les résultats dans Scrapy Shell. Supposons que nous voulions obtenir le bloc de devis indiqué ci-dessus:

Vous pouvez soit utiliser Xpath response.xpath (“// div[@class=’quote’]").obtenir() (.obtenir() affiche le premier élément sélectionné, utilisez .Avoir tout() pour tout afficher) ou CSSresponse.css ("div .quote"). get () . J'ai mis en gras le texte de citation, l'auteur et les balises que nous souhaitons obtenir de ce bloc de citation:

>>> response.xpath ("// div[@class='quote']").obtenir()'
n «Le monde tel que nous l'avons créé est un processus de notre pensée. Cela ne peut pas être changé sans changer notre façon de penser. " n par n (sur) n n
n Tags: n n n changement n n pensées profondes n n en pensant n n monde n n
n
'

Nous pouvons procéder en shell pour obtenir les données comme suit:

  • Obtenez tous les blocs de devis en "guillemets"
  • utilisez la première citation entre “guillemets”: guillemets[0]
  • essayez les sélecteurs css
>>> quotes = response.xpath ("// div[@class='quote']")
>>> citations[0].css (". text :: text"). getall ()
['“The world as we have created it is a process of our thinking. It cannot be changed without changing our thinking.”']>>> citations[0].css (". author :: text"). getall ()['Albert Einstein']>>> citations[0].css (". tag :: text"). getall ()['change', 'deep-thoughts', 'thinking', 'world']

Il semble que les sélecteurs présentés ci-dessus répondent à nos besoins. Notez que je mélange ici les sélecteurs Xpath et CSS à des fins de démonstration - inutile d’utiliser les deux dans ce didacticiel.

Maintenant, révisons le fichier araignée et utilisons le mot-clé rendement pour sortir les données sélectionnées sur la console (notez que chaque page a plusieurs guillemets et que nous utilisons une boucle pour les parcourir toutes):

importer des déchetsClasse QuotesSpider (scrapy.Spider):
name = "quotes"
start_urls = ['http://quotes.toscrape.com']def parse (auto, réponse):
self.logger.info ('bonjour c'est ma première araignée')
quotes = response.css ('div.quote')
pour devis entre guillemets:
rendement {
'text': quote.css ('. text :: text'). get (),
'author': quote.css ('. author :: text'). get (),
'tags': quote.css ('. tag :: text'). getall (),
}

Exécutez à nouveau l'araignée: citations raclées et vous pouvez voir les données extraites dans le journal:

Vous pouvez enregistrer les données dans un fichier JSON en exécutant: scrapy crawl quotes -o quotes.json

Jusqu'à présent, nous obtenons toutes les informations de devis de la première page et notre tâche suivante consiste à analyser toutes les pages. Vous devriez remarquer un bouton Suivant en bas de la page d'accueil pour la navigation entre les pages. La logique est la suivante: cliquez sur le bouton Suivant pour accéder à la page suivante, obtenez les guillemets, cliquez à nouveau sur Suivant jusqu'à la dernière page sans le bouton Suivant.

Via Chrome DevTools, nous pouvons obtenir l'URL de la page suivante:

Essayons-le dans Scrapy Shell en exécutant coquille grasse http://quotes.toscrape.com/ encore:

$ shell scrapy http://quotes.toscrape.com/
...
>>> response.css ('li.next a :: attr (href)'). get ()'/page 2/'

Nous pouvons maintenant écrire le code suivant pour que l'araignée passe en revue toutes les pages afin d'obtenir toutes les citations:

next_page = response.urljoin (next_page) obtient l'URL complète et donnez scrapy.Request (next_page, callback = self.parse) envoie une nouvelle requête pour obtenir la page suivante et utilise une fonction de rappel pour appeler la même fonction d'analyse afin d'obtenir les guillemets de la nouvelle page.

Des raccourcis peuvent être utilisés pour simplifier davantage le code ci-dessus: voir cette section. Essentiellement, réponse.suivre supporte les URL relatives (pas besoin d'appeler rejoindre) et utilise automatiquement le href attribut pour . Ainsi, le code peut être raccourci davantage:

pour a dans response.css ('li.next a'):
return response.follow (a, callback = self.parse)

Maintenant, lancez à nouveau l'araignée citations raclées vous devriez voir des citations de toutes les 10 pages ont été extraites. Accrochez-vous - nous avons presque terminé cette première partie. La tâche suivante consiste à explorer la page de chaque auteur.

Comme indiqué ci-dessus, lorsque nous traitons chaque devis, nous pouvons accéder à la page de chaque auteur en suivant le lien mis en surbrillance - utilisons Scrapy Shell pour obtenir le lien:

$ shell scrapy http://quotes.toscrape.com/
...
>>> response.css ('. auteur + a :: attr (href)'). get ()
'/ auteur / Albert-Einstein'

Ainsi, lors de la boucle d’extraction de chaque devis, nous émettons une autre demande pour accéder à la page de l’auteur correspondant et créer un autre fichier. parse_author fonction pour extraire le nom de l’auteur, sa date de naissance, son lieu de naissance, sa biographie et sa sortie sur la console. L'araignée mise à jour ressemble à ceci:

Relancez l'araignée citations raclées et vérifiez deux fois que tout ce que vous devez extraire est correctement exporté vers la console. Notez que Scrapy est basé sur Twisted, un framework de réseau populaire basé sur les événements pour Python et est donc asynchrone. Cela signifie que la page de l'auteur individuel peut ne pas être traitée en synchronisation avec le devis correspondant, par exemple, l'ordre des résultats de la page de l'auteur peut ne pas correspondre à l'ordre des devis sur la page. Nous verrons comment lier la citation à la page de l'auteur correspondant dans une partie ultérieure.

Félicitations, vous avez terminé la partie I de ce didacticiel.

En savoir plus sur Item et ItemLoader dans la deuxième partie.

Partie I, Partie II, Partie III, Partie IV

Show More

SupportIvy

SupportIvy.com : Un lieu pour partager le savoir et mieux comprendre le monde. Meilleure plate-forme de support gratuit pour vous, Documentation &Tutoriels par les experts.

Related Articles

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Close
Close