Scraping avec Python - Introduction à Scrapy Première 2e étape

Contexte

J'ai récemment appris l'existence de Scrapy, un framework de grattage fabriqué par Python, et c'était le plus fort lorsque je l'ai touché. Les bons points spécifiques sont les suivants.

Les articles suivants seront très utiles pour la vue d'ensemble et l'introduction.

Objectif de cet article

L'article ci-dessus est suffisant pour le plan et l'introduction, mais j'ai résumé quelques points supplémentaires dont j'ai besoin lorsque j'essaye de faire diverses choses moi-même. Je n'ai pas écrit le contenu de l'article ci-dessus, donc je pense que c'est une bonne idée de le lire d'abord.

Il est écrit sous la forme de l'introduction de la page correspondante de Référence officielle et de la compléter.

architecture

Le framework est pratique, mais si vous l'utilisez sans connaître la structure interne, il sera très flou, alors commençons par un aperçu. Un aperçu peut être trouvé sur cette page.

Scrapy architecture overview

Component Scrapy Engine La partie qui contrôle le traitement des données de l'ensemble du framework.

Scheduler La partie qui gère les demandes aux pages en tant que file d'attente. Reçoit un objet scrapy.Request (un objet avec une URL et des fonctions de rappel), le met dans une file d'attente et renvoie la file d'attente à la demande du moteur.

Downloader La partie qui accède à la page Web réelle. Récupérez la page Web et transmettez-la à Spider.

Spiders La partie qui traite les données de la page Web extraites. L'utilisateur doit personnaliser lui-même le traitement de cette partie. Le traitement qui peut être écrit est grossièrement divisé en deux types

Item Pipeline La partie qui traite les données de l'élément extraites par Spider. Effectuer le nettoyage des données, la validation, l'enregistrement dans des fichiers et DB.

Middlewares Puisqu'il existe des couches Middleware avant et après Downloader et Spider, il est possible d'y insérer un traitement.

Choses à garder à l'esprit

Fondamentalement, tout ce que vous avez à écrire vous-même est ** le traitement dans Spider, la définition de la classe Item, les paramètres pour le pipeline d'articles et d'autres paramètres de base **. (Bien sûr, si vous souhaitez l'agrandir, vous pouvez jouer avec d'autres)

De plus, la ** série de flux de "téléchargement de données à partir d'une page Web, de les enregistrer quelque part, puis de suivre la page suivante" est transformée en un composant et traitée de manière asynchrone **. Dans cet esprit, vous pouvez comprendre ce qui se passe lorsque vous créez un objet scrapy.Request dans Spider et transmettez-le au Scrapy Engine pour spécifier la page suivante.

flux de données

Le flux de données global est le suivant.

  1. Tout d'abord, Engine obtient l'URL de démarrage et transmet l'objet Request avec cette URL au planificateur.
  2. Le moteur demande au planificateur l'URL suivante
  3. Le planificateur renvoie l'URL suivante et le moteur la transmet au téléchargeur
  4. Le téléchargeur récupère les données de la page et renvoie l'objet Response au moteur
  5. Le moteur reçoit la réponse et la transmet à Spider
  6. Spider analyse les données de la page et renvoie ** un objet Item contenant les données ** et un ** objet Response ** avec l'URL à transférer vers le moteur.
  7. Le moteur les reçoit et transmet l'objet Item au pipeline d'articles et l'objet Request au planificateur.
  8. Répétez les étapes 2 à 7 jusqu'à ce que la file d'attente soit épuisée

Si vous comprenez l'architecture, vous pouvez comprendre clairement l'ensemble du flux.

Selector Scrapy vous permet d'utiliser des sélecteurs CSS et XPath pour récupérer les éléments de la page explorée. La référence officielle est ici.

J'utilise ceci parce que XPath vous donne plus de flexibilité. Les articles et références officielles suivants seront utiles.

Comment déboguer

La référence officielle est ici.

Scrapy Shell Scrapy a une fonction de débogage pratique appelée Scrapy Shell.

