DrissionPage и residential-прокси: полное руководство по веб-скрапингу

Практическое руководство по DrissionPage — фреймворку Python, объединяющему HTTP-запросы и управление Chromium. Настройка прокси, режим SessionPage/ChromiumPage/WebPage, паттерны продакшена.

DrissionPage Proxy Guide: One Python Tool for HTTP and Chromium Scraping
В этой статье

Что такое DrissionPage и зачем ему прокси

Python-разработчики, занимающиеся веб-скрапингом, давно привыкли к компромиссу: requests для быстрых HTTP-запросов или Selenium/Playwright для рендеринга JavaScript. DrissionPage устраняет этот выбор, объединяя оба подхода в одном фреймворке с общим состоянием сессии. Вы начинаете с лёгкого HTTP-запроса, а при необходимости переключаетесь на полноценный браузер Chromium — без потери cookies, заголовков и контекста.

Однако даже лучший фреймворк бесполезен против жёстких антибот-систем, если все запросы идут с одного IP-адреса. Residential-прокси необходимы для обхода гео-ограничений, rate-limiting и IP-based fingerprinting. В этом руководстве мы разберём, как интегрировать DrissionPage с прокси ProxyHat для надёжного и масштабируемого скрапинга.

Правовая оговорка: статья охватывает сбор только публично доступных данных. Неправомерный доступ к защищённым системам может нарушать CFAA (США), GDPR (ЕС) и аналогичные законы других юрисдикций. Уважайте robots.txt, условия обслуживания сайтов и ограничения по скорости. Если у сайта есть официальный API — предпочтите его.

Архитектура DrissionPage: три режима работы

DrissionPage предлагает три класса страниц, каждый из которых решает свою задачу. Понимание различий между ними — ключ к эффективному скрапингу, который не сжигает ресурсы впустую.

SessionPage — чистый HTTP

SessionPage работает поверх библиотеки requests (или urllib3). Это самый быстрый и лёгкий режим: один запрос занимает ~50ms, расход RAM — около 20MB. Идеально для статичных HTML-страниц, REST API и JSON-эндпоинтов, не требующих рендеринга JavaScript.

ChromiumPage — полноценный браузер

ChromiumPage управляет браузером через Chrome DevTools Protocol (CDP) — без Selenium WebDriver в качестве посредника. Это даёт прямой доступ к сети, DOM и JavaScript-контексту страницы. Запуск страницы занимает ~200-500ms, расход RAM — 150-300MB на инстанс. Используется, когда контент рендерится JavaScript или требует взаимодействия с динамическими элементами.

WebPage — переключение на лету

WebPage — ключевая инновация DrissionPage. Он объединяет SessionPage и ChromiumPage, позволяя переключаться между HTTP- и браузерным режимами в рамках одной сессии. Cookies, заголовки и состояние сохраняются при переключении. Это снижает стоимость скрапинга на 40-60% для сайтов, где только часть страниц требует рендеринга JS.

СвойствоSessionPageChromiumPageWebPage
Движокrequests / urllib3CDP → ChromiumОба, переключение
Скорость запроса~50ms~200-500msЗависит от режима
JS-рендерингНетДаДа (при переключении)
Расход RAM~20MB150-300MBЗависит от режима
Прокси-настройкаset_proxies()ChromiumOptions.set_proxy()Оба метода
Перехват XHRНетlisten.start()listen.start()

Подробная документация по всем классам доступна на официальном сайте DrissionPage.

Идиоматичный API DrissionPage

DrissionPage имеет свой синтаксис локаторов, который компактнее XPath и гибче CSS-селекторов. Понимание этих паттернов — основа drissionpage tutorial для продакшена.

Локаторы ele() и eles()

Метод ele() возвращает первый найденный элемент, eles() — список всех совпадений. Синтаксис поддерживает несколько форматов:

from DrissionPage import WebPage

page = WebPage()
page.get('https://example.com')

# По тегу
title = page.ele('tag:h1').text

# По атрибуту
button = page.ele('@class=submit-btn')

# XPath
items = page.eles('xpath://div[@class="item"]')

# Комбинированный синтаксис: tag + атрибут
links = page.eles('tag:a@href^=https')

# Текст содержит
elem = page.ele('text:Купить')

Комбинированный синтаксис tag:a@href^=https означает: найти все теги <a>, у которых атрибут href начинается с https. Это читается проще, чем эквивалентный XPath //a[starts-with(@href, 'https')].

ChromiumOptions — конфигурация браузера

ChromiumOptions управляет параметрами запуска Chromium: headless-режим, user-agent, прокси, размер окна, расширения. Для drissionpage chromium сценариев это центральная точка конфигурации:

from DrissionPage import ChromiumOptions

