나는 개인적으로 scrapy와 selenium을 사용하고 별도의 컨테이너에 도커를 사용하는 것을 선호합니다. 이렇게하면 최소한의 번거 로움과 크롤링이 가능한 최신 웹 사이트를 모두 설치할 수 있습니다. 예를 들면 다음과 같습니다.
를 사용 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에서 발생합니다. 다운로더 미들웨어의 두 가지 방법을 덮어 쓰기, __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 파일에서 다음 줄의 주석 처리를 제거하여이 middlware를 활성화하는 것을 잊지 마십시오.
DOWNLOADER_MIDDLEWARES = {
'sample_project.middlewares.SampleProjectDownloaderMiddleware': 543,}
도 커화를위한 다음. 당신의 작성 Dockerfile
요구를 설치, 경량의 이미지에서 (내가 사용 파이썬 여기 알파인)를 여기에 프로젝트 디렉토리를 복사 :
# 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
. 이 작업을 처음 수행하는 경우 최신 셀레늄 / 독립 실행 형 크롬을 가져오고 스크레이퍼 이미지도 빌드하는 데 시간이 걸립니다.
완료되면 컨테이너가 실행 중인지 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 페이지에 있으며 여기 에서 얻을 수 있습니다