Dieser Artikel verwendet ein "Scraping-Framework" namens "Scrapy" für das Web-Scraping in Python.
Informationen zum Framework Übersicht
Components
Scrapy Engine
Steuern Sie jede Komponente wie im Diagramm "Datenfluss" oben gezeigt.
Scheduler
Empfängt Anforderungen von der Scrapy Engine und stapelt sie in einer Warteschlange, damit sie aus späteren Anforderungen von der Scrapy Engine abgerufen werden können.
Downloader
Downloader ruft die Webseite ab, füttert sie an Scrapy Engine und gibt sie an Spider weiter.
Spiders
Spinnen sind benutzerdefinierte Klassen, in denen Scrapy-Benutzer die Antwort analysieren, um Elemente (abgekratzte Elemente) oder zusätzliche Anforderungen zu extrahieren.
Ich passe hier hauptsächlich selbst an.
Item Pipeline
Die Item-Pipeline behandelt das Item, sobald es von Spider extrahiert wurde. Typische Aufgaben sind Bereinigung, Validierung und Persistenz (z. B. Speichern von Elementen in einer Datenbank).
Sie können es in eine JSON-Datei schreiben oder in einer Datenbank speichern.
Downloader middlewares
Downloader-Middlewares zwischen Scrapy Engine und Downloader sind spezielle Hooks, die Anforderungen verarbeiten, die von Scrapy Engine an Downloader und von Downloader an Scrapy Engine übergeben werden.
Ich werde es dieses Mal nicht benutzen.
Spider middlewares
Spider-Middlewares sind spezielle Hooks, die sich zwischen der Scrapy Engine und Spider befinden und Spider-Eingaben (Antworten) und Ausgaben (Elemente und Anforderungen) verarbeiten können.
Ich werde es dieses Mal nicht benutzen.
Install Requirements
Für die Installation erforderliche Bibliothek
python-dev
, zlib1g-dev
, libxml2-dev
and libxslt1-dev
are required for lxml
libssl-dev
and libffi-dev
are required for cryptography
--Erstellen einer lokalen Entwicklungsumgebung mit Docker --Ein Projekt erstellen
Lass uns Tokio genießen wurde zum Schaben ausgewählt.
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 sieht so aus
# Production
# =============================================================================
scrapy==1.4.0
# Development
# =============================================================================
flake8==3.3.0
flake8-mypy==17.3.3
mypy==0.511
docker build -t festival-crawler-app .
#Führen Sie direkt unter dem Arbeitsverzeichnis aus
docker run -itd -v $(pwd)/app:/usr/src/app \
--name festival-crawler-app \
festival-crawler-app
Geben Sie den gestarteten Container ein
docker exec -it festival-crawler-app /bin/sh
# scrapy startproject <project_name> [project_dir]
scrapy startproject scraping .
Das erstellte Verzeichnis sieht wie folgt aus.
Vor dem Erstellen eines Projekts
├── Dockerfile
├── app
└── pip_requirements.txt
Nach dem Erstellen des Projekts
.
├── Dockerfile
├── app
│ ├── scraping
│ │ ├── __init__.py
│ │ ├── items.py
│ │ ├── middlewares.py
│ │ ├── pipelines.py
│ │ ├── settings.py
│ │ └── spiders
│ │ └── __init__.py
│ └── scrapy.cfg
└── pip_requirements.txt
Sie können festlegen, wie lange der Downloader darauf wartet, aufeinanderfolgende Seiten von derselben Website herunterzuladen.
__ Stellen Sie diesen Wert so ein, dass die verkratzte Website nicht überlastet wird. __ __
Es scheint gut, die robots.txt der Zielsite zu überprüfen und den Wert anzugeben, wenn "Crawl-Verzögerung" angegeben ist.
#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(),
)
Die Item-Klasse definiert die Daten, die durch Scraping verarbeitet werden sollen. Dieses Mal werden wir die folgenden Daten definieren.
input_processor
und output_processor
sind sehr praktisch, da sie Daten zum Zeitpunkt der Ausgabe akzeptieren bzw. verarbeiten können.
# -*- 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()
Die Implementierung hier ist eine Beschreibung des tatsächlichen Scrapings.
Die Klassenvariable name: str ='fest: august'
ist der Name des Befehls, der über die Befehlszeile ausgeführt werden soll. Wenn Sie das Obige schreiben, können Sie beim "Scrapy Crawl Festival: August" Scraping durchführen.
# -*- 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)
Das Obige ist möglicherweise nicht die richtige Verwendung, aber ich dachte, es wäre verwirrend, die CSS-Selektoren in festival.py
aufzulisten, also habe ich es in ItemLoader
definiert. Die Methode "set_load_items" ist die neu hinzugefügte Methode, die in der Klasse "ItemLoader" nicht vorhanden ist.
Die Ausgabe kann mit der Option -o angegeben werden. Wenn Sie es in der Datenbank usw. speichern möchten, müssen Sie es separat implementieren.
scrapy crawl festival:august -o result.json
Jetzt können Sie die Festivalinformationen für August erhalten
[
{
"name": "ECO EDO Nihonbashi Kunstaquarium 2017 ~ Edo / Goldfisch Ryo ~ & Nachtaquarium",
"stations": [
"Shin Nihonbashi Station"
],
"term_text": "2017/07/07(Geld)"
},
{
"name": "Tennokawa Illumination ~ Blue Flame Campaign ~",
"stations": [
"Akabashi Station (5 Minuten zu Fuß)"
],
"term_text": "2017/06/01(Holz)"
},
{
"name": "Feuerwerk Aquarium von NAKED",
"stations": [
"Shinagawa Station"
],
"term_text": "2017/07/08(Boden)"
}
...
]
Normalerweise ist es notwendig, Paging ordnungsgemäß zu erstellen, Datums- und Zeitdaten usw. zu analysieren, aber vorerst konnte ich festliches Schaben sanft durchführen.
Bitte beziehen Sie sich unten auf die Quelle des Festival-Scrapings.
das ist alles.
Recommended Posts