AI Agent 云端浏览器自动化方案

3,745 阅读11分钟

开发 AI Agent 时的浏览器自动化方案探索

本文介绍的是 Bright Data 的 Browser API(浏览器自动化 API),一个云端浏览器解决方案

最近在做一个项目,需要让 AI 自动完成一些网页操作:搜索资料、提取信息、填写表单等。一开始觉得应该不难,用 Puppeteer 或 Selenium 就能搞定。但真正动手后才发现,在生产环境中要让浏览器自动化稳定运行,远比想象中复杂。

graph LR
    A[AI Agent 启动] --> B[打开浏览器]
    B --> C[搜索关键词]
    C --> D[分析搜索结果]
    D --> E[点击目标链接]
    E --> F[提取页面信息]
    F --> G{需要更多信息?}
    G -->|是| H[填写表单]
    G -->|否| J[完成任务]
    H --> I[提交表单]
    I --> F
    
    style A fill:#e1f5ff
    style J fill:#d4edda
    style G fill:#fff3cd

遇到的第一个问题:反爬机制

最初的方案很简单:用 Puppeteer 写个脚本,自动访问目标网站。本地测试完全正常,但部署到服务器上运行几次后就出问题了。

第一次是验证码。很多网站会检测到"异常访问",弹出"请验证您是人类"的提示。一开始以为是访问频率太高,降低频率后,验证码依然频繁出现。

后来发现问题出在浏览器指纹上。无头浏览器(headless browser)有很多特征可以被识别:

  • navigator.webdriver 属性为 true
  • 缺少某些 WebGL 相关的 API
  • Chrome DevTools Protocol 的痕迹
  • window 对象上的某些属性缺失

反爬系统会检测这些特征,一旦发现是自动化程序,就触发验证码或直接拒绝访问。

graph TD
    A[访问网站] --> B{反爬检测}
    B -->|检测浏览器指纹| C{navigator.webdriver?}
    B -->|检测行为特征| D{访问频率异常?}
    B -->|检测环境| E{缺少WebGL等API?}
    
    C -->|是| F[🚫 触发验证码]
    D -->|是| F
    E -->|是| F
    
    C -->|否| G[✅ 正常访问]
    D -->|否| G
    E -->|否| G
    
    F --> H[需要人工处理]
    
    style F fill:#f8d7da
    style G fill:#d4edda
    style H fill:#fff3cd

在这里插入图片描述

网上有一些规避方案,比如 puppeteer-extra-plugin-stealth 插件,可以隐藏部分特征。我试过,确实有一定效果,但不是万能的。有些网站的检测机制更复杂,经常需要调整对抗策略。而且这些插件的维护也是个问题,网站更新检测逻辑后,插件可能就失效了。

在这里插入图片描述

第二个问题:IP 管理

为了避免单个 IP 被封,我买了一批代理。但代理也带来了新的麻烦。

graph TD
    A[需要使用代理] --> B[购买代理服务]
    B --> C{代理质量检测}
    
    C -->|便宜数据中心代理| D[❌ 经常被拉黑]
    C -->|住宅代理| E[✅ 质量好但贵]
    
    E --> F[配置代理池]
    F --> G[实现轮换逻辑]
    
    G --> H{什么时候换?}
    H -->|定时换| I[可能触发风控]
    H -->|失败后换| J[频率不可控]
    
    G --> K[定期检测可用性]
    K --> L[剔除失效代理]
    L --> M[补充新代理]
    
    M --> N[还要考虑地理位置]
    N --> O[😫 维护成本很高]
    
    style D fill:#f8d7da
    style E fill:#fff3cd
    style O fill:#f8d7da

在这里插入图片描述

首先是代理质量。便宜的数据中心代理经常被网站拉黑,连接成功率很低。我试过几家服务商,质量都不太稳定。住宅代理好一些,但费用也高不少。

其次是轮换逻辑。什么时候换 IP?请求失败后换还是定时换?换得太频繁,有些网站会觉得异常;不换,又容易被封。不同网站的策略不一样,需要分别调试。

