ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

DrissionPage同源会话:让浏览器自动化与requests请求无缝协作

DrissionPage同源会话:让浏览器自动化与requests请求无缝协作 简介DrissionPage 是面向开发者、测试人员与运维工程师的 Web 自动化集成工具提供脚本录制、元素定位、数据处理、多线程执行及报告生成等核心能力可广泛应用于自动化测试、数据抓取与持续集成场景。这份 v4.0.2 资源包共含 79 个文件核心为 39 个 Python 源码与 31 个类型标注文件配合 README、LICENSE、配置说明及示例页面构成一套结构完整的工具项目方便直接阅读源码或集成到自己的流程中。压缩包整体仅 172KB轻量易部署适合前端、爬虫方向的学生借助源码开展毕业设计或论文研究理解浏览器自动化底层实现。目前已有 572 人学习下载对于希望快速掌握 DrissionPage 用法或二次开发个性化自动化脚本的读者来说是一份值得收藏的参考资料。1. 拿到 DrissionPage v4.0.2 这个压缩包先理解它到底在解决什么问题做 Web 自动化的人第一次见到 DrissionPage 这个集成工具最容易犯的错是拿它跟 Selenium 做简单对比然后问“又是换了个壳吧”。真跑起来才发现它把 Chromium 内核和 requests 会话合并到了同一个上下文里页面里登录过的 cookie、localStorage、UA 全都能被后续请求直接复用不用再手动搬运登录态。这一下就让页面自动化巡检、后台批量操作这类脚本的写法彻底变了——你不需要在浏览器和 requests 之间来回导数据这也是标题里“集成”两个字真正的分量。这个压缩包适合四类人写周期性巡检页面健康度的、处理多账号后台操作与表单提交的、想把旧脚本改成浏览器控件的、以及刚接触 Web 自动化想少踩环境坑的新手。2. 先搞清楚“同源会话”这个设计再谈怎么安装和跑通最小示例2.1 它和 Selenium 的本质区别浏览器与 requests 共用一套状态用 Selenium 写页面自动化你面对的是两层数据浏览器层面有一套 cookie、localStorage、sessionStoragerequests 层面又有另一套。页面里登录完切到 requests 去拿接口数据你得手动把 cookie 拼进请求头登录态还会因为浏览器上下文关闭就失效。这已经是行业里最常见的自动化翻车点也是很多开发回头去骂“这是玄学”的原因——本质只是两层会话没有被统一。DrissionPage 把这两件事合并到一个会话里。你用浏览器模式打开页面页面里通过 JS 写入的 cookie、发起请求时生成的身份标识都会被同一个上下文记录切到数据模式去请求接口自动带上当前页面持有的状态。这个设计带来的直接收益是巡检脚本里“打开页面看状态”和“请求接口拿数据”不再是两次独立动作而是一次会话里的连续行为。理解了这一点后面所有参数和代码就比较容易对号入座。2.2 从 zip 到能跑的最小命令v4.0.2 是压缩包形式解压后你通常能看到源码目录、依赖清单和使用说明。我的习惯是先看一遍说明文件确认依赖版本要求再决定用离线安装还是直接拉取已发布的主库。这个版本建议在 Python 3.8 以上的环境里跑低于这个版本容易出现类型语法不兼容。# 先装主库压缩包里的源码一般对应同一个发布版本 python -m pip install drissionpage # 验证安装是否真的可用 python -c from DrissionPage import ChromiumPage; print(ok)第一行命令把主库装进当前 Python 环境第二行看起来简单但值得执行。很多解压后闪退、报 ModuleNotFoundError 的场景其实都是这步没踩实环境里残留了旧版本或者装到了别的解释器。如果你手头是离线内网环境就把压缩包里的依赖目录指给 pip 用常见做法是python -m pip install --no-index --find-links./libs drissionpage这样不会去外网拉包。跑通这步后再谈浏览器控制。2.3 第一个能跑通的最小示例启动浏览器并读取标题from DrissionPage import ChromiumPage # 启动本机已安装的 Chrome 内核 page ChromiumPage() page.get(https://example.com) print(page.title) page.quit()这段代码做的事就三件启动浏览器、打开指定页面、打印页面标题。逻辑上ChromiumPage()负责拉起一个受控的 Chrome 实例get()等于在地址栏输入 URL 回车page.title拿当前标签页的标题quit()关闭浏览器这个释放动作在长跑脚本里尤其重要否则进程会越积越多。第一行如果报错说找不到浏览器最常见原因是本机 Chrome 版本过旧或安装路径不在默认位置后面避坑章节细说。跑通这个最小示例说明压缩包的环境依赖和内核驱动是匹配的你才刚跨过门槛。3. 四个控制器怎么选ChromiumPage、SessionPage、WebPage、ChromiumOptions3.1 控制器不是越多越好是按任务形态分情况选接触 DrissionPage 时最容易晕的是控制器太多ChromiumPage、SessionPage、WebPage、ChromiumOptions名字长得也像。组合起来无非是一张表的事。我一般把问题反过来问自己这轮任务需不需要看一眼真实渲染后的页面控制器模式典型场景ChromiumPage浏览器渲染模式页面点击、表单填写、等待 JS 渲染后取数据SessionPagerequests 会话模式纯接口调用、JSON 拉取、文件下载WebPage双模式切换同一会话里先页面操作再请求接口ChromiumOptions启动参数配置设置无头模式、下载路径、UA、用户目录如果你只是巡检一个接口是否返回 200SessionPage 足够别的控制器反而多余。如果你想处理一个要点击按钮后经过 JS 渲染的后台表格则必须用 ChromiumPage 或 WebPage。这里有一个容易忽略的代价浏览器渲染模式比纯 requests 会话慢一到两个数量级因为它要启动完整的内核、加载页面资源、执行脚本。巡检大批量 URL 时能走 SessionPage 的不要强行开浏览器。3.2 SessionPage 的极简请求与返回对象from DrissionPage import SessionPage # 纯会话模式不需要浏览器进程 s SessionPage() resp s.get(https://httpbin.org/json) print(resp.status_code) print(resp.json)这段代码里SessionPage()创建了一个类似 requests.Session 的会话对象但底层会和浏览器模式共享状态配置s.get()返回响应对象.status_code是状态码.json是解析后的 JSON 数据。参数层面get()支持timeout、headers、params接口巡检脚本里我会习惯写明 timeout比如s.get(url, timeout15)不写的话可能用默认值挂很久。SessionPage 的价值不在于它比 requests 快而在于它能复用你给浏览器模式配置的同一套身份状态又不额外消耗渲染资源。3.3 WebPage一个容器里先看页面再拿接口数据from DrissionPage import WebPage # 默认以 d_mode浏览器渲染模式启动 page WebPage() page.get(https://example.com) print(page.title) # 切换到 s_mode沿用当前页面的请求上下文 page.change_mode() resp page.get(https://httpbin.org/get) print(resp.status_code)WebPage()同时持有渲染模式和数据模式初始在 d_modechange_mode()负责切换切换后get()的语义跟着变——在 d_mode 里打开的是可视化页面在 s_mode 里发出的是纯请求。参数上没有额外花哨的东西关键是记住一个边界s_mode 没法执行页面里的 JS也拿不到动态渲染后的 DOM需要这两样就得先切回 d_mode。同一个容器里先页面登录、再切数据模式调接口适合做多账号后台操作你不需要再把 cookie 导进导出这是它对比 Selenium 加 requests 组合最省事的地方。4. 配置 ChromiumOptions 时先抓住三个直接影响成败的参数4.1 下载目录与失败重试是两个必调参数默认情况下浏览器会把下载文件丢进系统下载目录脚本跑久了文件散落得到处都是。常见的做法是用 ChromiumOptions 指定下载路径同时调大失败重试阈值。下面的代码演示典型配置from DrissionPage import ChromiumOptions, ChromiumPage co ChromiumOptions() co.set_download_path(D:/audit_downloads) # 所有下载落盘到这个目录 co.retry_times(3) # 连接失败时重试 3 次 co.retry_interval(1.5) # 每次重试间隔 1.5 秒 page ChromiumPage(co) page.get(https://example.com/file.zip) page.wait_download_begin() page.wait_download_ok()set_download_path接收一个绝对路径路径不存在时工具会尝试创建retry_times和retry_interval控制网络异常时的重试策略。参数不宜调得过大重试 3 次、间隔 1.5 秒对大多数巡检场景已经够用。设置过大的重试次数会让脚本在一个坏目标上卡很久反而影响整体巡检周期。wait_download_begin和wait_download_ok是等待下载开始的典型调用实际下载完成后你可以继续用文件系统相关逻辑去校验文件大小。4.2 多账号与请求头配置不让每次启动都暴露同一张脸import random ua_list [ Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/120.0.0.0, Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) Chrome/121.0.0.0, ] co ChromiumOptions() co.set_user_agent(random.choice(ua_list)) co.set_headless(True) co.set_user_data_dir(fC:/profile/user_{random.randint(1, 99)})set_user_agent设置请求头里的 UA每次换一个能减少被识别成固定脚本特征的概率set_headless(True)开启无头模式后台运行不弹窗适合服务器上长跑set_user_data_dir指定用户数据目录每个账号独立目录可避免登录态互相覆盖。参数上有几个细节值得注意多账号场景不要几个账号共享同一个 user_data_dir否则后登录的账号会把前面顶掉无头模式在部分需要物理显卡渲染的页面上会出现白屏这类页面反而要切回有头模式排查这个在后面排查章节会再提。4.3 接管本机浏览器要懂 user_data_dir 的冲突边界很多人以为 DrissionPage 接管 Chrome 就是直接连接当前已打开的浏览器这是个常见误解。默认情况下它启动的是一个全新的受控实例和你在桌面手动打开的浏览器是隔离的。想让脚本用上你日常登录过的会话可以用operating_path()指向本机 Chrome 的用户目录或者手动启动 Chrome 时带上调试端口再让 DrissionPage 接管。但这里有坑如果你已经开着一个 Chrome 窗口占用了默认用户目录再次用同一个 user_data_dir 启动受控实例会直接启动失败或者打开到相同进程里。我处理多账号时会为每个账号复制一份独立目录脚本启动前先确认没有残留的 chrome 进程占用端口这是最省心的姿势。5. 避坑排查DrissionPage 集成工具最常见的五个现场事故5.1 解压 zip 后运行入口程序闪退现象从压缩包解压后运行 demo 脚本或入口程序窗口一闪就消失控制台看不到任何报错。原因通常是 Python 环境版本不对或者依赖包没有完整安装到当前解释器路径下。v4.0.2 要求 Python 3.8 以上低于这个版本在语法解析阶段就会异常退出而有些 windows 环境里系统自带的是 Python 2 或 3.6命令python指向的却不是你先装的版本。解决在命令行用python --version先确认解释器版本再执行python -m pip list查看 DrissionPage 相关包是否出现在列表。若依赖没装全走python -m pip install -r requirements.txt补装。注意如果压缩包里有多个 demo 脚本先用最小版跑通不要直接跑带图形界面的大脚本这样能把环境问题和业务逻辑问题隔离开。5.2 页面元素定位到了但始终点不动现象元素用page.ele()找得到打印出来有文本有属性但执行click()没反应甚至报not clickable。原因有两种高频场景一是元素被 iframe 包着DOM 在子框架里当前作用域并不在目标文档上二是元素本身被遮挡比如悬浮层或弹窗压在上面。解决先page.into_iframe()切进对应 iframe操作完再page.exit_iframes()退出来如果是遮挡用ele.wait_clickable()先等它可点击再不行用page.scroll_to_see(ele)把它滚动进可视区再点。我的经验是出现“找得到但点不动”优先检查 iframe再检查遮挡最后才怀疑元素坐标。把这三步做成一个固定排查顺序能省下很多瞎试的时间。5.3 请求 403 或验证码频繁弹出现象同一套脚本在开发机上跑正常部署到服务器跑就频繁 403或者弹出验证码。原因大概率是目标站点识别到了无头浏览器的特征。无头模式里 WebDriver 相关标记、屏幕尺寸、UA 这几个维度和真实浏览器有差异服务端风控很容易识别这不属于脚本语法问题。解决关闭无头模式改用有头模式跑一轮看是否恢复同时通过 ChromiumOptions 显式设置 UA、窗口大小、--disable-blink-featuresAutomationControlled之类参数降低自动化特征。另一个有效的做法是降低请求频率重试间隔调到 2 秒以上。验证码弹窗一旦出现先停脚本手工处理一次别立刻堆参数否则容易越调越乱。5.4 浏览器登录了但 requests 会话拿不到相同登录态现象用页面模式成功登录切到 SessionPage 或 requests 侧发请求却提示未认证。原因十有八九是控制器选错了。SessionPage 是独立会话它并不会自动附加你 ChromiumPage 页面里产生的 cookie只有 WebPage 这种双模式容器才保证状态在一个上下文里。这个误用几乎人人都会踩一次。解决如果你的任务需要“页面登录 接口验证”直接用WebPage替代两处控制器在 d_mode 登录后change_mode()再请求接口。如果你坚持用 SessionPage那就手动把 cookie 从页面会话里取出通过set_headers或SessionPage对应的 cookie 设置方法塞进去但这会回归到老式的搬运逻辑显然更麻烦。首选还是换 WebPage。5.5 脚本打包后到别的机器运行报 DLL 错误现象本地跑得好好的用 PyInstaller 打成 exe 后搬到另一台机器启动时报找不到 DLL 或者浏览器内核路径无效。原因有两个叠在一起一是打包时没有把 DrissionPage 依赖的本地动态库一起收录二是目标机器没有安装 Chrome或者 Chrome 版本过旧受控内核启动不了。解决打包命令里显式 include 相关依赖例如用--hidden-import把浏览器控制相关的模块带进去同时启动脚本里加一段浏览器路径检查逻辑发现默认路径不存在就提示安装 Chrome 或让用户通过driver_path指定内核路径。我一般会给目标机器准备一份可用的浏览器安装包部署文档里写明版本要求这能把环境冲突拦在运行之前。6. 把工具落成一个周期性巡检脚本完整模板与验证土办法6.1 巡检脚本的骨架循环、超时、日志与异常兜底很多团队做“web页面自动化巡检”时会把代码写重又是数据库又是可视化面板反而忽略了最基本的循环保障。先看一段可以直接改着用的模板import time from DrissionPage import ChromiumPage urls [ https://example.com/login, https://example.com/dashboard, ] base_timeout 15 # 单页超时秒数 wait_interval 300 # 两轮巡检间隔秒数 page ChromiumPage() for round_no in range(10): # 先跑 10 轮观察稳定性 for url in urls: try: page.get(url, timeoutbase_timeout) title page.title if title : raise ValueError(页面标题为空疑似拦截页) print(f[ok] {url} title{title}) except Exception as e: # 异常不进黑匣子直接落日志 with open(audit.log, a, encodingutf-8) as f: f.write(f{time.strftime(%Y-%m-%d %H:%M:%S)} {url} {e}\n) time.sleep(wait_interval) page.quit()几个参数值得按现场情况改base_timeout建议 10 到 20 秒太短会误报太长会让一轮巡检卡死wait_interval是两轮之间的间隔巡检内网页面 60 秒足够巡检公网页面建议 300 秒以上避免被目标服务端判定为高频访问。page实例只创建一次而不是在循环里反复创建这是巡检脚本最容易忽略的性能点。异常信息统一走文件日志不加告警的话至少要能看到历史失败记录。6.2 验证链路成立的两个土办法脚本写完先别急着挂后台用两个土办法验证。第一招故意把其中一个 URL 改成一个不存在的路径比如在目标后加/__test__跑完一轮确认日志落了记录说明异常捕获和日志链路是真的生效而不是表面跑得好看。第二招选一个已知稳定的页面先手动访问五次记录平均加载耗时再让脚本跑五轮如果脚本页面加载耗时比手动高出一倍以上优先怀疑代理或网络层而不是怀疑工具本身。这两个办法能在五分钟内定位八成“脚本看着在跑但实际没意义”的问题。6.3 收尾习惯一个跑过几百次周期的经验我最后留一个自己的习惯每次升级 DrissionPage 版本不要直接线上替换先拿一条固定 URL 做回放测试。这个工具更新后个别参数名和默认行为会变尤其是重试策略和超时处理升级后脚本可能不报错但行为已经不同。回放测试就是拿上一版本跑正常的用例再执行一遍对比标题、耗时、日志记录三项有没有变化。有了这个习惯你可以在不读 changelog 的情况下也及时发现回归减少生产期翻车。另一个习惯是不要开无头模式追查页面渲染问题无头模式节省的不过是资源但页面卡在白屏、元素不可见这类问题换有头模式一看就明省下的排查时间远超多开的窗口成本。这套工具用顺之后你会发现自己对“页面自动化”的看法变了它不是用来替代手工点击的玩具而是能把巡检、监控、批量后台操作统统收进一条时间线里的正经方案。希望帮到你。本文还有配套的精品资源点击获取
返回列表