Grattage festif avec Python, scrapy

introduction

Cet article utilise un "framework de scraping" appelé "scrapy" pour le web scraping en python.

Document officiel

Architecture en lambeaux

À propos du framework Overview

flux de données

architecture image

Components

Scrapy Engine

Contrôlez chaque composant comme indiqué dans le diagramme Data Flow en haut.

Scheduler

Reçoit les demandes du Scrapy Engine et les empile dans une file d'attente afin qu'elles puissent être récupérées des demandes ultérieures du Scrapy Engine.

Downloader

Le téléchargeur obtient la page Web, la transmet à Scrapy Engine et la transmet à Spider.

Spiders

Les araignées sont des classes personnalisées qui permettent aux utilisateurs de Scrapy d'analyser la réponse et d'extraire des éléments (éléments récupérés) ou toute demande supplémentaire qui suit.

Je personnalise principalement ici moi-même.

Item Pipeline

Le pipeline d'objets gère l'objet une fois qu'il a été extrait par Spider. Les tâches typiques incluent le nettoyage, la validation et la persistance (comme le stockage des éléments dans une base de données).

Vous pouvez l'écrire dans un fichier json ou l'enregistrer dans une base de données.

Downloader middlewares

Les middlewares de téléchargement sont des hooks spécifiques qui se situent entre Scrapy Engine et Downloader et gèrent les requêtes transmises par Scrapy Engine à Downloader et les réponses transmises par Downloader à Scrapy Engine.

Je ne vais pas l'utiliser cette fois.

Spider middlewares

Les middlewares Spider sont des hooks spécifiques qui se situent entre Scrapy Engine et Spider et peuvent gérer les entrées (réponses) et les sorties de Spider (éléments et requêtes).

Je ne vais pas l'utiliser cette fois.

Install Requirements

Bibliothèque requise pour l'installation

Procédure de mise en œuvre / image de l'application Festival Scraping

--Construire un environnement de développement local à l'aide de Docker --Création d'un projet --Mise en œuvre cliquetante

Let's, Enjoy Tokyo a été ciblé pour le grattage.

Créer un Dockerfile

FROM python:3.6-alpine

RUN apk add --update --no-cache \
    build-base \
    python-dev \
    zlib-dev \
    libxml2-dev \
    libxslt-dev \
    openssl-dev \
    libffi-dev

ADD pip_requirements.txt /tmp/pip_requirements.txt
RUN pip install -r /tmp/pip_requirements.txt

ADD ./app /usr/src/app
WORKDIR /usr/src/app

pip_requirements.txt ressemble à ceci

# Production
# =============================================================================
scrapy==1.4.0


# Development
# =============================================================================
flake8==3.3.0
flake8-mypy==17.3.3
mypy==0.511

Créer une image Docker

docker build -t festival-crawler-app .

Démarrer le conteneur Docker

#Exécuter directement sous le répertoire de travail
docker run -itd -v $(pwd)/app:/usr/src/app \
--name festival-crawler-app \
festival-crawler-app

Entrez dans le conteneur démarré

docker exec -it festival-crawler-app /bin/sh

Créer un projet

# scrapy startproject <project_name> [project_dir]
scrapy startproject scraping .

Le répertoire créé ressemble à ce qui suit.

Avant de créer un projet

├── Dockerfile
├── app
└── pip_requirements.txt

Après avoir créé le projet

.
├── Dockerfile
├── app
│   ├── scraping
│   │   ├── __init__.py
│   │   ├── items.py
│   │   ├── middlewares.py
│   │   ├── pipelines.py
│   │   ├── settings.py
│   │   └── spiders
│   │       └── __init__.py
│   └── scrapy.cfg
└── pip_requirements.txt

settings.py paramètres

Vous pouvez définir la durée pendant laquelle le téléchargeur attend pour télécharger des pages consécutives à partir du même site Web.

__ Assurez-vous de définir cette valeur afin qu'elle ne surcharge pas le site Web que vous raclez. __

Vérifiez le fichier robots.txt du site cible, et si Crawl-delay est spécifié, il semble bon de spécifier cette valeur.

#DOWNLOAD_DELAY = 10  # sec

Implémentation de app / scraping / items.py

# -*- coding: utf-8 -*-

import scrapy
from scrapy.loader.processors import (
    Identity,
    MapCompose,
    TakeFirst,
)
from w3lib.html import (
    remove_tags,
    strip_html5_whitespace,
)


class FestivalItem(scrapy.Item):
    name = scrapy.Field(
        input_processor=MapCompose(remove_tags),
        output_processor=TakeFirst(),
    )
    term_text = scrapy.Field(
        input_processor=MapCompose(remove_tags, strip_html5_whitespace),
        output_processor=TakeFirst(),
    )
    stations = scrapy.Field(
        input_processor=MapCompose(remove_tags),
        output_processor=Identity(),
    )

La classe Item définit les données à traiter par scraping. Cette fois, nous définirons les données suivantes.

ʻInput_processor et ʻoutput_processor sont très pratiques car ils peuvent accepter et traiter des données au moment de la sortie, respectivement.

Implémentation du fichier app / scraping / spider / festival.py

# -*- coding: utf-8 -*-

from typing import Generator

import scrapy
from scrapy.http import Request
from scrapy.http.response.html import HtmlResponse