co = ChromiumOptions()
co.headless(True)
co.set_argument('--no-sandbox')
co.set_argument('--disable-gpu')
co.set_user_agent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) ...')
co.set_proxy('http://user-country-US:pass@gate.proxyhat.com:8080')

listen.start() — перехват сетевых пакетов

Одна из самых мощных возможностей DrissionPage — перехват XHR/Fetch запросов через CDP. Вы можете слушать фоновые запросы и извлекать JSON-данные, которые сайт загружает асинхронно:

from DrissionPage import ChromiumPage

page = ChromiumPage()
page.listen.start('api/products')  # фильтр по URL
page.get('https://shop.example.com/catalog')

for packet in page.listen.steps(count=10):
    print(packet.url)
    data = packet.response.body  # JSON-ответ
    print(data)

Этот паттерн часто позволяет получить структурированные данные из скрытых API, минуя парсинг HTML вообще. Если сайт загружает данные через XHR в формате JSON — нет смысла парсить DOM.

Настройка drissionpage proxy: SessionPage и ChromiumPage

Прокси-конфигурация различается между режимами. В SessionPage прокси устанавливается через метод set_proxies(), в ChromiumPage — через ChromiumOptions.set_proxy().

Прокси для SessionPage

from DrissionPage import SessionPage

page = SessionPage()
page.set_proxies('http://user-country-DE:pass@gate.proxyhat.com:8080')
page.get('https://httpbin.org/ip')
print(page.html)

Прокси для ChromiumPage

from DrissionPage import ChromiumPage, ChromiumOptions

co = ChromiumOptions()
co.set_proxy('http://user-country-DE:pass@gate.proxyhat.com:8080')
co.headless(True)

page = ChromiumPage(co)
page.get('https://httpbin.org/ip')
print(page.ele('tag:pre').text)

Почему residential-прокси, а не datacenter

Datacenter IP-адреса легко распознаются антибот-системами — Cloudflare, Akamai, PerimeterX и Datadome ведут базы диапазонов дата-центров. Residential-прокси используют IP реальных устройств, что делает их неотличимыми от обычных пользователей. Для жёстких целей — SERP-трекинг, e-commerce, социальные сети — residential-прокси обеспечивают success rate 90%+ против 30-50% у datacenter.

ProxyHat предоставляет residential-прокси с гео-таргетингом по странам и городам, а также sticky-сессии для сохранения IP между запросами. Подробности — на странице локаций ProxyHat и в официальной документации.

Практический пример: WebPage с ProxyHat

Теперь соберём всё вместе. Мы создадим WebPage, который начинает в HTTP-режиме через residential-прокси США, собирает базовые данные, а затем переключается в режим Chromium для рендеринга JS-зависимой страницы — с сохранением cookies и сессии.

from DrissionPage import WebPage
import json

# ProxyHat: residential, США, sticky-сессия
PROXY_HTTP = 'http://user-country-US-session-abc123:pass@gate.proxyhat.com:8080'

def scrape_product(url: str) -> dict:
    page = WebPage()

    # --- Режим 1: SessionPage (быстрый HTTP) ---
    page.set_proxies(PROXY_HTTP)
    page.get(url)

    # Проверяем, есть ли нужные данные в HTML
    title_el = page.ele('tag:h1')
    if title_el:
        title = title_el.text
        price_el = page.ele('@class=price')
        price = price_el.text if price_el else None

        if price:  # Данные доступны без JS
            page.close()
            return {'title': title, 'price': price, 'mode': 'http'}

    # --- Режим 2: переключение в Chromium ---
    # Cookies и заголовки сохраняются автоматически
    page.change_mode()  # SessionPage → ChromiumPage

    # Тот же прокси применяется к браузеру
    # (настраивается через ChromiumOptions при инициализации,
    #  либо через page.set.proxy() после переключения)

    page.get(url)  # перезагружаем с рендерингом JS
    page.wait.eles_loaded('@class=price')

    title = page.ele('tag:h1').text
    price = page.ele('@class=price').text

    # Перехватываем XHR для получения структурированных данных
    page.listen.start('api/product')
    page.get(url)
    packet = page.listen.wait()
    if packet:
        api_data = json.loads(packet.response.body)
        price = api_data.get('price', price)

    page.close()
    return {'title': title, 'price': price, 'mode': 'chromium'}

result = scrape_product('https://shop.example.com/product/123')
print(json.dumps(result, indent=2))

Этот паттерн — «HTTP сначала, браузер при необходимости» — снижает расход ресурсов на 50%+ для сайтов, где только часть страниц требует рендеринга. Вы платите за браузер только тогда, когда он действительно нужен.

Продвинутая конфигурация с ProxyHat SDK