还有代理池的维护。要定期检测代理的可用性,剔除失效的,补充新的。这些都需要额外的代码和定时任务。

代理的地理位置也是个问题。有些网站会根据 IP 归属地返回不同内容,或者限制某些地区访问。需要针对不同任务选择合适的代理地区。

第三个问题:规模化运行

一开始只有几个任务,单机跑几个浏览器实例就够了。但后来任务量增加,需要几十甚至上百个并发。

浏览器很吃资源。Chrome 一个实例就要几百 MB 内存,10 个实例就是好几个 GB。CPU 占用也不低,页面渲染、JavaScript 执行都需要计算资源。

我试过用轻量级的 headless 模式,禁用图片加载等优化手段,但效果有限。服务器配置不够的话,要么加机器,要么减少并发数。

会话管理也是个问题。AI Agent 需要保持上下文:登录状态、浏览历史、Cookie 等。多个实例之间要做好数据隔离,避免互相干扰。如果实例崩溃了,还要能恢复会话状态。

横向扩展就更复杂了。单机扛不住,就要多台机器。但多台机器怎么协调?任务怎么分配?状态怎么同步?基本要搭一套完整的分布式系统。

AI Agent 的特殊需求

传统爬虫通常是"请求-响应"模式:发一个 HTTP 请求,拿到页面内容就结束了。但 AI Agent 不一样。

它需要像人一样操作网页:

  • 先搜索一个关键词
  • 根据搜索结果点击某个链接
  • 在新页面填写表单
  • 提交后等待结果
  • 根据结果决定下一步操作

这是一个多步骤、有状态的交互流程。每一步都依赖前面的操作,需要保持会话连续性。

另外,AI 的决策是动态的。它可能根据页面内容临时调整策略,比如看到某个按钮就点击,没看到就跳过。这种动态交互,用传统的爬虫脚本很难实现。

云端浏览器方案

在寻找解决方案时,我了解到 Bright Data 有一个叫 Browser API 的服务(也叫 Scraping Browser)。简单说,就是把浏览器放在云端运行,通过 API 来控制。

这个思路其实不新。之前也有类似的"浏览器即服务"产品,比如 BrowserStack、Sauce Labs 等,主要用于自动化测试。但 Browser API 的设计目标不太一样,它更侧重于解决生产环境中的反爬和扩展性问题,特别适合多步骤的数据采集场景。

在这里插入图片描述

几个关键特点:

有头浏览器运行

它在云端跑的是完整的浏览器(有 GUI 的),而不是 headless 模式。从网站的角度看,这和真实用户访问没什么区别。浏览器指纹、WebGL、各种 API 的行为都和正常浏览器一致。

这解决了前面说的反爬检测问题。因为它本质上就是一个真实的浏览器,没有那些 headless 的特征。

内置反爬处理

验证码识别、IP 轮换、浏览器指纹管理这些,都在底层自动处理了。不需要自己去对接打码平台,也不需要维护代理池。

据官方介绍,他们维护了一个很大的住宅代理网络,覆盖全球 195 个国家。请求失败时会自动切换 IP 重试,对用户来说是透明的。

验证码处理也是自动的。常见的滑块验证、图片选择等,系统会尝试识别和通过。虽然不是 100% 成功,但成功率比自己实现要高不少。

在这里插入图片描述

按需分配资源

需要多少个浏览器实例,直接通过 API 创建就行。不用担心服务器资源不够,也不用提前规划容量。

这对于任务量波动比较大的场景很有用。比如平时只需要几个实例,但某个时间段突然需要几百个,可以临时扩容,用完就释放。

兼容现有工具

支持 Puppeteer、Selenium、Playwright 这些常用框架。现有代码基本不用改,只需要改一下连接方式。

这是我比较看重的一点。如果要用一个新工具,意味着要重新学习 API、重写代码、迁移现有项目。但如果能兼容现有工具,迁移成本就低多了。

实际测试

在这里插入图片描述

在这里插入图片描述

