DrissionPage 代理配置完全指南:HTTP 与浏览器双模式爬虫实战

学习如何在 DrissionPage 中配置 ProxyHat 住宅代理,实现 SessionPage HTTP 模式与 ChromiumPage 浏览器模式无缝切换,涵盖 ele() 定位、listen 监听、会话固定与并发控制。

DrissionPage Proxy Guide: HTTP + Chromium Scraping with Residential IPs
本文目录

法律与合规声明:本文仅讨论公开可访问数据的采集方法。在使用 DrissionPage 或任何爬虫工具前,请遵守目标网站的 robots.txt 和服务条款,并了解美国《计算机欺诈和滥用法》(CFAA)欧盟《通用数据保护条例》(GDPR)的相关规定。如果目标平台提供官方 API,请优先使用。

如果你是一名 Python 爬虫开发者,大概率遇到过这样的困境:requests 速度快、内存占用低,但碰到 JS 渲染页面就无能为力;Selenium 或 Playwright 能渲染页面,但每个请求都启动浏览器实例,内存吃掉 2 GB,速度慢 10 倍。DrissionPage 正是为解决这个矛盾而生——它在一个框架内同时提供 HTTP 模式和浏览器模式,通过 WebPage 实现无缝切换并共享 cookies 和会话状态。本篇 DrissionPage 教程将深入讲解如何将住宅代理集成到这个双模式框架中,实现高效且不易被封的 DrissionPage web scraping 工作流。

DrissionPage 是什么:HTTP 与浏览器的统一框架

DrissionPage 是一个基于 Python 的自动化工具库,由国内开发者 g1879 创建并在 GitHub 开源。其核心设计理念是"一个工具,两种模式"。它通过 Chrome DevTools Protocol(CDP)直接与 Chromium 浏览器通信,无需 WebDriver 中间层,因此比 Selenium 更轻量、更快。

三种页面模型

DrissionPage 提供三种页面类型,各有适用场景:

  • SessionPage:基于 Python requests 库的 HTTP 客户端模式。内存占用约 50 MB,适合采集静态页面或直接调用 JSON API。不支持 JavaScript 渲染。
  • ChromiumPage:通过 CDP 协议控制 Chromium 浏览器。支持完整的 JS 渲染、截图、文件下载等操作。内存占用约 300-500 MB,适合处理动态渲染页面。DrissionPage Chromium 模式是处理现代 SPA 网站的关键能力。
  • WebPage:DrissionPage 的核心创新。它同时持有 SessionPage 和 ChromiumPage 的能力,可以在运行时切换模式,且两种模式共享 cookies、headers 和会话状态。先用 HTTP 模式快速获取列表页,再切换到浏览器模式渲染详情页——无需重新登录或传递 cookies。
特性SessionPageChromiumPageWebPage
底层引擎requests (HTTP)CDP → Chromium可切换
JS 渲染不支持支持按需启用
典型内存~50 MB~300-500 MB取决于当前模式
Cookie 共享自身会话浏览器上下文跨模式共享
代理配置方式set_proxies()ChromiumOptions.set_proxy()两种方式均支持

这种架构的经济学意义在于:大多数爬虫任务中,只有 10%-30% 的页面真正需要浏览器渲染。用 SessionPage 处理其余 70%-90% 的请求,可以将服务器成本降低 60% 以上。查看 ProxyHat 定价方案,结合你的并发需求估算代理成本。

DrissionPage 惯用 API:定位器、选项与监听器

ele() 与 eles() 元素定位

DrissionPage 提供了一套简洁的元素定位语法,比 Selenium 的 find_element 更直观:

# 按 ID
page.ele('#username')

# 按 class
page.ele('.search-box')

# 按属性
page.ele('@class=result-item')
page.ele('@type=submit')

# 按标签
page.ele('tag:input')
page.ele('tag:div@class=container')

# XPath
page.ele('xpath://div[@class="content"]/p[1]')

# 获取多个元素
items = page.eles('tag:article')
for item in items:
    print(item.text)

ChromiumOptions 配置

ChromiumOptions 是 ChromiumPage 的配置中心,用于设置浏览器路径、启动参数、代理等:

from DrissionPage import ChromiumOptions

co = ChromiumOptions()
co.set_argument('--no-sandbox')
co.set_argument('--disable-gpu')
co.set_argument('--window-size', '1920,1080')
co.headless()  # 无头模式

listen.start() 监听网络请求

