Automation & RPA Integration Guide

学习如何使用 NestBrowser 的自动化 API 与 Selenium、Puppeteer、Playwright 及自定义 RPA 工作流集成,实现浏览器配置文件的规模化自动管理。

NestBrowser 提供本地 REST API,允许你通过程序化方式控制浏览器配置文件。这支持强大的自动化工作流——从简单的脚本化登录,到管理数百个账号的复杂 RPA 流程。

自动化 API 的工作原理

NestBrowser 运行时会启动一个本地 HTTP 服务(默认:http://localhost:19222)。该服务提供以下功能的接口:

  • 列出和创建浏览器配置文件
  • 启动和停止配置文件
  • 通过 WebSocket 调试端口连接自动化框架
  • 通过程序化方式管理 Cookie 和会话

使用 Puppeteer 连接

Puppeteer 是最常见的 NestBrowser 集成自动化框架。

第一步:获取配置文件的 WebSocket URL

const axios = require('axios');

// 获取配置文件列表
const { data: profiles } = await axios.get('http://localhost:19222/api/v1/browser/list');

// 通过 ID 启动指定配置文件
const profileId = profiles[0].id;
const { data: startResult } = await axios.post(
  `http://localhost:19222/api/v1/browser/start?id=${profileId}`
);

const wsEndpoint = startResult.ws.puppeteer;
// 例如: "ws://127.0.0.1:9222/devtools/browser/xxx"

第二步:将 Puppeteer 连接到配置文件

const puppeteer = require('puppeteer-core');

const browser = await puppeteer.connect({
  browserWSEndpoint: wsEndpoint,
  defaultViewport: null,
});

const page = await browser.newPage();
await page.goto('https://www.amazon.com');

// 在这里编写你的自动化逻辑
await page.waitForSelector('#nav-link-accountList');

第三步:自动化完成后关闭配置文件

// 关闭配置文件(可选——会停止浏览器但保留配置文件数据)
await axios.post(`http://localhost:19222/api/v1/browser/stop?id=${profileId}`);

使用 Selenium WebDriver 连接

NestBrowser 的 API 与 ChromeDriver 兼容,因此 Selenium 的接入配置很简单。

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import requests

# 启动配置文件(Python 示例)
profile_id = "your-profile-id"
result = requests.post(f"http://localhost:19222/api/v1/browser/start?id={profile_id}")
debugger_address = result.json()["ws"]["selenium"]
# 例如: "127.0.0.1:9223"

# 连接 Selenium
options = Options()
options.add_experimental_option("debuggerAddress", debugger_address)
driver = webdriver.Chrome(options=options)

driver.get("https://www.tiktok.com")
# 在这里编写你的 Selenium 逻辑

使用 Playwright 连接

const { chromium } = require('playwright');
const axios = require('axios');

// 启动配置文件
const { data } = await axios.post(
  `http://localhost:19222/api/v1/browser/start?id=${profileId}`
);

// 连接 Playwright
const browser = await chromium.connectOverCDP(data.ws.puppeteer);
const context = browser.contexts()[0];
const page = context.pages()[0];

await page.goto('https://www.facebook.com');

多配置文件并发自动化

API 支持并发配置文件操作,便于同时对多个账号运行自动化任务。

const axios = require('axios');
const puppeteer = require('puppeteer-core');

async function automateProfile(profileId, task) {
  // 启动配置文件
  const { data } = await axios.post(
    `http://localhost:19222/api/v1/browser/start?id=${profileId}`
  );
  
  const browser = await puppeteer.connect({
    browserWSEndpoint: data.ws.puppeteer,
    defaultViewport: null,
  });
  
  try {
    const page = await browser.newPage();
    await task(page);
  } finally {
    await axios.post(
      `http://localhost:19222/api/v1/browser/stop?id=${profileId}`
    );
  }
}

// 并发运行 5 个配置文件
const profiles = ['id1', 'id2', 'id3', 'id4', 'id5'];
await Promise.all(
  profiles.map(id => automateProfile(id, async (page) => {
    await page.goto('https://example.com');
    // 你的任务逻辑
  }))
);

常见自动化使用场景

账号自动预热

async function warmAccount(page) {
  // 模拟自然的浏览行为
  await page.goto('https://www.amazon.com');
  await page.waitForTimeout(2000 + Math.random() * 3000);
  
  // 浏览一些商品类目
  const categories = [
    '/s?k=电子产品',
    '/s?k=图书',
    '/s?k=服装'
  ];
  
  for (const cat of categories) {
    await page.goto(`https://www.amazon.com${cat}`);
    await page.waitForTimeout(3000 + Math.random() * 5000);
    // 模拟滚动
    await page.evaluate(() => window.scrollBy(0, 500));
    await page.waitForTimeout(1000 + Math.random() * 2000);
  }
}

数据采集

async function collectProductData(page, searchTerm) {
  await page.goto(`https://www.amazon.com/s?k=${encodeURIComponent(searchTerm)}`);
  
  const products = await page.evaluate(() => {
    return Array.from(document.querySelectorAll('[data-component-type="s-search-result"]'))
      .map(el => ({
        title: el.querySelector('h2 span')?.textContent,
        price: el.querySelector('.a-price-whole')?.textContent,
        rating: el.querySelector('.a-icon-alt')?.textContent,
        asin: el.getAttribute('data-asin'),
      }));
  });
  
  return products;
}

定时任务(Cron)

const cron = require('node-cron');

// 每天上午 9 点自动检查库存并更新商品信息
cron.schedule('0 9 * * *', async () => {
  console.log('开始每日库存检查...');
  
  const profiles = await getActiveSellerProfiles();
  for (const profile of profiles) {
    await automateProfile(profile.id, async (page) => {
      await checkInventory(page, profile.storeId);
    });
  }
});

API 接口参考

GET /api/v1/browser/list

返回所有浏览器配置文件。

响应:

[
  {
    "id": "profile-uuid",
    "name": "亚马逊店铺A",
    "created_at": "2024-01-15T10:00:00Z",
    "last_used": "2024-03-01T14:22:00Z"
  }
]

POST /api/v1/browser/start?id={profileId}

启动浏览器配置文件并返回连接信息。

响应:

{
  "code": 0,
  "ws": {
    "puppeteer": "ws://127.0.0.1:9222/devtools/browser/xxx",
    "selenium": "127.0.0.1:9222"
  }
}

POST /api/v1/browser/stop?id={profileId}

停止正在运行的配置文件。

最佳实践

添加类人延迟:真实用户不会以机器速度点击。在操作之间添加随机延迟(例如:await page.waitForTimeout(800 + Math.random() * 1500))。

优雅处理错误:始终用 try/catch 包裹自动化代码,确保即使发生错误时配置文件也能被正常关闭。

不要同时运行过多配置文件:可同时运行的配置文件数量取决于机器内存。一般建议:每个活动配置文件 100–200MB。

将自动化代码与配置文件管理分离:自动化脚本应可以在不同配置文件 ID 之间复用。

相关文档