Ich persönlich bevorzuge die Verwendung von Scrapy und Selen und das Andocken beider in getrennten Behältern. Auf diese Weise können Sie moderne Websites, die fast alle Javascript in der einen oder anderen Form enthalten, mit minimalem Aufwand installieren und crawlen. Hier ist ein Beispiel:
Verwenden Sie die scrapy startproject
, um Ihren Schaber zu erstellen und Ihre Spinne zu schreiben. Das Skelett kann so einfach sein:
import scrapy
class MySpider(scrapy.Spider):
name = 'my_spider'
start_urls = ['https://somewhere.com']
def start_requests(self):
yield scrapy.Request(url=self.start_urls[0])
def parse(self, response):
# do stuff with results, scrape items etc.
# now were just checking everything worked
print(response.body)
Die wahre Magie findet in der Middleware statt. Überschreiben Sie zwei Methoden in der Downloader-Middleware __init__
und zwar process_request
auf folgende Weise:
# import some additional modules that we need
import os
from copy import deepcopy
from time import sleep
from scrapy import signals
from scrapy.http import HtmlResponse
from selenium import webdriver
class SampleProjectDownloaderMiddleware(object):
def __init__(self):
SELENIUM_LOCATION = os.environ.get('SELENIUM_LOCATION', 'NOT_HERE')
SELENIUM_URL = f'http://{SELENIUM_LOCATION}:4444/wd/hub'
chrome_options = webdriver.ChromeOptions()
# chrome_options.add_experimental_option("mobileEmulation", mobile_emulation)
self.driver = webdriver.Remote(command_executor=SELENIUM_URL,
desired_capabilities=chrome_options.to_capabilities())
def process_request(self, request, spider):
self.driver.get(request.url)
# sleep a bit so the page has time to load
# or monitor items on page to continue as soon as page ready
sleep(4)
# if you need to manipulate the page content like clicking and scrolling, you do it here
# self.driver.find_element_by_css_selector('.my-class').click()
# you only need the now properly and completely rendered html from your page to get results
body = deepcopy(self.driver.page_source)
# copy the current url in case of redirects
url = deepcopy(self.driver.current_url)
return HtmlResponse(url, body=body, encoding='utf-8', request=request)
Vergessen Sie nicht, diese Middlware zu aktivieren, indem Sie die nächsten Zeilen in der Datei settings.py auskommentieren:
DOWNLOADER_MIDDLEWARES = {
'sample_project.middlewares.SampleProjectDownloaderMiddleware': 543,}
Weiter zur Dockerisierung. Erstellen Sie Ihr Dockerfile
Image aus einem einfachen Image (ich verwende hier Python Alpine), kopieren Sie Ihr Projektverzeichnis in das Image und installieren Sie die Anforderungen:
# Use an official Python runtime as a parent image
FROM python:3.6-alpine
# install some packages necessary to scrapy and then curl because it's handy for debugging
RUN apk --update add linux-headers libffi-dev openssl-dev build-base libxslt-dev libxml2-dev curl python-dev
WORKDIR /my_scraper
ADD requirements.txt /my_scraper/
RUN pip install -r requirements.txt
ADD . /scrapers
Und zum Schluss alles zusammen in docker-compose.yaml
:
version: '2'
services:
selenium:
image: selenium/standalone-chrome
ports:
- "4444:4444"
shm_size: 1G
my_scraper:
build: .
depends_on:
- "selenium"
environment:
- SELENIUM_LOCATION=samplecrawler_selenium_1
volumes:
- .:/my_scraper
# use this command to keep the container running
command: tail -f /dev/null
Ausführen docker-compose up -d
. Wenn Sie dies zum ersten Mal tun, dauert es eine Weile, bis das neueste Selen / Standalone-Chrom abgerufen und Ihr Scraper-Image erstellt wurde.
Sobald dies erledigt ist, können Sie überprüfen, ob Ihre Container ausgeführt werden docker ps
und ob der Name des Selencontainers mit dem der Umgebungsvariablen übereinstimmt, die wir an unseren Scraper-Container übergeben haben (hier war es SELENIUM_LOCATION=samplecrawler_selenium_1
).
Geben Sie Ihren Scraper-Container mit ein docker exec -ti YOUR_CONTAINER_NAME sh
, der Befehl für mich lautete docker exec -ti samplecrawler_my_scraper_1 sh
: CD in das richtige Verzeichnis und führen Sie Ihren Scraper mit aus scrapy crawl my_spider
.
Das Ganze ist auf meiner Github-Seite und du kannst es von hier bekommen