Saya pribadi lebih suka menggunakan kasar dan selenium dan merendam keduanya dalam wadah terpisah. Dengan cara ini Anda dapat menginstal keduanya dengan kerumitan minimal dan merayapi situs web modern yang hampir semuanya berisi javascript dalam satu bentuk atau lainnya. Ini sebuah contoh:
Gunakan scrapy startproject
untuk membuat scraper Anda dan tuliskan laba-laba Anda, kerangkanya bisa sesederhana ini:
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)
Keajaiban yang sebenarnya terjadi di middlewares.py. Timpa dua metode dalam middleware pengunduh, __init__
dan process_request
, dengan cara berikut:
# 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)
Jangan lupa untuk mengaktifkan middlware ini dengan menghapus komentar pada baris berikutnya dalam file settings.py:
DOWNLOADER_MIDDLEWARES = {
'sample_project.middlewares.SampleProjectDownloaderMiddleware': 543,}
Selanjutnya untuk buruh pelabuhan. Buat Anda Dockerfile
dari gambar yang ringan (Saya menggunakan python Alpine di sini), salin direktori proyek Anda untuk itu, instal persyaratan:
# 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
Dan akhirnya kumpulkan semuanya dalam 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
Lari docker-compose up -d
. Jika Anda melakukan ini pertama kali akan butuh waktu cukup lama untuk mengambil selenium / standalone-chrome terbaru dan membuat gambar scraper Anda juga.
Setelah selesai, Anda dapat memeriksa apakah wadah Anda berjalan docker ps
dan juga memeriksa bahwa nama wadah selenium cocok dengan variabel lingkungan yang kami berikan ke wadah scraper kami (di sini, itu SELENIUM_LOCATION=samplecrawler_selenium_1
).
Masukkan wadah scraper Anda dengan docker exec -ti YOUR_CONTAINER_NAME sh
, perintah untuk saya adalah docker exec -ti samplecrawler_my_scraper_1 sh
, cd ke direktori yang benar dan jalankan scraper Anda dengan scrapy crawl my_spider
.
Semuanya ada di halaman github saya dan Anda bisa mendapatkannya dari sini