โดยส่วนตัวแล้วฉันชอบที่จะใช้ scrapy และ selenium และ dockerizing ทั้งสองในภาชนะที่แยกต่างหาก วิธีนี้คุณสามารถติดตั้งได้ทั้งกับความยุ่งยากน้อยที่สุดและรวบรวมข้อมูลเว็บไซต์ทันสมัยที่เกือบทั้งหมดมีจาวาสคริปต์ในรูปแบบเดียวหรืออีกรูปแบบหนึ่ง นี่คือตัวอย่าง:
ใช้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)
อย่าลืมที่จะเปิดใช้งาน middlware นี้โดยไม่ใส่เครื่องหมายในบรรทัดถัดไปในไฟล์ settings.py:
DOWNLOADER_MIDDLEWARES = {
'sample_project.middlewares.SampleProjectDownloaderMiddleware': 543,}
ถัดไปสำหรับการเชื่อมต่อ สร้างของคุณDockerfile
จากอิมเมจน้ำหนักเบา (ฉันใช้ python Alpine ที่นี่) คัดลอกไดเรกทอรีโครงการของคุณไปยังข้อกำหนดในการติดตั้ง:
# 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 ของฉันและคุณสามารถรับได้จากที่นี่