Lorsque vous démarrez Scrapy Shell en spécifiant l'URL de la page Web que vous souhaitez obtenir, ipython démarre avec certains objets Scrapy tels que la réponse de Downloader. Dans cet état, vous pouvez déboguer le code de Selector écrit en Spider.

% scrapy shell "https://gunosy.com/"
2016-09-05 10:38:56 [scrapy] INFO: Scrapy 1.1.2 started (bot: gunosynews)
2016-09-05 10:38:56 [scrapy] INFO: Overridden settings: {'LOGSTATS_INTERVAL': 0, 'NEWSPIDER_MODULE': 'gunosynews.spiders', 'DOWNLOAD_DELAY': 3, 'ROBOTSTXT_OBEY': True, 'SPIDER_MODULES': ['gunosynews.spiders'], 'DUPEFILTER_CLASS': 'scrapy.dupefilters.BaseDupeFilter', 'BOT_NAME': 'gunosynews'}
---
2016-09-05 10:38:56 [scrapy] DEBUG: Telnet console listening on 127.0.0.1:6023
2016-09-05 10:38:56 [scrapy] INFO: Spider opened
2016-09-05 10:38:57 [scrapy] DEBUG: Crawled (200) <GET https://gunosy.com/robots.txt> (referer: None)
2016-09-05 10:39:01 [scrapy] DEBUG: Crawled (200) <GET https://gunosy.com/> (referer: None)

##↓ Objets Scrapy disponibles dans Scrapy Shell
[s] Available Scrapy objects:
[s]   crawler    <scrapy.crawler.Crawler object at 0x10ff54fd0>
[s]   item       {}
[s]   request    <GET https://gunosy.com/>
[s]   response   <200 https://gunosy.com/>
[s]   settings   <scrapy.settings.Settings object at 0x110b0ef28>
[s]   spider     <GunosynewsSpider 'gunosy' at 0x110d40d68>
[s] Useful shortcuts:
[s]   shelp()           Shell help (print this help)
[s]   fetch(req_or_url) Fetch request (or URL) and update local objects
[s]   view(response)    View response in a browser

