Cet article utilise un "framework de scraping" appelé "scrapy" pour le web scraping en python.
À propos du framework Overview
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
python-dev
, zlib1g-dev
, libxml2-dev
and libxslt1-dev
are required for lxml
libssl-dev
and libffi-dev
are required for cryptography
--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.
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
docker build -t festival-crawler-app .
#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
# 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
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
# -*- 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.
# -*- 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
.
# -*- 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
.
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.
c'est tout.
Recommended Posts