写这篇文章之前,我翻了翻旧项目仓库,看到那些“能跑就行”的代码片段,突然有点怀旧。
它们简单粗暴、没啥技巧,但却是我们整个执行环境管理体系的起点。
只是直到后来我们反复被风控拉扯、被代理封禁、被 JS 阻断,我们才逐渐意识到:
**浏览器不是工具,它是一只会反击的野兽。
**要想驯服它,必须清楚地知道它的每一块骨骼、每一根神经都在干什么。
于是,我们从一个土炮脚本,走到了自动化环境构建体系。
这一段演化,几乎浓缩了我过去几年对“浏览器执行环境工程化”的全部理解。
1. 史前时代:只要跑就算成功
那时候的我们很单纯。
一台云服务器装好 Python 和 Playwright,只要能跑出 HTML,我们甚至会互相击掌庆祝。
代码简单到让人害羞:
fromplaywright.sync_apiimportsync_playwrightdefrun_basic():withsync_playwright()asp:browser=p.chromium.launch(headless=True)page=browser.new_page()page.goto("https://example.com")print(page.content())browser.close()当时的潜台词几乎是:
- “默认 User-Agent?无所谓,反正能访问。”
- “不用 Cookie?没事,大不了被弹窗挡一下。”
- “IP 被封?那就换服务器吧。”
我们根本没想到后面会变成那么多“风控场合的互相试探”。
2. 扩张后的第一波暴击:网站开始盯上你了
规模上涨的那段时间特别魔幻。
原本几乎没人管的流量,突然就不再让你随便拿了。
- 固定 IP 连续 3 天抓某站点,被直接拉黑
- 默认 User-Agent 被识别为“自动化工具访问”
- 缺乏 Cookie 会导致无限跳转“请先登录”页面
- 并发数一升高,代理商节点开始抽风
你会突然感受到:
“哦,网站原来一直在看着你。”
这时我们开始尝试“补补补”式防御。
3. 补丁时代:哪里出问题就补哪里
为了尽快恢复上线,我们开始疯狂往旧系统贴补丁:
- 加 User-Agent 随机器
- 给每个站点配置 Cookie
- 代理按小时更换
- JS on/off 全靠硬编码
代码逐渐变成了“加得越多越容易爆炸”的样子。
# 加代理 / Cookie / User-Agent 的中期补丁版fromplaywright.sync_apiimportsync_playwright PROXY_HOST="tunnel.ynuip.cn"PROXY_PORT="8888"PROXY_USER="your_username"PROXY_PASS="your_password"defrun_with_proxy_cookie():withsync_playwright()asp:browser=p.chromium.launch(headless=True,proxy={"server":f"http://{PROXY_HOST}:{PROXY_PORT}","username":PROXY_USER,"password":PROXY_PASS})context=browser.new_context(user_agent="Mozilla/5.0 ... Chrome/123 Safari/537.36",cookies=[{"name":"sessionid","value":"abc","domain":".example.com"}])page=context.new_page()page.goto("https://example.com")print(page.title())browser.close()这一阶段最典型的问题就是——
我们对浏览器的行为一知半解,而“补丁式增强”正是放大混乱的最佳方式。
4. 失控阶段:当系统变成一团无法解释的纠结物
某天凌晨,一次大规模封禁让我们彻底清醒——
30 多个节点瞬间被锁死,我们的任务直接瘫掉一半。
最终的诊断结果几乎令人窒息:
- 有的 UA 是随机的,有的是固定的
- Cookie 有人手填、有自动登录、有过期残留
- 代理IP失效
- JS 开关逻辑完全不统一
- 浏览器指纹 patch 有的做了,有的没做
事情到了这个地步,你已经无法用“人”来推断浏览器的行为了。
那段时间我特有感触:
不是网站风控太强,是我们完全没有管理自己的执行环境。
5. 真正的导火索:我们必须重构
说重构其实很简单,但真要动手是一条漫长的路。
我们意识到一个关键事实:
浏览器执行环境不是写代码时顺手设置的几个参数,而是一整套可描述、可复现、可审计的“配置模型”。
如果不建立一个全局架构去管理,系统只会越来越乱。
于是我们正式开始规划新的执行环境体系。
6. 新架构的诞生:让浏览器的执行环境像产品一样被“制造”
最终,我们把整个“浏览器环境”拆成了三层。
(1)环境模板层:写清楚你“想要的是什么”
它定义一种“任务需要的环境”:
- 用什么 UA(桌面?移动?随机?)
- Cookie 来源?需要登录吗?
- 优质代理?爬虫代理–亿牛云代理
- 是否执行 JS?
- 需要怎样的浏览器指纹策略?
模板就像“需求单”,不用掺杂任何 Playwright 代码。
(2)环境构建器:根据模板生成“真实浏览器环境”
这一层是整个系统的心脏。
构建器要自动完成:
- 创建浏览器实例
- 配置亿牛云代理
- 注入 Cookie
- 设置 UA
- 配置 JS 拦截
- 注入指纹 patch
这就像是“浏览器环境的工厂流水线”。
(3)任务执行层:只关注如何取数
使用者不再需要关心 Cookie、代理、指纹等问题,只需:
env = builder.build(template) page.goto(url) return data简单、稳定、可复现。
7. 新架构示例代码
下面是更完整、更清晰的版本:
""" 执行环境构建器:统一管理代理 让浏览器环境“模块化、可制造” """fromplaywright.sync_apiimportsync_playwright# 16YUN代理配置PROXY_HOST="tunnel.16yun.cn"PROXY_PORT="8888"PROXY_USER="your_username"PROXY_PASS="your_password"classBrowserEnvironmentBuilder:"""负责统一构建 Playwright 执行环境"""def__init__(self,p):self.p=pdefbuild(self,ua:str,cookies:list):"""根据模板构建浏览器上下文"""# 配置代理browser=self.p.chromium.launch(headless=True,proxy={"server":f"http://{PROXY_HOST}:{PROXY_PORT}","username":PROXY_USER,"password":PROXY_PASS})# 注入 UA、Cookiecontext=browser.new_context(user_agent=ua,cookies=cookies)returnbrowser,contextdefrun_task():withsync_playwright()asp:builder=BrowserEnvironmentBuilder(p)# 构建执行环境browser,context=builder.build(ua="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/... Chrome/123",cookies=[{"name":"sessionid","value":"builder_cookie_123","domain":".example.com","path":"/"}])page=context.new_page()page.goto("https://example.com")print("页面标题:",page.title())browser.close()run_task()