##↓ Vérifiez si vous pouvez obtenir comme prévu
>>> response.xpath('//div[@class="list_title"]/*/text()').extract()
['Sanada Maru "Inubushi" est inondé d'éloges "Des temps incroyables" "Les larmes ne s'arrêtent pas"...Voix d'admiration pour la performance d'Oizumi', 'Vous pouvez pleurer si Kairos apparaît sur un œuf de 10 km! Les 10 km que vous avez parcourus étaient gaspillés! Pokemon GO1...', '"Ame Talk!" Passez à Golden le dimanche deux fois par semaine, ce qui est inhabituel à minuit le jeudi', 'Apparition surprise de Sagan Tosu Toyoda au festival culturel de l'école locale AKB et PR', 'Kengo Nishioka, le centre de Majipuri, a déclaré "PON!"Je ferai de mon mieux pour le premier" frère météo "!"', 'Les États-Unis prêtent attention au revers de Nishikiori qui s'est classé parmi les 16 meilleurs!', 'Ichiro frappe 2 matchs de suite! "4" à la 26e place de l'histoire avec 3016 résultats au total', 'Défense KO=Takashi Inoue qui avait mal au dos-Classe de vol WBO / S', 'Terashima et Fujihira sont les pichets les plus forts du Japon au lycée.', 'Le premier faux pas d'Ichiro en deux saisons Le commentateur américain fait rage contre le jeu négligent d'Ace "La responsabilité de Jose"', 'La terre est trop petite! "Infinity of the Univers" dans la vidéo comparant les tailles des planètes est dangereux', 'Le compte populaire "Okegawa Neko" a arrêté Twitter. Je ne peux pas finir la raison...', 'Où avez-vous appris!?11 personnes dont les talents se sont épanouis dans la mauvaise direction', 'Ma fille et mon copain "flirt drive" → Après cela, mon père entreprend une action surprenante...!', '[Howahowa ♡] Kyun Kyun ne peut pas s'arrêter à «l'innocence» d'un petit chaton et d'un chiot jouant ensemble!', 'La tragédie du prestigieux Idemitsu...Soudainement, le fondateur est confus par l'intervention de la direction et la réorganisation de l'industrie menée par le pays est au bord de l'effondrement', '5e matin "Formation à 8,8 millions d'Osaka" tenue Réception du courrier d'urgence qui émet un son lorsque vous êtes à Osaka', 'A 16 ans, il était déjà une "bête sexuelle"! Témoignage de Yuta Takahata, "J'étais sur le point de devenir une corde pour un crime sexuel."', 'Déplacez le marché de Tsukiji dès que possible! Si vous pensez aux habitants de Tokyo, il n'y a qu'une seule réponse', 'Toru Hashishita "Confrontation ou coopération avec le conseil municipal! M. Koike doit bientôt avoir faim"', 'Un policier qui a divulgué une image de sexe de voiture prise lors d'une patrouille a été arrêté et la femme photographiée s'est suicidée-Chine', 'Une tournée coréenne de mauvaise qualité suscite la colère des touristes chinois contre les médias japonais-chinois', 'Le thé qui a été introduit de Chine au Japon, le "Matcha" a été réimporté et est devenu populaire=Couverture de la Chine', '"Too Japan!" Pour les productions qui influencent fortement les films chinois, les dramatiques et le Japon', 'L'American Museum of Art expose une "carte déformée", la Grande Muraille de Mari qui s'étend jusqu'à la péninsule coréenne=Korea Net "Le Japon est terrible, mais la Chine l'est encore plus...', 'Est-ce incroyable de l'enlever? 5 caractéristiques du corps féminin sensuel', 'Quel est le problème avec les "maisons sans téléphone fixe" sur le réseau de contact de l'école?', 'Est-ce vrai! Deux "cadeaux à ne pas offrir aux hommes" super surprenants', 'N'y touchez pas! 4 parties qui deviennent sensibles pendant la physiologie', '"espoir perdu...Divers exemples de bagages malheureux livrés à l'étranger', 'Cela ne semble pas étrange! Nonsta Inoue et Ocarina échangent des visages! Le sujet est que cela ne semble pas du tout étrange', 'Sanko lance un chiffon à air rechargeable "SHU"', 'Sangle intelligente "Sgnl" qui vous permet de passer des appels téléphoniques en utilisant votre doigt comme récepteur', 'Un film dans lequel Siri d'Apple est frappé par Cortana de Microsoft', 'Techniques utiles de Google-Organiser les fichiers sur Google Drive', 'Vous pouvez l'acheter à la gare de Sapporo sans hésitation! 5 souvenirs incontournables', 'Découverte "Trop belle vente de déjeuner" à Shinjuku → 400 yens pour le déjeuner, c'est un niveau qui donne envie d'aller travailler les samedis et dimanches!', 'Le propriétaire de Ramen Jiro avoue ses vrais sentiments/Même si une personne mange tôt, cela ne veut pas dire que les autres clients sont en retard. "Chacun doit faire de son mieux."', 'Chat! Chat! Chat! 3 cadeaux avec des motifs de chats que les amoureux des chats vont adorer', 'La bière continue! J'ai fait une simple collation de Hanpen et Conbeef', 'J'en suis encore accro ♪ Nouveau travail "Six!] Est un jeu d'actualité créé par une équipe de grands succès [Revue de jeu qui peut être lue en seulement 10 secondes]', '[Sélection super soignée] Deux jeux recommandés de la semaine sélectionnés par la rédaction de Game8! Cette semaine "Lost Maze" "Flip"...', 'Jeu de simulation de guérison "Midori no Hoshiboshi" qui laisse échapper des étoiles désolées [Weekend Review]', 'Jeu de mort "Mr" qui a atteint 5 millions de DL en 4 jours après sa sortie.Jump (Mr. Jump) "', 'Une attaque totale de jusqu'à 16 corps est un chef-d'œuvre! Le vrai frisson du RPG est ici. "ODYSSÉE ÉCLATANTE...']

Commande d'analyse

