Ornold
返回博客
工程10 分钟阅读

如何并行运行数十个指纹浏览器并保持同步

我们拆解了分组视觉分析、状态恢复和并发控制,说明这些机制如何让大批浏览器像一个系统一样协同工作。
2026年4月1日

并行浏览器自动化的挑战

运行一个浏览器很简单。同时运行50个浏览器执行相同的操作是完全不同的问题。页面加载速度不同,CAPTCHA在某些会话中出现但在其他会话中不出现,不同配置文件之间的网络条件也不同。没有协调,并行批处理很快就会变成50个独立脚本,彼此分散。
Ornold将一批浏览器视为单个协调系统。每个操作——导航、表单填充、点击、CAPTCHA求解——都在所有活跃会话中同时运行,内置处理分散和故障的机制。

Ornold中的并行执行如何工作

当您告诉AI代理"在所有浏览器中打开google.com"时,Ornold不会逐个遍历会话。它通过CDP(Chrome DevTools Protocol)将导航命令并行发送到所有活跃会话。同样的方法适用于点击、表单填充、截图和所有其他浏览器操作。
// This navigates ALL active sessions simultaneously await browser_parallel_navigate({ url: "https://target.example/signup" }); // This fills the email field in ALL sessions at once // Each session can get a different value await browser_parallel_fill({ ref: "email", values: profiles.map(p => p.email) });
工具名称中的"parallel"前缀不仅仅是命名约定——它反映了实际的执行模型。命令分散到所有会话,并发执行,结果在下一步之前收集。

分组视觉分析

并行自动化最困难的部分是知道每个屏幕上显示什么。在30个浏览器的批处理中,有些可能显示注册表单,其他可能有CAPTCHA,还有一些可能卡在加载屏幕上。在决定接下来做什么之前,您需要知道每个会话的状态。
Ornold的分组视觉分析通过从所有会话获取截图、将其作为批处理进行分析并按视觉状态对会话进行分组来解决此问题:
// Analyze all sessions at once const analysis = await browser_parallel_vision_analyze_grouped(); // Results are grouped by page state: // group "signup_form": [session1, session2, ... session25] // group "captcha": [session26, session27, session28] // group "error_page": [session29] // group "loading": [session30]
这与逐个检查每个会话根本不同。一个API调用为您提供完整的图景。AI代理随后可以分支逻辑:为需要的会话求解CAPTCHA,为失败的会话重试导航,为准备好的会话继续流程。
分组分析在页面因A/B测试、地理定位或机器人检测而分散时特别有价值。您不是假设所有会话都处于相同状态,而是看到每个会话的实际情况。

有界并发

在真正的并行中运行50个浏览器听起来不错,直到您遇到资源限制。每个浏览器会话消耗CPU、内存和网络带宽。视觉分析调用有API速率限制。CAPTCHA求解服务限制并发请求。
Ornold使用有界并发——它以受控的批处理方式处理会话,而不是一次性启动所有内容:
  • 浏览器操作(导航、点击、填充)——在所有会话中同时运行。这些是轻量级CDP命令,不会消耗资源。
  • 视觉分析——按组处理(默认:一次12个)。截图并行获取,但分析调用被分组以保持在API限制内。
  • CAPTCHA求解——请求并行发出,但求解服务根据容量自然限制。Ornold处理排队。
  • 截图——从所有会话同时捕获。图像数据流式传输,不在内存中缓冲。
// Control concurrency for vision analysis await browser_parallel_vision_analyze_grouped({ maxConcurrency: 12 }); // For very large batches, you can lower concurrency // to reduce memory pressure await browser_parallel_vision_analyze_grouped({ maxConcurrency: 6 });

状态跟踪和恢复

在任何批处理操作中,某些会话都会失败。页面可能无法加载,CAPTCHA可能超时,或表单提交可能返回错误。问题是:如何在不重新启动整个批处理的情况下检测故障并恢复?
Ornold为每个活跃会话提供实时状态跟踪:
// Check the state of all sessions const status = await browser_status(); // Returns per-session info: // { id: "session-1", url: "https://target.example/dashboard", state: "ready" } // { id: "session-2", url: "https://target.example/signup", state: "ready" } // { id: "session-3", url: "about:blank", state: "error" }
有了状态数据,AI代理可以做出恢复决策:
  • 错误页面上的会话——重新导航到目标URL
  • 有CAPTCHA的会话——仅为这些会话运行CAPTCHA求解器
  • 有错误的会话——获取截图进行诊断,然后重试或跳过
  • 领先的会话——等待较慢的会话赶上,然后再进行下一个批处理操作