Для управления ротацией и гео-таргетингом можно построить helper, который генерирует username с нужными параметрами:

import random
import string

def build_proxyhat_username(
    country: str = 'US',
    city: str = None,
    session_id: str = None,
    mobile: bool = False
) -> str:
    """Строит username для ProxyHat с гео и сессионными параметрами."""
    parts = ['user']
    if mobile:
        parts.append('mobile')
    parts.append(f'country-{country}')
    if city:
        parts.append(f'city-{city.lower()}')
    if session_id:
        parts.append(f'session-{session_id}')
    return '-'.join(parts)

def make_proxy(country='US', session_id=None):
    username = build_proxyhat_username(
        country=country,
        session_id=session_id or ''.join(
            random.choices(string.ascii_lowercase + string.digits, k=8)
        )
    )
    return f'http://{username}:pass@gate.proxyhat.com:8080'

# Пример: sticky-сессия для одного домена
proxy = make_proxy(country='US', session_id='shop123')
# Пример: ротация при каждом запросе (без session_id)
proxy_rotating = make_proxy(country='US')

Sticky-сессии важны для сайтов, которые привязывают корзину или токен к IP-адресу. Если IP меняется в середине сессии — сайт может разлогинить пользователя. ProxyHat поддерживает sticky-сессии до 30 минут через параметр session-{id} в username. Тарифы и лимиты — на странице цен ProxyHat.

Паттерны продакшена: масштабирование DrissionPage

Переход от прототипа к продакшену требует другой архитектуры. Вот ключевые паттерны для надёжного drissionpage web scraping в продакшене.

1. Per-session proxy pinning

Каждая логическая сессия скрапинга должна привязываться к одному IP через sticky-сессию. Это предотвращает срабатывание антибот-систем, которые отслеживают смену IP в рамках одной пользовательской сессии:

from DrissionPage import WebPage
import uuid

class ScraperSession:
    def __init__(self, country='US'):
        self.session_id = str(uuid.uuid4())[:8]
        self.proxy = make_proxy(country=country, session_id=self.session_id)
        self.page = WebPage()
        self.page.set_proxies(self.proxy)

    def fetch(self, url):
        for attempt in range(3):
            try:
                self.page.get(url, timeout=15)
                if self.page.status_code == 200:
                    return self.page.html
            except Exception as e:
                print(f'Попытка {attempt+1} неудачна: {e}')
                # Ротируем сессию при ошибке
                self.session_id = str(uuid.uuid4())[:8]
                self.proxy = make_proxy(country='US', session_id=self.session_id)
                self.page.set_proxies(self.proxy)
        return None

    def close(self):
        self.page.close()

2. Retries с экспоненциальной задержкой

Сетевые ошибки и временные блокировки — норма при скрапинге. Реализуйте retry с экспоненциальной задержкой и ротацией IP при повторных попытках:

  • Попытка 1: базовая задержка 1s
  • Попытка 2: задержка 2s, новый IP
  • Попытка 3: задержка 4s, новый IP + новый User-Agent
  • Попытка 4: задержка 8s, переключение в Chromium-режим

3. Packet capture для обнаружения скрытых API

Многие сайты загружают данные через XHR/Fetch в формате JSON. Вместо парсинга HTML используйте listen.start() для перехвата этих запросов. Это быстрее, надёжнее и даёт структурированные данные. Проверьте вкладку Network в DevTools — если видите JSON-ответы, DrissionPage может их перехватить программно.

4. Управление конкурентностью

ChromiumPage требует ~150-300MB RAM на инстанс. На сервере с 8GB RAM можно запускать 15-20 параллельных браузеров. Для SessionPage лимит выше — 100+ параллельных сессий на те же ресурсы. Используйте asyncio или concurrent.futures.ThreadPoolExecutor для SessionPage и пул процессов для ChromiumPage.

from concurrent.futures import ThreadPoolExecutor, as_completed

def scrape_url(url: str) -> dict:
    session = ScraperSession(country='US')
    try:
        html = session.fetch(url)
        # ... парсинг ...
        return {'url': url, 'status': 'ok'}
    finally:
        session.close()

urls = ['https://example.com/page1', 'https://example.com/page2']

with ThreadPoolExecutor(max_workers=10) as executor:
    futures = [executor.submit(scrape_url, url) for url in urls]
    for f in as_completed(futures):
        result = f.result()
        print(result)

5. Контейнеризация

Для масштабирования запускайте DrissionPage в Docker-контейнерах с Chromium, установленным системно. Базовый образ:

FROM python:3.11-slim