我拿之前的项目试了一下。原本用 Puppeteer 跑的脚本,验证码触发率比较高,大概每访问 5-10 次就会遇到一次验证码。

换成 Browser API 后,同样的任务,跑了上百次,验证码出现的次数明显减少。具体数字没仔细统计,但感觉降到了 5% 以下。

更重要的是,代码改动很小。原本的 Puppeteer 脚本,只需要把连接方式从本地改成远程 WebSocket 就行了:

// 原来的方式
const browser = await puppeteer.launch();

// 改成远程连接(使用 Browser API)
const AUTH = 'USERNAME:PASSWORD'; // 从控制台获取你的凭证
const browser = await puppeteer.connect({
  browserWSEndpoint: `wss://${AUTH}@brd.superproxy.io:9222`,
});

// 后面的代码完全不变
const page = await browser.newPage();
await page.goto('https://example.com');
await page.click('#some-button');
// ...

如果用 Selenium,也类似。只需要改一下 WebDriver 的连接地址:

from selenium import webdriver
from selenium.webdriver.chromium.remote_connection import ChromiumRemoteConnection

# 连接到远程浏览器(使用 Browser API)
AUTH = 'USERNAME:PASSWORD'  # 从控制台获取你的凭证
sbr_webdriver = f'https://{AUTH}@brd.superproxy.io:9515'
connection = ChromiumRemoteConnection(sbr_webdriver, 'goog', 'chrome')

# 后面的代码不变
with webdriver.Remote(connection, options=webdriver.ChromeOptions()) as driver:
    driver.get('https://example.com')
    driver.find_element(By.ID, 'some-button').click()
    # ...

会话管理的限制

在实际使用中,需要注意 Browser API 的一些会话限制。根据官方文档:

单次导航限制
每个浏览器会话只允许一次"初始导航"(initial navigation)。这个初始导航指的是第一次用 page.goto() 加载目标网站。

之后,你可以在同一个会话中自由地点击、滚动、填表单等操作,但如果要开始一个新的抓取任务(即使是同一个网站),需要创建新的会话。

超时限制

  • 空闲超时:如果会话5分钟没有活动,会自动断开
  • 最大时长:单个会话最多维持30分钟

这些限制主要是为了防止资源浪费。在设计任务时需要考虑到这一点,把长时间的任务拆分成多个会话,或者确保会话中持续有操作。

会话保持

AI Agent 的另一个需求是会话保持。比如要完成一个"搜索商品并加入购物车"的任务,需要:

  1. 访问首页
  2. 登录账号(保持登录态)
  3. 搜索商品(在登录态下)
  4. 点击商品详情(仍然保持登录态)
  5. 加入购物车
  6. 查看购物车

这个流程中,每一步都依赖前面的状态。如果用传统的 HTTP 请求方式,需要手动管理 Cookie、Session 等。而且很多网站会检测请求头、Referer 等,一旦不一致就会判定为异常。

在真实的浏览器环境里,这些都是自动处理的。Browser API 支持会话保持,可以维护登录态、浏览历史、Cookie 等状态。代码写起来也很自然:

graph TD
    A[启动浏览器会话] --> B[访问首页]
    B --> C[登录账号]
    C --> D[🔒 登录态已建立]
    
    D --> E[搜索商品]
    E --> F[🔒 保持登录态]
    
    F --> G[点击商品详情]
    G --> H[🔒 继续保持登录态]
    
    H --> I[加入购物车]
    I --> J[🔒 仍然保持登录态]
    
    J --> K[查看购物车]
    K --> L[✅ 完成整个流程]
    
    style D fill:#d4edda
    style F fill:#d4edda
    style H fill:#d4edda
    style J fill:#d4edda
    style L fill:#cfe2ff

在这里插入图片描述

整个过程中,Cookie、Session 等会话状态自动保持,无需手动管理

const AUTH = 'USERNAME:PASSWORD'; // 你的 Browser API 凭证
const browser = await puppeteer.connect({ 
  browserWSEndpoint: `wss://${AUTH}@brd.superproxy.io:9222`
});
const page = await browser.newPage();

