DrissionPage 代理实战教程:用住宅 IP 统一 HTTP 与 Chromium 爬虫

DrissionPage 将 requests 风格 HTTP 与 Chromium CDP 浏览器控制合为一体。本文详解 SessionPage、ChromiumPage、WebPage 三种模式,演示如何集成 ProxyHat 住宅代理、捕获 XHR 数据包、构建高并发生产级爬虫。

DrissionPage Proxy Guide: One Python Tool for HTTP and Chromium Scraping
本文目录

DrissionPage 是什么:一个工具同时搞定 HTTP 与浏览器爬虫

如果你曾在 Python 爬虫项目里同时维护 requests 脚本和 Selenium/Playwright 浏览器脚本,就知道切换两套代码有多痛苦——Cookie 要手动同步、选择器语法不一致、代理配置各写一遍。DrissionPage 正是为解决这个问题而生的 Python 框架:它把 requests 风格的 HTTP 模式和 Chromium CDP 驱动的浏览器模式统一到同一套 API 下,并且能在两种模式之间无缝切换而共享 Cookie、Session 和状态。

对于需要 drissionpage web scraping 的开发者来说,这意味着你可以在简单页面用轻量 HTTP 请求(速度快、成本低),遇到 JS 渲染页面时一键升级到 drissionpage chromium 浏览器模式,无需重新登录或重建会话。结合 ProxyHat 住宅代理,你还能在每个请求或会话级别轮换 IP,绕过地理封锁和反爬机制。

法律与合规提示:本文仅讨论对公开数据的采集。在美国,计算机欺诈和滥用法(CFAA)对未经授权的访问有严格规定;在欧盟,GDPR对个人数据处理有严格要求。请始终遵守目标网站的 robots.txt 和服务条款,优先使用官方 API,控制请求频率,不要采集受版权保护或需登录才能访问的非公开数据。

为什么需要 DrissionPage:传统双工具方案的痛点

典型的爬虫项目会经历这样的演进:先用 requests 快速抓取静态页面,发现目标网站用了 React/Vue 动态渲染后,又引入 Selenium 或 Playwright 处理 JS。于是项目里出现了两套独立的代码:

  • HTTP 訡式:速度快(单请求约 200ms),内存占用低(约 30MB),但无法执行 JavaScript。
  • 浏览器模式:能渲染完整 DOM、执行 JS、处理复杂交互,但每个浏览器实例占用 200-500MB 内存,启动耗时 1-3 秒。

两套代码之间的 Cookie 同步、代理配置重复、选择器语法差异(CSS vs XPath vs Playwright 定位器),让维护成本翻倍。DrissionPage 的 WebPage 类通过 CDP(Chrome DevTools Protocol)直接控制 Chromium,在同一对象上切换模式,从根本上消除了这些问题。

DrissionPage 的三种页面模型

DrissionPage 提供三个核心页面类,理解它们的区别是掌握 drissionpage tutorial 的基础:

SessionPage — 纯 HTTP 模式

SessionPage 基于 Python requests 库封装,行为类似 requests.Session()。它发送 HTTP 请求、解析 HTML,不启动浏览器。适合抓取静态页面或 API 端点。优势是速度快、资源消耗极低,适合高并发批量采集。

ChromiumPage — 浏览器模式

ChromiumPage 通过 CDP 协议直接控制 Chromium 浏览器(无需 WebDriver),能执行 JavaScript、渲染动态内容、模拟用户交互。相比 Selenium,CDP 方式减少了中间层,通信延迟更低。适合处理 SPA 应用、需要点击/滚动等交互的场景。

WebPage — 混合模式(核心亮点)

WebPage 是 DrissionPage 最强大的类,它同时包含 SessionPageChromiumPage 的能力,可以在运行时通过 page.change_mode() 在 HTTP 和浏览器模式之间切换。关键点:切换时 Cookie 和 Session 状态自动保留——你在 HTTP 模式下登录获取的 Cookie,切到浏览器模式后依然有效,反之亦然。