RUN apt-get update && apt-get install -y \
    chromium \
    chromium-driver \
    fonts-liberation \
    && rm -rf /var/lib/apt/lists/*

RUN pip install DrissionPage

ENV CHROME_PATH=/usr/bin/chromium

COPY scraper.py /app/
WORKDIR /app
CMD ["python", "scraper.py"]

При горизонтальном масштабировании каждый контейнер получает свой пул прокси-сессий. Оркестрация через Kubernetes позволяет автоматически масштабировать количество подов в зависимости от нагрузки. Для SERP-трекинга с высокой частотой запросов см. use-case SERP-трекинга.

Когда НЕ переходить на браузер

Преждевременное переключение в Chromium-режим — частая ошибка. Браузер в 4-10 раз медленнее и требует в 10-15 раз больше RAM. Переходите на Chromium только если:

  • Контент рендерится JavaScript (React, Vue, Angular SPA)
  • Страница требует взаимодействия (клик, скролл, заполнение формы)
  • Антибот-система требует выполнения JS-челленджей (Cloudflare Turnstile, reCAPTCHA)
  • Нужно перехватить XHR-запросы через listen.start()

Во всех остальных случаях SessionPage достаточен. Если сайт отдаёт HTML с данными при прямом HTTP-запросе — нет смысла запускать браузер. Проверьте: сделайте curl запрос и посмотрите, есть ли нужные данные в ответе. Если да — используйте SessionPage.

Для задач, где браузер всё-таки нужен, drissionpage chromium через CDP эффективнее Selenium, так как обходит WebDriver-обнаружение. CDP не оставляет следов navigator.webdriver, которые Selenium WebDriver выставляет по умолчанию.

Ключевые выводы

  • DrissionPage объединяет HTTP и браузерный скрапинг в одном фреймворке с общим состоянием — это снижает стоимость и сложность инфраструктуры.
  • WebPage позволяет переключаться между SessionPage и ChromiumPage на лету, сохраняя cookies и сессию.
  • Прокси настраиваются через set_proxies() для HTTP и ChromiumOptions.set_proxy() для браузера, с residential-прокси ProxyHat через gate.proxyhat.com:8080.
  • listen.start() перехватывает XHR/Fetch запросы — часто это лучший способ получить структурированные данные без парсинга HTML.
  • Sticky-сессии через session-{id} в username сохраняют IP для одной логической сессии скрапинга.
  • Переходите в Chromium-режим только при необходимости — это снижает расход RAM в 10-15 раз для простых страниц.
  • Уважайте robots.txt, условия обслуживания и ограничения по скорости. Собирайте только публичные данные.

Готовы начать? Изучите use-case веб-скрапинга и тарифы ProxyHat для выбора подходящего плана residential-прокси.

Часто задаваемые вопросы

Что такое DrissionPage?

DrissionPage — это Python-фреймворк для веб-автоматизации, который объединяет HTTP-запросы (через requests) и управление браузером Chromium (через Chrome DevTools Protocol) в одном API. Три режима — SessionPage, ChromiumPage и WebPage — позволяют переключаться между лёгкими HTTP-запросами и полноценным рендерингом JS с сохранением cookies и состояния сессии.

Зачем DrissionPage нужен прокси?

Без прокси все запросы идут с одного IP-адреса, что быстро приводит к блокировке антибот-системами. Residential-прокси используют IP реальных устройств, что делает запросы неотличимыми от обычных пользователей. Sticky-сессии позволяют сохранить IP для одной логической сессии, а гео-таргетинг — обходить региональные ограничения.

Какой тип прокси лучше для DrissionPage?

Residential-прокси — оптимальный выбор для большинства задач скрапинга в DrissionPage. Они обеспечивают success rate 90%+ против 30-50% у datacenter-прокси, так как используют IP реальных провайдеров. Mobile-прокси ещё надёжнее, но дороже. Datacenter-прокси подходят только для простых сайтов без антибот-защиты.

Как избежать блокировок при скрапинге через DrissionPage?

Используйте residential-прокси с ротацией IP, sticky-сессии для связанных запросов, реалистичные User-Agent, задержки между запросами (1-3 секунды), и переключайтесь в Chromium-режим только когда HTTP недостаточен. Перехватывайте XHR через listen.start() для получения данных из скрытых API вместо парсинга HTML. Уважайте robots.txt и ограничения по скорости.

Чем DrissionPage отличается от Selenium и Playwright?

DrissionPage управляет Chromium напрямую через CDP, без WebDriver-посредника, что делает его менее обнаружимым антибот-системами. Кроме того, DrissionPage позволяет переключаться между HTTP- и браузерным режимами в рамках одной сессии через WebPage, сохраняя cookies и состояние. Selenium и Playwright работают только в браузерном режиме.

Готовы начать?

Резидентные, ISP и мобильные прокси в 148+ странах. Создайте бесплатный аккаунт.

Создать бесплатный аккаунт
← Вернуться в Блог