// 第一步:登录
await page.goto('https://example.com/login');
await page.type('#username', 'myuser');
await page.type('#password', 'mypass');
await page.click('#submit');
await page.waitForNavigation();

// 第二步:搜索商品(自动保持登录态)
await page.goto('https://example.com/search?q=laptop');
await page.waitForSelector('.product-item');

// 第三步:加入购物车(仍然保持登录态)
await page.click('.product-item:first-child .add-to-cart');
await page.waitForTimeout(1000);

// 第四步:查看购物车
await page.goto('https://example.com/cart');
const cartItems = await page.$$eval('.cart-item', items => 
  items.map(item => item.textContent)
);

console.log('购物车内容:', cartItems);

整个流程中,登录态、Cookie、浏览历史都自动保持了,不需要手动处理。

多标签页支持

有时候一个任务需要同时操作多个页面。比如在一个页面搜索,在另一个页面查看详情,再在第三个页面比价。

graph TB
    A[同一个浏览器会话] --> B[标签页1: 搜索页]
    A --> C[标签页2: 商品详情]
    A --> D[标签页3: 比价页]
    
    B --> E[提取商品ID]
    C --> F[获取详细信息]
    D --> G[获取价格对比]
    
    E --> H{数据汇总}
    F --> H
    G --> H
    
    H --> I[✅ 综合分析结果]
    
    style A fill:#e1f5ff
    style H fill:#fff3cd
    style I fill:#d4edda

在这里插入图片描述

传统的 HTTP 请求方式很难模拟这种场景。但在浏览器里,这就是普通的多标签页操作:

const AUTH = 'USERNAME:PASSWORD';
const browser = await puppeteer.connect({ 
  browserWSEndpoint: `wss://${AUTH}@brd.superproxy.io:9222`
});

// 打开多个标签页
const page1 = await browser.newPage();
await page1.goto('https://site1.com');

const page2 = await browser.newPage();
await page2.goto('https://site2.com');

const page3 = await browser.newPage();
await page3.goto('https://site3.com');

// 在不同标签页之间切换操作
await page1.click('#some-button');
const data1 = await page1.$eval('#result', el => el.textContent);

await page2.type('#input', data1);
await page2.click('#submit');

// 所有标签页共享同一个浏览器会话

这对于需要关联多个网站数据的 AI Agent 很有用。

地理位置选择

有些网站会根据访问者的 IP 地址返回不同内容。比如电商网站的价格、库存,新闻网站的内容等。

Browser API 可以指定浏览器实例的地理位置。支持全球 195 个国家,可以在代码里灵活切换:

const AUTH = 'USERNAME:PASSWORD';

// 从美国访问
const browserUS = await puppeteer.connect({
  browserWSEndpoint: `wss://${AUTH}@brd.superproxy.io:9222?country=us`,
});

// 从日本访问
const browserJP = await puppeteer.connect({
  browserWSEndpoint: `wss://${AUTH}@brd.superproxy.io:9222?country=jp`,
});

这对于跨区域的数据采集、价格监控等场景比较有用。

扩展性

前面提到,自己搭建分布式浏览器集群很复杂。用云端方案的好处是,扩展性基本不用操心。

需要 10 个并发,就创建 10 个会话;需要 100 个,就创建 100 个。底层的资源调度、负载均衡都是自动的。

graph LR
    A[业务需求] --> B{并发数量}
    
    B -->|10个| C1[创建10个会话]
    B -->|100个| C2[创建100个会话]
    B -->|1000个| C3[创建1000个会话]
    
    C1 --> D[云端自动分配]
    C2 --> D
    C3 --> D
    
    D --> E[全球分布式节点]
    E --> F[自动负载均衡]
    F --> G[任务并行执行]
    
    G --> H[✅ 无需管理服务器]
    
    style B fill:#fff3cd
    style D fill:#e1f5ff
    style H fill:#d4edda

在这里插入图片描述