保持会话同步

并行自动化中最大的挑战不是启动50个浏览器,而是在工作流进行时保持它们同步。不同的页面加载速度不同。某些会话遇到速率限制。其他会话被重定向。
Ornold使用等待所有语义:在每个并行操作之后,它等待所有会话完成(或超时)后再移动到下一步。这可以防止快速会话超过慢速会话。
// Navigate all sessions await browser_parallel_navigate({ url: "https://target.example/signup" }); // Wait until all sessions show the signup form await browser_parallel_wait_for({ text: "Create Account", timeoutMs: 15000 }); // Only proceeds when ALL sessions are ready (or timed out) // Now fill forms — all sessions are on the same page await browser_parallel_fill({ ref: "email", values: emails });
`wait_for`中的超时充当安全阀。如果会话在超时内无法达到预期状态,它会被标记,而不是永远阻止整个批处理。

批处理操作中的每个配置文件数据

并行不意味着相同。每个浏览器配置文件通常需要唯一的数据——不同的电子邮件地址、名称、密码或其他表单值。Ornold在批处理命令中支持每个会话的值:
// Each session gets its own email await browser_parallel_fill({ ref: "email", values: [ "user1@mail.com", "user2@mail.com", "user3@mail.com", // ... one per active session ] }); // Each session gets its own password await browser_parallel_fill({ ref: "password", values: profiles.map(p => p.password) });
值数组按顺序1:1映射到活跃会话。如果您有30个活跃会话,您提供30个值。这保持了并行执行模型,同时允许完全的每个配置文件自定义。

完整的并行工作流

以下是在30个反检测浏览器配置文件上注册账户的现实端到端流程:
// 1. Start sessions and navigate await browser_list(); // See available profiles await browser_parallel_navigate({ url: "https://target.example/signup" }); await browser_parallel_wait_for({ text: "Create Account", timeoutMs: 15000 }); // 2. Fill forms with per-profile data await browser_parallel_fill({ ref: "email", values: emails }); await browser_parallel_fill({ ref: "password", values: passwords }); await browser_parallel_fill({ ref: "name", values: names }); // 3. Solve CAPTCHAs (detected and solved across all sessions) await browser_solve_captcha(); // 4. Submit await browser_parallel_click({ ref: "submit" }); // 5. Verify results await browser_parallel_wait_for({ text: "Welcome", timeoutMs: 20000 }); const status = await browser_status(); // Check which sessions succeeded and which need recovery

扩展提示

  • 从5-10个会话开始验证工作流,然后扩展。使用小批处理进行调试要容易得多。
  • 在每个主要步骤后使用`browser_status()`。不要假设所有会话都处于相同状态。
  • 设置合理的超时。太短会导致虚假故障。太长会导致卡住的会话永远阻止批处理。
  • 对于超过30个的批处理,考虑分成组并按顺序运行。这可以减少峰值资源使用。
  • 监控反检测浏览器的资源使用情况。每个配置文件消耗RAM——50个Chromium实例可以轻松使用16+ GB。
  • 保持代理质量一致。混合的代理质量导致混合的页面加载时间,这会导致同步问题。

常见陷阱

  • 假设所有会话看到相同的页面——它们不会。A/B测试、地理定位和机器人检测会造成分散。始终使用`browser_status()`或分组分析进行检查。
  • 没有恢复逻辑——如果您不处理故障,一个卡住的会话可能会阻止整个批处理。构建重试和跳过逻辑。
  • 忽视资源限制——50个浏览器+视觉分析+CAPTCHA求解可能会使机器过载。使用有界并发。
  • 在并行系统中进行顺序思维——不要逐个遍历会话。使用`browser_parallel_*`工具同时对所有会话进行操作。
  • 不验证结果——成功的表单提交并不意味着账户已创建。始终验证最终状态。

相关文章