写这篇文章之前,我翻了翻旧项目仓库,看到那些“能跑就行”的代码片段,突然有点怀旧。
它们简单粗暴、没啥技巧,但却是我们整个执行环境管理体系的起点。

只是直到后来我们反复被风控拉扯、被代理封禁、被 JS 阻断,我们才逐渐意识到:

**浏览器不是工具,它是一只会反击的野兽。
**要想驯服它,必须清楚地知道它的每一块骨骼、每一根神经都在干什么。

于是,我们从一个土炮脚本,走到了自动化环境构建体系。
这一段演化,几乎浓缩了我过去几年对“浏览器执行环境工程化”的全部理解。

1. 史前时代:只要跑就算成功

那时候的我们很单纯。

一台云服务器装好 Python 和 Playwright,只要能跑出 HTML,我们甚至会互相击掌庆祝。

代码简单到让人害羞:

from playwright.sync_api import sync_playwright

def run_basic():
    with sync_playwright() as p:
        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 的中期补丁版
from playwright.sync_api import sync_playwright

PROXY_HOST = "tunnel.ynuip.cn"
PROXY_PORT = "8888"
PROXY_USER = "your_username"
PROXY_PASS = "your_password"

def run_with_proxy_cookie():
    with sync_playwright() as p:
        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. 新架构示例代码

下面是更完整、更清晰的版本:

"""
执行环境构建器:统一管理代理 
让浏览器环境“模块化、可制造”
"""

from playwright.sync_api import sync_playwright

# 16YUN代理配置
PROXY_HOST = "tunnel.16yun.cn"
PROXY_PORT = "8888"
PROXY_USER = "your_username"
PROXY_PASS = "your_password"

class BrowserEnvironmentBuilder:
    """负责统一构建 Playwright 执行环境"""

    def __init__(self, p):
        self.p = p

    def build(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、Cookie
        context = browser.new_context(
            user_agent=ua,
            cookies=cookies
        )

        return browser, context


def run_task():
    with sync_playwright() as p:
        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()

Logo

这里是“一人公司”的成长家园。我们提供从产品曝光、技术变现到法律财税的全栈内容,并连接云服务、办公空间等稀缺资源,助你专注创造,无忧运营。

更多推荐