这是 DrissionPage 最强大的功能之一——监听浏览器发出的后台 XHR/fetch 请求,直接捕获 JSON 数据,无需解析渲染后的 HTML:

from DrissionPage import WebPage

page = WebPage()
page.listen.start('api/products')  # 监听匹配 URL 的请求

page.get('https://example.com/shop')
# 等待并获取数据包
packet = page.listen.wait(timeout=10)
if packet:
    print(packet.url)            # 请求 URL
    print(packet.method)        # GET / POST
    print(packet.response.body) # 响应体(通常为 JSON)

page.listen.stop()

通过 listen 捕获后台 API 响应,你可以跳过 HTML 解析,直接获取结构化 JSON 数据。这在 DrissionPage web scraping 中是一个关键技巧——许多现代网站通过 XHR 加载数据,监听网络流量比解析 DOM 更可靠。

配置 DrissionPage 代理:SessionPage 与 ChromiumPage

在 DrissionPage 中配置代理需要区分两种模式。SessionPage 使用 set.proxies() 方法,而 ChromiumPage 通过 ChromiumOptions.set_proxy() 设置。DrissionPage proxy 配置的核心区别在于:HTTP 模式走 requests 的代理机制,浏览器模式走 Chromium 的代理机制。

SessionPage 代理配置

from DrissionPage import SessionPage

page = SessionPage()
page.set.proxies({
    'http': 'http://user-country-US:pass@gate.proxyhat.com:8080',
    'https': 'http://user-country-US:pass@gate.proxyhat.com:8080'
})

page.get('https://httpbin.org/ip')
print(page.json)

ChromiumPage 代理配置

from DrissionPage import ChromiumPage, ChromiumOptions

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

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

对于硬目标网站(如电商、社交媒体、票务平台),数据中心 IP 往往被直接封禁。住宅代理使用真实 ISP 分配的 IP 地址,请求看起来来自普通家庭用户,因此成功率显著更高。ProxyHat 提供覆盖全球的住宅代理网络,支持国家/城市级地理定位,查看 可用代理位置 了解覆盖范围。

完整示例:WebPage 双模式 + ProxyHat 住宅代理

下面是一个完整的可运行示例,展示 WebPage 如何在 HTTP 模式和浏览器模式之间切换,同时保持代理和会话状态。我们使用 ProxyHat 的住宅代理端点,通过用户名参数实现地理定位和会话固定。

首先,创建一个 ProxyHat 用户名构建器:

class ProxyHatConfig:
    GATEWAY = 'gate.proxyhat.com'
    HTTP_PORT = 8080
    SOCKS5_PORT = 1080

    @staticmethod
    def build_username(country=None, city=None, session=None):
        parts = ['user']
        if country:
            parts.append(f'country-{country}')
        if city:
            parts.append(f'city-{city}')
        if session:
            parts.append(f'session-{session}')
        return '-'.join(parts)

    @classmethod
    def http_url(cls, country=None, city=None, session=None):
        username = cls.build_username(country, city, session)
        return f'http://{username}:pass@{cls.GATEWAY}:{cls.HTTP_PORT}'

    @classmethod
    def socks5_url(cls, country=None, city=None, session=None):
        username = cls.build_username(country, city, session)
        return f'socks5://{username}:pass@{cls.GATEWAY}:{cls.SOCKS5_PORT}'

然后,使用 WebPage 实现双模式采集:

from DrissionPage import WebPage, ChromiumOptions
import uuid

# 构建 ProxyHat 住宅代理 URL
session_id = str(uuid.uuid4())[:8]
proxy_url = ProxyHatConfig.http_url(
    country='US',
    session=session_id
)

# 创建 WebPage,初始使用 HTTP 模式
page = WebPage()
page.set.proxies({
    'http': proxy_url,
    'https': proxy_url
})

# 第一步:HTTP 模式获取列表页(快速、低开销)
page.get('https://example.com/products?page=1')
links = page.eles('tag:a@class=product-link')
product_urls = [link.attr('href') for link in links[:5]]
print(f'HTTP 模式获取到 {len(product_urls)} 个产品链接')

# 第二步:切换到 Chromium 模式渲染 JS 详情页
co = ChromiumOptions()
co.set_proxy(proxy_url)
co.headless()

page.change_mode(co)  # 切换到浏览器模式,cookies 自动传递

# 监听后台 API
page.listen.start('api/product-detail')

