Я особисто вважаю за краще використовувати скрап та селен та докерінг в обох контейнерах. Таким чином ви можете встановити як мінімум клопоту, так і сканувати сучасні веб-сайти, які майже всі містять JavaScript у тій чи іншій формі. Ось приклад:
Використовуйте 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)
Справжня магія трапляється у midwares.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:
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
, введіть компакт-диск у потрібний каталог та запустіть свій скрепер scrapy crawl my_spider
.
Вся справа знаходиться на моїй сторінці github, і ви можете отримати її звідси