Лично я предпочитаю использовать скрап и селен и докеризацию как в отдельных контейнерах.Таким образом, вы можете установить как с минимальными хлопотами, так и сканировать современные веб-сайты, которые почти все содержат 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)
Настоящая магия происходит в промежуточном программном обеспечении.ру.Перезапишите два метода в промежуточном программном обеспечении загрузчика, __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 страницу, и вы можете получить его от здесь