for url in product_urls[:3]:
    page.get(url)
    packet = page.listen.wait(timeout=15)
    if packet:
        data = packet.response.body
        print(f'产品数据: {data[:200]}')
    else:
        # 降级为 DOM 解析
        title = page.ele('h1').text
        print(f'产品名称: {title}')

page.listen.stop()
page.quit()

这个示例展示了 DrissionPage 的核心优势:先用 SessionPage 快速抓取列表页(每个请求约 200ms),再切换到 ChromiumPage 渲染需要 JS 执行的详情页。代理在两种模式下保持一致,cookies 自动传递,无需手动管理会话。

生产级模式:会话固定、重试与并发

会话固定(Sticky Session)

许多网站要求同一会话使用同一 IP(登录后操作、多步表单等)。ProxyHat 支持通过用户名中的 session-xxx 参数固定 IP。在 DrissionPage 中,为每个 WebPage 实例分配独立的 session ID:

import uuid
from DrissionPage import WebPage

def create_pinned_session(country='US'):
    session_id = str(uuid.uuid4())[:8]
    proxy = ProxyHatConfig.http_url(
        country=country,
        session=session_id
    )
    page = WebPage()
    page.set.proxies({'http': proxy, 'https': proxy})
    return page, session_id

# 每个任务使用独立的 sticky session
page, sid = create_pinned_session('US')
# 同一 session_id 在有效期内保持同一出口 IP

重试与错误处理

import time
from DrissionPage.errors import ElementNotFoundError

def safe_get(page, url, max_retries=3):
    for attempt in range(max_retries):
        try:
            resp = page.get(url, timeout=15)
            if resp and page.status_code == 200:
                return page
            print(f'尝试 {attempt+1} 失败: HTTP {page.status_code}')
        except ElementNotFoundError:
            print(f'尝试 {attempt+1} 失败: 元素未找到')
        except Exception as e:
            print(f'尝试 {attempt+1} 失败: {e}')
        time.sleep(2 ** attempt)  # 指数退避
    return None

并发控制

DrissionPage 本身不提供并发管理,但可以与 concurrent.futuresasyncio 配合使用。关键原则:

  • SessionPage 模式下,每个线程使用独立的 WebPage 实例和独立代理 session ID。
  • ChromiumPage 模式下,每个浏览器实例约占用 300-500 MB 内存。一台 16 GB 内存的服务器建议最多运行 20-30 个并发浏览器实例。
  • 设置合理的请求间隔(1-3 秒),避免触发目标网站的频率限制。
  • 使用 ProxyHat 的旋转代理模式(不指定 session)实现每请求换 IP,适合大规模 SERP 采集。参考 SERP 跟踪用例 了解更多。
from concurrent.futures import ThreadPoolExecutor, as_completed
import uuid

def scrape_task(url):
    session_id = str(uuid.uuid4())[:8]
    proxy = ProxyHatConfig.http_url(country='US', session=session_id)
    page = WebPage()
    page.set.proxies({'http': proxy, 'https': proxy})
    try:
        page.get(url, timeout=15)
        result = page.ele('h1').text if page.ele('h1') else 'N/A'
        return url, result
    finally:
        page.close()

urls = ['https://example.com/page/1', 'https://example.com/page/2']
with ThreadPoolExecutor(max_workers=10) as executor:
    futures = [executor.submit(scrape_task, url) for url in urls]
    for f in as_completed(futures):
        url, result = f.result()
        print(f'{url}: {result}')

通过 listen 发现隐藏 API

许多现代网站将数据放在后台 XHR 请求中,前端只负责渲染。通过 listen.start() 监听网络流量,你可以发现这些隐藏的 API 端点,然后直接用 SessionPage 调用它们——无需浏览器渲染。这是从 ChromiumPage 降级到 SessionPage 的关键发现手段。

# 第一步:用浏览器模式监听,发现 API
page = ChromiumPage(co)
page.listen.start('api/')  # 监听所有 API 请求
page.get('https://target-site.com')
# 收集所有 API 端点
for _ in range(10):
    pkt = page.listen.wait(timeout=5)
    if pkt:
        print(f'发现 API: {pkt.url} -> {pkt.response.status}')
page.listen.stop()
page.quit()

# 第二步:切换到 SessionPage 直接调用 API
sp = SessionPage()
sp.set.proxies({'http': proxy_url, 'https': proxy_url})
sp.get('https://target-site.com/api/data?page=1')
data = sp.json  # 直接获取 JSON

什么时候不要升级到浏览器