这种设计让你能以最低成本完成任务:先用 HTTP 模式快速获取大部分数据,只在必要时升级到浏览器模式,节省 80% 以上的计算资源。

DrissionPage 惯用 API 速览

无论哪种页面模式,DrissionPage 的元素定位 API 是统一的。掌握以下核心方法即可覆盖大部分场景:

ele() 和 eles() — 元素定位

ele() 返回单个元素,eles() 返回元素列表。定位语法支持多种格式:

from DrissionPage import WebPage

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

# 通过标签定位
input_box = page.ele('tag:input')

# 通过属性定位(@语法)
submit_btn = page.ele('@class=submit-button')

# XPath 语法
article = page.ele('xpath://div[@id="content"]/article')

# 组合定位
links = page.eles('tag:a@href:contains=product')

# 链式定位
title = page.ele('tag:div@class=card').ele('tag:h2')

这种统一的定位语法意味着你不需要在 HTTP 模式和浏览器模式之间切换选择器写法——同一套 ele() 调用在两种模式下都能工作。

ChromiumOptions — 浏览器配置

ChromiumOptions 用于配置浏览器行为,包括无头模式、代理设置、用户代理、窗口大小等:

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 的杀手级功能之一。listen 模块可以监听浏览器发出的 XHR/Fetch 请求,直接捕获后台 API 返回的 JSON 数据,无需逆向分析接口:

page = ChromiumPage()
page.listen.start('api/products')  # 监听包含此关键词的请求

page.get('https://example.com/shop')
# 等待数据包被捕获
packet = page.listen.wait(timeout=10)

if packet:
    json_data = packet.response.body  # 直接获取 JSON
    print(f'捕获到 {len(json_data.get("items", []))} 条商品数据')

这种方法比手动分析 Network 面板高效得多——你只需指定 URL 关键词,DrissionPage 会自动拦截匹配的响应并返回解析后的数据。

配置代理:SessionPage 与 ChromiumPage 的方式

drissionpage proxy 配置中,HTTP 模式和浏览器模式的设置方式不同,但都很直接。

SessionPage 设置代理

SessionPage 使用 set.proxies() 方法,与 requests 的 proxies 参数一致:

from DrissionPage import SessionPage

page = SessionPage()
page.set.proxies({
    'http': 'http://user-country-US-session-abc123:pass@gate.proxyhat.com:8080',
    'https': 'http://user-country-US-session-abc123:pass@gate.proxyhat.com:8080'
})
page.get('https://httpbin.org/ip')
print(page.html)

ChromiumPage 设置代理

浏览器模式通过 ChromiumOptions.set_proxy() 在启动时配置代理。注意:Chromium 的代理在启动时生效,运行时不能直接更改,需要重启浏览器实例:

from DrissionPage import ChromiumPage, ChromiumOptions

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

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

为什么需要住宅代理

对于硬目标网站(如 SERP 搜索引擎、电商价格监控、社交媒体),数据中心 IP 通常会被直接封锁。根据 Google robots.txt 规范,搜索引擎允许公开抓取,但实际访问时数据中心 IP 段容易被识别和限速。住宅代理使用真实 ISP 分配的 IP 地址,请求看起来来自普通家庭用户,成功率可达 95% 以上,而数据中心代理在严格反爬的网站上成功率可能低于 30%。

ProxyHat 提供住宅、移动和数据中心三种代理类型。对于 DrissionPage 爬虫,推荐使用住宅代理处理高难度目标,数据中心代理用于低防护站点以降低成本。详见 ProxyHat 定价方案

实战示例:WebPage 从 HTTP 升级到浏览器模式

下面是一个完整的可运行示例,展示 WebPage 如何先以 HTTP 模式通过美国住宅代理请求静态页面,然后无缝升级到 Chromium 模式处理 JS 渲染页面——全程保持同一代理会话和 Cookie。