Après avoir implémenté Spider, vérifions avec la commande Parse.

% scrapy parse --spider=gunosy "https://gunosy.com/categories/1"
2016-09-05 10:57:26 [scrapy] INFO: Scrapy 1.1.2 started (bot: gunosynews)
2016-09-05 10:57:26 [scrapy] INFO: Overridden settings: {'NEWSPIDER_MODULE': 'gunosynews.spiders', 'DOWNLOAD_DELAY': 3, 'BOT_NAME': 'gunosynews', 'ROBOTSTXT_OBEY': True, 'SPIDER_MODULES': 
---
 'start_time': datetime.datetime(2016, 9, 5, 1, 57, 26, 384501)}
2016-09-05 10:57:30 [scrapy] INFO: Spider closed (finished)

>>> STATUS DEPTH LEVEL 1 <<<
# Scraped Items  ------------------------------------------------------------
[{'subcategory': 'films',
  'title': 'Kuranosuke Sasaki x Kyoko Fukada "Super rapide! "Renvoie" est "Redonner"',
  'url': 'https://gunosy.com/articles/R07rY'},
 {'subcategory': 'Divertissement',
  'title': 'Un Indien de naissance inconnue remporte le championnat et 10 épisodes de "Soma No. 2 Plate of Shokugeki"',
  'url': 'https://gunosy.com/articles/Rb0dc'},
 {'subcategory': 'poste de télévision',
  'title': 'Résolution de mystère "Asunaro étreignant". Ligne 132 de Takuya Kimura à Hidetoshi Nishijima "Toto-neechan"',
  'url': 'https://gunosy.com/articles/RrtZJ'},
 {'subcategory': 'Divertissement',
  'title': 'Les t-shirts qui combinent "Hadashi no Gen" et la culture du club des années 90 sont géniaux',
  'url': 'https://gunosy.com/articles/aw7bd'},
 {'subcategory': 'Dessin animé',
  'title': 'L'histoire moderne du Japon lui-même ... Une voix d'adieu des fans taïwanais pour terminer "Kochigame"=Médias de Taiwan',
  'url': 'https://gunosy.com/articles/Rmd7L'},
---
 {'subcategory': 'poste de télévision',
  'title': 'Ame Talk!Deux fois par semaine!!Dimanche Golden Advance',
  'url': 'https://gunosy.com/articles/afncS'},
 {'subcategory': 'Dessin animé',
  'title': 'Décidé d'animer "Ahito-chan veut parler" qui dépeint la vie quotidienne des lycéennes qui sont un peu "insolites"',
  'url': 'https://gunosy.com/articles/aan1a'}]

# Requests  -----------------------------------------------------------------
[]

Il existe d'autres façons d'ajouter Ouvrir dans le navigateur, ce qui vous permet de vérifier le contenu de la réponse directement à partir du navigateur et de la journalisation.

Comment spécifier la sortie

La référence officielle est ici.

Format (json, jsonlines, xml, csv)

C'est OK si vous spécifiez l'élément FEED_FORMAT dans settings.py.

settings.py


FEED_FORMAT = 'csv'

Auparavant, seul Python2 était pris en charge, donc le japonais dans le fichier de sortie et le journal était encodé, mais ** Parce que Scrapy / Scrapy Cloud prenait en charge Python3 en mai 2016 ** , Il semble que Scrapy lui-même soit également pris en charge séquentiellement afin qu'il soit produit sans être encodé dans chaque format.

Enregistrer la destination (local, ftp, s3)

Ce n'est pas grave si vous définissez FEED_URI dans settings.py de manière appropriée.

settings.py


FEED_URI = 'file:///tmp/export.csv'

Si vous utilisez S3, vous devez spécifier un ID et une CLÉ supplémentaires, mais c'est très facile à utiliser.

settings.py


FEED_URI = 's3://your-bucket-name/export.csv'
AWS_ACCESS_KEY_ID = 'YOUR_ACCESS_KEY_ID'
AWS_SECRET_ACCESS_KEY = 'YOUR_SECRET_ACCESS_KEY'