// 同时启动 50 个任务
const tasks = [];
for (let i = 0; i < 50; i++) {
  tasks.push(runTask(i));
}
await Promise.all(tasks);

async function runTask(id) {
  const browser = await puppeteer.connect({ browserWSEndpoint: '...' });
  const page = await browser.newPage();
  // 执行任务...
  await browser.close();
}

当然,这会产生相应的费用。但至少不用担心服务器撑不住,也不用半夜起来处理故障。

一些限制

没有完美的方案。Browser API 也有一些限制:

会话限制
每个会话只能有一次初始导航,最长30分钟,空闲5分钟自动断开。对于需要长时间保持同一会话的场景,需要特别设计任务流程。

费用问题
按流量计费,如果任务量很大,费用会比较高。需要在成本和便利性之间权衡。对于低频任务或者预算有限的场景,自建可能更合适。

网络延迟
浏览器在云端运行,每次操作都需要通过网络传输指令和结果。如果对响应时间要求很高,可能不太适合。

不是所有网站都能解决
内置的反爬处理能应对大部分网站,但也不是万能的。极个别的网站可能仍然会检测出来。这种情况下,可能需要额外的对抗策略。

调试不如本地方便
本地运行浏览器的话,可以直接看到浏览器窗口,调试起来很直观。云端浏览器虽然也有截图、录屏等调试手段,但还是没有本地方便。

适用场景

综合来看,Browser API 比较适合这些场景:

在这里插入图片描述

AI Agent 自动化任务
需要多步交互、保持会话、动态决策的场景。比如智能客服、自动填表、数据采集等。特别适合需要在同一会话中完成多个交互步骤的任务。

大规模并发任务
需要同时运行几十上百个浏览器实例,自建基础设施成本太高的场景。

对反爬要求高
目标网站的反爬机制比较严格,普通 headless 浏览器容易被封的场景。

快速原型开发
想快速验证一个想法,不想花时间搭建基础设施。或者项目初期,任务量不确定,希望先用起来再说。

相反,如果是这些场景,可能不太适合:

  • 任务量很小,偶尔跑几次
  • 预算非常有限,必须控制成本
  • 对响应时间要求极高(毫秒级)
  • 需要极度定制化的浏览器环境

总结

浏览器自动化在 AI Agent 时代变得越来越重要。但要在生产环境稳定运行,需要解决反爬、代理、扩展性等一系列问题。

自己搭建完整的基础设施,对于大多数团队来说成本都比较高。云端浏览器服务提供了一个折中方案:用 API 的方式调用浏览器,底层的复杂性都被封装了。

graph TB
    subgraph 传统自建方案
    A1[开发者] --> B1[购买服务器]
    B1 --> C1[部署浏览器]
    C1 --> D1[配置代理池]
    D1 --> E1[实现反爬对抗]
    E1 --> F1[维护监控]
    F1 --> G1[处理故障]
    G1 --> H1[扩容优化]
    end
    
    subgraph 云端浏览器方案
    A2[开发者] --> B2[调用 API]
    B2 --> C2[✅ 自动分配浏览器]
    C2 --> D2[✅ 自动管理代理]
    D2 --> E2[✅ 自动处理反爬]
    E2 --> F2[✅ 自动扩展]
    F2 --> G2[专注业务逻辑]
    end
    
    style G1 fill:#f8d7da
    style G2 fill:#d4edda

在这里插入图片描述

Browser API 是这个方向上的一个实现。它的核心价值是让开发者可以专注于业务逻辑,而不是花时间对抗反爬、维护代理池、管理服务器。

当然,任何技术方案都有适用场景和成本考量。特别是要注意会话限制(单次导航、30分钟最大时长)对业务流程的影响。重要的是理解自己的需求,在便利性、成本、性能之间找到平衡点。

如果你也在开发 AI Agent 或者做浏览器自动化,遇到类似的问题,可以考虑试试看云端浏览器方案。

如果你对亮数据不熟悉,对里面的一些技术不了解,可以直接点击右下角的 AI亮助理 发起提问

在这里插入图片描述


相关资源: