私は個人的には、スクレイピーとセレンを使用し、両方を別々のコンテナーでドッキングすることを好みます。この方法で、最小限の手間で両方をインストールし、ほとんどすべてのJavascriptが何らかの形式で含まれている最新のWebサイトをクロールできます。次に例を示します。
を使用しscrapy startproject
てスクレーパーを作成し、スパイダーを記述します。スケルトンは次のように簡単です。
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)
本当の魔法は、middlewares.pyで発生します。ダウンローダミドルウェアにおける2つのメソッドを上書きし、 __init__
そして process_request
、次のように:
# 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)
settings.pyファイルの次の行のコメントを外して、このミドルウェアを有効にすることを忘れないでください。
DOWNLOADER_MIDDLEWARES = {
'sample_project.middlewares.SampleProjectDownloaderMiddleware': 543,}
次はドッキングです。作成し、あなたのDockerfile
軽量画像から(私はここでのpythonアルパインを使用しています)、プロジェクトディレクトリは、それをコピーし、要件をインストールします。
# 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
そして最後にそれをすべて一緒にまとめ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
を実行しますdocker-compose up -d
。これを初めて行う場合、最新のselenium / standalone-chromeをフェッチしてスクレイパーイメージをビルドするのにも時間がかかります。
完了したら、コンテナーが実行されdocker ps
ていることを確認し、セレンコンテナーの名前が、スクレイパーコンテナーに渡した環境変数の名前と一致していることを確認します(ここではSELENIUM_LOCATION=samplecrawler_selenium_1
)。
でスクレーパーコンテナーを入力します。docker exec -ti YOUR_CONTAINER_NAME sh
コマンドはでしdocker exec -ti samplecrawler_my_scraper_1 sh
た。適切なディレクトリにcdして、でスクレーパーを実行しますscrapy crawl my_spider
。
すべては私のgithubページにあり、ここから入手できます