Si vous souhaitez enregistrer sur S3 dans un environnement local, veuillez installer botocore ou boto. Il semble qu'il soit installé dans Scrapy Cloud depuis le début, donc aucun support n'est requis.

% pip install botocore

Comment spécifier le nom de fichier dynamiquement

De plus, le nom du fichier peut être spécifié dynamiquement. Par défaut, les deux variables suivantes sont définies.

Vous pouvez également ajouter des variables vous-même en les définissant dans le code de Spider. Le% (time) s par défaut n'est pas l'heure japonaise, voici donc un exemple de sortie en spécifiant un répertoire ou un nom de fichier en heure japonaise.

gunosy.py


# -*- coding: utf-8 -*-
import scrapy
from pytz import timezone
from datetime import datetime as dt
from gunosynews.items import GunosynewsItem

class GunosynewsSpider(scrapy.Spider):
    name = "gunosy"
    allowed_domains = ["gunosy.com"]
    start_urls = (
    'https://gunosy.com/categories/1',  #Divertissement
    'https://gunosy.com/categories/2',  #Des sports
    'https://gunosy.com/categories/3',  #intéressant
    'https://gunosy.com/categories/4',  #National
    'https://gunosy.com/categories/5',  #étranger
    'https://gunosy.com/categories/6',  #colonne
    'https://gunosy.com/categories/7',  #Informatique / Science
    'https://gunosy.com/categories/8',  #Gourmet
    )

    # For output path
    #Peut être défini dynamiquement ici
    now = dt.now(timezone('Asia/Tokyo'))
    date = now.strftime('%Y-%m-%d')
    jst_time = now.strftime('%Y-%m-%dT%H-%M-%S')

settings.py


FEED_URI = 's3://your-bucket-name/%(name)s/dt=%(date)s/%(jst_time)s.csv'
FEED_FORMAT = 'csv'
AWS_ACCESS_KEY_ID = 'YOUR_ACCESS_KEY_ID'
AWS_SECRET_ACCESS_KEY = 'YOUR_SECRET_ACCESS_KEY'

Comment spécifier l'environnement sur Scrapy Cloud

Comment spécifier python3

Pour plus d'informations sur la prise en charge de Python3, voir ici. À partir du 05/09/2016, Python2 sera utilisé sur Scrapy Cloud, sauf indication contraire.

Pour fonctionner avec Python3 sur Scrapy Cloud, vous devez ajouter les paramètres suivants à scrapinghub.yml qui est créé lorsque vous exécutez la commande `` shub deploy ''.

scrapinghub.yml


projects:
  default: 99999
stacks:
  default: scrapy:1.1-py3

Comment inclure des packages dépendants

Si vous souhaitez utiliser la bibliothèque dans le processus Scrapy, vous devez écrire le nom du package dépendant dans requirements.txt et le spécifier dans scrapinghub.yml.

requirements.txt


pytz

scrapinghub.yml


projects:
  default: 99999
stacks:
  default: scrapy:1.1-py3
requirements_file: requirements.txt

c'est tout.

Housmart - Organization Page

Recommended Posts

Scraping avec Python - Introduction à Scrapy Première 2e étape
Python - La première étape de Pygal
Web scraping avec Python Première étape
La première étape de Python Matplotlib
Impressions Udemy: Web Scraping avec Python-Introduction- [Premiers pas vers l'efficacité commerciale] Impressions
La première étape de l'analyse du journal (comment formater et mettre les données du journal dans Pandas)
Télécharger les artefacts récupérés dans Scrapy Cloud vers S3
Premiers pas pour essayer Google CloudVision en Python
La première étape du problème de réalisation des contraintes en Python
Comment transmettre les paramètres au pipeline d'articles dans Scrapy
Introduction à Scrapy (1)
Introduction à Scrapy (3)
Introduction à Scrapy (2)
Introduction à Scrapy (4)
J'étais accro au grattage avec Selenium (+ Python) en 2020
TemplateView les modèles que vous souhaitez apprendre en premier dans Django
La première étape pour obtenir Blender disponible à partir de Python