from DrissionPage import WebPage
import time

def build_proxy_url(country='US', session_id='abc123'):
    """构建 ProxyHat 住宅代理 URL"""
    username = f'user-country-{country}-session-{session_id}'
    password = 'your_password'
    return f'http://{username}:{password}@gate.proxyhat.com:8080'

def scrape_with_escalation():
    proxy_url = build_proxy_url(country='US', session_id='sess001')
    
    # 创建 WebPage,初始为 HTTP 模式
    page = WebPage(mode='session')
    
    # 配置 HTTP 模式代理
    page.set.proxies({
        'http': proxy_url,
        'https': proxy_url
    })
    
    # 第一步:HTTP 模式抓取静态列表页
    print('--- HTTP 模式 ---')
    page.get('https://books.toscrape.com/')
    titles = page.eles('tag:h3')
    print(f'HTTP 模式获取到 {len(titles)} 个书名')
    for t in titles[:3]:
        print(f'  - {t.ele("tag:a").text}')
    
    # 第二步:升级到浏览器模式处理 JS 渲染页面
    print('--- 切换到 Chromium 模式 ---')
    # 通过 ChromiumOptions 配置浏览器代理
    from DrissionPage import ChromiumOptions
    co = ChromiumOptions()
    co.set_proxy(proxy_url)
    co.headless(True)
    co.set_argument('--no-sandbox')
    
    # 切换模式,Cookie 自动保留
    page.change_mode(co)
    
    # 监听后台 API 请求
    page.listen.start('api')
    
    # 访问需要 JS 渲染的页面
    page.get('https://quotes.toscrape.com/js/')
    
    # 等待页面加载和元素出现
    quotes = page.eles('tag:div@class=quote', timeout=10)
    print(f'浏览器模式获取到 {len(quotes)} 条引言')
    for q in quotes[:3]:
        text = q.ele('tag:span@class=text').text
        author = q.ele('tag:small@class=author').text
        print(f'  - {author}: {text[:50]}...')
    
    # 检查是否捕获到 XHR 数据包
    packets = page.listen.steps(count=3, timeout=10)
    if packets:
        print(f'捕获到 {len(packets)} 个网络数据包')
    
    page.close()

scrape_with_escalation()

这个示例的关键在于:change_mode() 调用时,DrissionPage 会自动将 HTTP 模式下获取的 Cookie 传递给新启动的 Chromium 实例,你不需要手动管理会话状态。代理也通过 ChromiumOptions 传递给浏览器进程。

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

会话固定(Sticky Session)

对于需要登录或多步骤流程的爬取,IP 频繁切换会导致会话失效。ProxyHat 支持 session 参数固定 IP:

import random
import string

def generate_session_id():
    return ''.join(random.choices(string.ascii_lowercase + string.digits, k=8))

# 同一会话 ID 在有效期内保持同一出口 IP
session_id = generate_session_id()
proxy_url = f'http://user-country-US-session-{session_id}:pass@gate.proxyhat.com:8080'

不同的 session_id 会被分配不同的 IP,相同 ID 在一段时间内复用同一 IP。这让你可以精确控制 IP 轮换粒度。

重试与错误处理

from DrissionPage import WebPage
import time

def fetch_with_retry(url, max_retries=3, backoff=2):
    """带指数退避的重试逻辑"""
    page = WebPage(mode='session')
    
    for attempt in range(max_retries):
        try:
            session_id = f'retry-{attempt}'
            proxy = f'http://user-country-US-session-{session_id}:pass@gate.proxyhat.com:8080'
            page.set.proxies({'http': proxy, 'https': proxy})
            
            resp = page.get(url, timeout=15)
            if resp.status_code == 200:
                return resp
            elif resp.status_code == 429:
                wait = backoff ** attempt
                print(f'触发限流,等待 {wait}s 后重试')
                time.sleep(wait)
            else:
                print(f'状态码 {resp.status_code},第 {attempt+1} 次重试')
                time.sleep(backoff)
        except Exception as e:
            print(f'异常: {e},第 {attempt+1} 次重试')
            time.sleep(backoff ** attempt)
    
    return None