from scraping.itemloaders import FestivalItemLoader


class FestivalSpider(scrapy.Spider):
    name: str = 'festival:august'

    def start_requests(self) -> Generator[Request, None, None]:
        url: str = (
            'http://www.enjoytokyo.jp'
            '/amuse/event/list/cate-94/august/'
        )
        yield Request(url=url, callback=self.parse)

    def parse(
        self,
        response: HtmlResponse,
    ) -> Generator[Request, None, None]:
        for li in response.css('#result_list01 > li'):
            loader = FestivalItemLoader(
                response=response,
                selector=li,
            )
            loader.set_load_items()
            yield loader.load_item()

La mise en œuvre ici est une description du grattage réel. La variable de classe name: str = 'festival: august' est le nom de la commande à exécuter depuis la ligne de commande. En écrivant ce qui précède, vous pouvez effectuer du scraping au scrapy crawl festival: août.

Implémentation de app / scraping / itemloaders.py

# -*- coding: utf-8 -*-

import scrapy
from scrapy.loader import ItemLoader

from scraping.items import FestivalItem

class FestivalItemLoader(ItemLoader):
    default_item_class = FestivalItem

    def set_load_items(self) -> None:
        s: str = '.rl_header .summary'
        self.add_css('name', s)
        s = '.rl_main .dtstart::text'
        self.add_css('term_text', s)
        s = '.rl_main .rl_shop .rl_shop_access'
        self.add_css('stations', s)

Ce qui précède n'est peut-être pas l'usage correct, mais j'ai pensé qu'il serait déroutant de lister le sélecteur css dans festival.py, donc je l'ai défini dans ʻItemLoader. La méthode set_load_items est une méthode ajoutée cette fois qui n'existe pas dans la classe ʻItemLoader.

Commande de raclage

La sortie peut être spécifiée avec l'option -o. Si vous souhaitez l'enregistrer dans DB, etc., vous devez l'implémenter séparément.

scrapy crawl festival:august -o result.json

Vous pouvez maintenant obtenir les informations du festival pour août

[
	{
		"name": "ECO EDO Nihonbashi Art Aquarium 2017 ~ Edo / Goldfish Ryo ~ & Aquarium de nuit",
		"stations": [
			"Gare de Shin Nihonbashi"
		],
		"term_text": "2017/07/07(Argent)"
	},
	{
		"name": "Illumination de Tennokawa ~ Campagne de la flamme bleue ~",
		"stations": [
			"Gare d'Akabashi (5 minutes à pied)"
		],
		"term_text": "2017/06/01(bois)"
	},
	{
		"name": "Aquarium de feux d'artifice par NAKED",
		"stations": [
			"Gare de Shinagawa"
		],
		"term_text": "2017/07/08(sol)"
	}
	...
]

Normalement, il est nécessaire de créer correctement la pagination, l'analyse des données de date et d'heure, etc., mais pour le moment, j'ai pu faire du grattage festif en douceur.

Veuillez vous référer à la source du scraping du festival ci-dessous.

github

c'est tout.

Recommended Posts

Grattage festif avec Python, scrapy
Grattage avec Python
Grattage avec Python
Grattage en Python (préparation)
Essayez de gratter avec Python.
Grattage avec Python + PhantomJS
Grattage avec coquille tremblante
Grattage avec du sélénium [Python]
Scraping avec Python + PyQuery
Scraping RSS avec Python
J'ai essayé de gratter avec Python
Web scraping avec python + JupyterLab
Grattage au sélénium en Python
Grattage avec Selenium + Python Partie 1
Grattage avec chromedriver en python
Grattage avec du sélénium en Python
Grattage Web facile avec Scrapy
Grattage avec Tor en Python
Scraping prévisions météorologiques avec python
Grattage avec Selenium + Python Partie 2
J'ai essayé de gratter avec du python
Web scraping débutant avec python
[Scraping] Scraping Python
Essayez de gratter avec Python + Beautiful Soup
Scraping avec Node, Ruby et Python
Scraping avec Selenium en Python (Basic)
Grattage avec Python, Selenium et Chromedriver
Web scraping avec Python Première étape
J'ai essayé webScraping avec python.
Grattage avec Python et belle soupe
Faisons du scraping d'images avec Python
Obtenez les tendances Qiita avec le scraping Python
Mémo d'apprentissage "Scraping & Machine Learning avec Python"
Obtenez des informations météorologiques avec Python et le grattage
Obtenez des informations sur la propriété en grattant avec python
Mémo de raclage Python
Grattage au sélénium
FizzBuzz en Python3
Scraping Python get_ranker_categories
Grattage au sélénium ~ 2 ~
Grattage WEB avec Python (pour mémo personnel)
Statistiques avec python
Python avec Go
Automatisez des tâches simples avec Python Part1 Scraping
Premiers pas avec Python Web Scraping Practice
Twilio avec Python
Intégrer avec Python
Python racle eBay
Jouez avec 2016-Python
AES256 avec python
Testé avec Python
Grattage avec du sélénium
Redémarrez avec Scrapy
[Note personnelle] Scraping de pages Web en python3
python commence par ()
Site de courses de chevaux Web scraping avec Python
Grattage Python get_title
avec syntaxe (Python)