DrissionPage 的双模式设计很强大,但并非所有场景都需要浏览器。以下情况应保持 SessionPage 模式:

  • 目标页面是静态 HTML:如果页面源码中已包含所需数据,用 SessionPage 即可,延迟约 200ms,而浏览器渲染需要 2-5 秒。
  • 已发现后台 API:通过 listen 发现 JSON API 后,直接用 SessionPage 调用,效率高 10 倍以上。
  • 大规模列表页采集:数千个列表页用 HTTP 模式可以在几分钟内完成,浏览器模式则需数小时。
  • 仅需 HTTP header 交互:设置 cookies、发送 POST 请求等,SessionPage 完全够用。

反之,以下情况需要升级到 ChromiumPage:

  • 页面数据由 JavaScript 动态生成,源码中不存在。
  • 需要与页面交互(点击、滚动、填表)。
  • 目标网站使用 Cloudflare Turnstile 或 reCAPTCHA 等 JS 验证。
  • 需要截图或下载文件。

更多爬虫场景的最佳实践,参考 Web Scraping 用例页面。ProxyHat 的 官方文档 提供了完整的代理配置参数说明。

关键要点

  • 双模式是核心价值:DrissionPage 的 WebPage 让你在 SessionPage(HTTP)和 ChromiumPage(浏览器)之间无缝切换,共享 cookies 和代理,按需付费——只在必要时才启动浏览器。
  • 代理配置分两路:SessionPage 用 set.proxies(),ChromiumPage 用 ChromiumOptions.set_proxy()。ProxyHat 住宅代理通过 gate.proxyhat.com:8080 接入。
  • listen 是杀手锏:用 listen.start() 监听浏览器网络流量,发现隐藏 API 后降级到 HTTP 模式,效率提升 10 倍以上。
  • 会话固定很重要:通过用户名中的 session-xxx 参数为每个任务分配独立 sticky session,避免 IP 频繁切换导致封号。
  • 合规先行:只采集公开数据,遵守 robots.txt 和服务条款,了解 CFAA 和 GDPR 的法律边界。

DrissionPage + ProxyHat 住宅代理的组合,为 Python 爬虫开发者提供了一个兼具效率和隐蔽性的解决方案。从 ProxyHat 定价方案 开始,选择适合你业务规模的代理套餐,然后按照本教程的示例快速集成到你的 DrissionPage 项目中。

常见问题

DrissionPage 是什么?

DrissionPage 是一个基于 Python 的自动化工具库,核心特色是同时提供 HTTP 客户端模式(SessionPage)和 Chromium 浏览器控制模式(ChromiumPage),并通过 WebPage 实现两种模式的无缝切换和状态共享。它使用 Chrome DevTools Protocol 直接与浏览器通信,无需 WebDriver 中间层,比 Selenium 更轻量高效,适合需要兼顾静态页面采集和动态页面渲染的爬虫场景。

为什么 DrissionPage 对代理用户很重要?

DrissionPage 的双模式设计意味着代理配置需要分两路处理:SessionPage 通过 set.proxies() 设置 HTTP 代理,ChromiumPage 通过 ChromiumOptions.set_proxy() 设置浏览器代理。WebPage 在模式切换时需要确保代理一致性。使用住宅代理可以显著提高对硬目标网站的访问成功率,因为住宅 IP 来自真实 ISP,不易被识别为爬虫流量。

DrissionPage 适合哪种代理类型?

DrissionPage 同时支持 HTTP/HTTPS 和 SOCKS5 代理。对于大多数场景,HTTP 代理(如 ProxyHat 的 gate.proxyhat.com:8080)即可满足需求。如果目标网站使用 HTTPS 且对代理协议有要求,可以选择 SOCKS5 代理(端口 1080)。住宅代理是最推荐的选择,因为其 IP 来自真实 ISP,成功率远高于数据中心代理,尤其适合电商、社交媒体等反爬措施严格的网站。

使用 DrissionPage 时如何避免被封?

避免被封的关键策略包括:使用住宅代理并为每个会话分配独立的 sticky session(通过用户名中的 session-xxx 参数固定 IP);设置合理的请求间隔(1-3 秒);优先使用 SessionPage HTTP 模式而非浏览器模式以降低资源占用;通过 listen.start() 发现后台 API 后直接调用以减少请求次数;遵守 robots.txt 和目标网站服务条款;设置合理的并发限制,避免短时间内大量请求同一域名。

准备好开始了吗?

覆盖 148+ 国家的住宅、ISP 和移动代理。创建免费账户。

创建免费账户
← 返回博客