并发控制

DrissionPage 的 HTTP 模式可以轻松实现 50-100 并发请求,但浏览器模式每个实例占用大量内存,建议将并发控制在 5-10 个浏览器实例。使用线程池或 asyncio 管理并发:

from concurrent.futures import ThreadPoolExecutor, as_completed
from DrissionPage import SessionPage

def scrape_single(url, session_id):
    proxy = f'http://user-country-US-session-{session_id}:pass@gate.proxyhat.com:8080'
    page = SessionPage()
    page.set.proxies({'http': proxy, 'https': proxy})
    resp = page.get(url, timeout=15)
    result = resp.status_code, len(page.html)
    page.close()
    return result

urls = ['https://httpbin.org/delay/1'] * 20
session_ids = [f'pool-{i:03d}' for i in range(20)]

with ThreadPoolExecutor(max_workers=10) as executor:
    futures = {
        executor.submit(scrape_single, url, sid): (url, sid)
        for url, sid in zip(urls, session_ids)
    }
    for future in as_completed(futures):
        url, sid = futures[future]
        try:
            status, length = future.result()
            print(f'{sid}: status={status}, length={length}')
        except Exception as e:
            print(f'{sid}: error={e}')

对于更大规模的需求,可以将浏览器实例容器化(Docker),每个容器运行独立 Chromium 实例并分配不同代理会话。ProxyHat 支持高并发,详见 全球代理节点位置

用 listen 发现隐藏 API

许多现代网站的数据实际通过后台 XHR 请求加载,页面上看到的数据来自 JSON API。listen 功能让你无需逆向就能发现这些接口:

page = ChromiumPage()
page.listen.start('api/search')  # 监听包含 api/search 的请求

page.get('https://example.com/search?q=laptop')

# 获取捕获的请求包
packet = page.listen.wait(timeout=15)
if packet:
    print(f'API URL: {packet.url}')
    print(f'方法: {packet.method}')
    print(f'请求头: {packet.request.headers}')
    print(f'响应体: {packet.response.body}')
    
    # 找到 API 后,可以切换到 HTTP 模式直接调用
    api_url = packet.url
    api_headers = packet.request.headers

发现 API 后,你可以用 SessionPage 直接请求该接口,速度提升 10 倍以上,无需启动浏览器。这就是 WebPage 混合模式的核心价值——用浏览器发现接口,用 HTTP 高效采集。更多爬虫场景参考 ProxyHat 爬虫用例SERP 追踪用例

何时不应升级到浏览器模式

虽然 DrissionPage 让模式切换变得简单,但并非所有场景都需要浏览器。以下情况应保持 HTTP 模式:

  • 目标页面是静态 HTML:如果数据直接在 HTML 源码中,用 HTTP 模式即可,浏览器模式是浪费资源。
  • 已知 API 端点:如果已经通过 listen 或浏览器开发者工具发现了 API,直接用 HTTP 请求 API 更高效。
  • 大批量数据采集:需要处理数万 URL 时,HTTP 模式的并发能力和资源效率远超浏览器。
  • 简单的表单提交:不涉及 JS 验证的 POST 请求,用 SessionPage 即可完成。

反过来说,以下情况必须使用 ChromiumPage:

  • 页面内容由 JavaScript 动态渲染(React、Vue、Angular SPA)。
  • 需要执行 JS 计算的加密参数(如签名、token 生成)。
  • 需要模拟复杂用户交互(拖拽、滚动加载、Canvas 操作)。
  • 目标网站有 JS Challenge / Cloudflare 等浏览器指纹检测。

关键要点总结

DrissionPage 的核心价值:

  • SessionPage + ChromiumPage + WebPage 三模式统一 API,Cookie/Session 跨模式共享。
  • 先用 HTTP 模式低成本采集,遇到 JS 渲染再升级浏览器,节省 80%+ 资源。
  • ele() / eles() 统一定位语法支持 @属性、tag:标签、xpath 三种格式。
  • listen.start() 直接捕获 XHR/JSON 响应,无需逆向接口。
  • ProxyHat 住宅代理通过 set.proxies()(HTTP)和 ChromiumOptions.set_proxy()(浏览器)集成。
  • 会话固定用 user-country-US-session-xxx 用户名格式,重试时更换 session ID 自动换 IP。
  • HTTP 模式可跑 50-100 并发,浏览器模式建议 5-10 实例并发。
  • 始终遵守 robots.txt、服务条款和相关法律法规,只采集公开数据。

更多 ProxyHat 代理配置细节和高级参数,请参阅 ProxyHat 官方文档。如果你需要评估不同代理类型和定价方案,可以查看 ProxyHat 定价页面

常见问题

DrissionPage 是什么?

DrissionPage 是一个 Python 爬虫框架,它将 requests 风格的 HTTP 请求和 Chromium CDP 浏览器控制统一到同一套 API 下。它提供三种页面类:SessionPage(纯 HTTP)、ChromiumPage(浏览器控制)和 WebPage(混合模式,可在两种模式间切换并共享 Cookie 和 Session 状态)。这种设计让开发者用一个工具就能同时处理静态页面和 JS 渲染页面,避免同时维护 requests 和 Selenium 两套代码。

DrissionPage 对代理用户有什么重要意义?

DrissionPage 的 WebPage 模式让代理用户可以在 HTTP 模式和浏览器模式之间无缝切换,同时保持同一代理会话和 Cookie 状态。这意味着你可以在 HTTP 模式下用住宅代理快速采集静态页面,遇到 JS 渲染页面时升级到浏览器模式,无需重新配置代理或同步 Cookie。此外,listen 功能可以捕获浏览器发出的 XHR 请求,发现隐藏 API 后切回 HTTP 模式直接调用,大幅提升采集效率并降低代理流量消耗。

DrissionPage 适合用哪种代理类型?

对于反爬严格的网站(如搜索引擎、电商平台、社交媒体),推荐使用住宅代理,因为住宅 IP 来自真实 ISP,请求看起来像普通用户访问,成功率可达 95% 以上。对于防护较低的公开数据网站,数据中心代理即可满足需求且成本更低。ProxyHat 同时提供住宅、移动和数据中心三种代理类型,可在用户名中通过 country 和 session 参数控制地理位置和 IP 固定策略,适配 DrissionPage 的 SessionPage 和 ChromiumPage 两种模式。

使用 DrissionPage 采集时如何避免被封锁?

避免封锁的关键策略包括:使用住宅代理轮换 IP(通过 ProxyHat 的 session 参数控制轮换粒度);设置合理的请求间隔(建议 1-3 秒);实现指数退避重试机制(遇到 429 状态码时自动等待并重试);使用 listen 功能发现并直接调用后台 API 以减少浏览器请求量;限制并发数(HTTP 模式 50-100 并发,浏览器模式 5-10 实例);始终遵守 robots.txt 和目标网站服务条款,优先使用官方 API。

DrissionPage 的 listen 功能怎么用?

listen 是 DrissionPage 的网络数据包监听功能,用于捕获浏览器发出的 XHR/Fetch 请求及其响应。使用方法:先调用 page.listen.start('url关键词') 开始监听,然后执行 page.get() 触发页面加载,再用 page.listen.wait(timeout=10) 等待匹配的数据包。捕获到的 packet 对象包含 url、method、request.headers 和 response.body 等属性,可以直接获取 API 返回的 JSON 数据,无需逆向分析接口。

准备好开始了吗?

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

创建免费账户
← 返回博客