# 多浏览器架构文档

## 概述

本项目采用**策略模式 + 工厂模式**实现多浏览器支持，可以轻松切换不同的浏览器提供商（AdsPower、Playwright、Puppeteer等）。

---

## 架构图

```
┌─────────────────────────────────────────────────────┐
│             BrowserManager (统一接口)                │
│         保持向后兼容，支持多种提供商                   │
└──────────────────────┬──────────────────────────────┘
                       │
                       ├── 使用工厂创建
                       ↓
         ┌─────────────────────────────┐
         │      BrowserFactory         │
         │        (工厂类)              │
         └─────────────┬───────────────┘
                       │
         ┌─────────────┴───────────────┐
         │                             │
         ↓                             ↓
┌──────────────────┐          ┌──────────────────┐
│  BaseBrowserProvider │       │  更多提供商...    │
│   (抽象基类)          │       │                  │
└────────┬─────────┘          └──────────────────┘
         │
         ├── 实现
         ↓
┌──────────────────────┐
│  AdsPowerProvider    │  付费 ✅ 指纹 ✅ Cloudflare绕过
│  (AdsPower集成)      │
└──────────────────────┘

未来扩展：
├── PlaywrightStealthProvider  免费 ✅ 隐身模式
├── PuppeteerStealthProvider   免费 ✅ 隐身模式
├── SeleniumUndetectedProvider 免费 ✅ 反检测
└── NoDriverProvider           免费 ✅ 反检测
```

---

## 目录结构

```
src/shared/libs/browser/
├── browser-manager.js           # 统一管理器（向后兼容）
├── providers/                   # 提供商实现
│   ├── base-provider.js        # 抽象基类
│   ├── adspower-provider.js    # AdsPower实现
│   └── ... (未来添加更多)
└── factory/
    └── browser-factory.js      # 工厂类
```

---

## 使用方式

### 1. 默认使用（AdsPower，向后兼容）

```javascript
const BrowserManager = require('./src/shared/libs/browser/browser-manager');

// 从环境变量读取配置
const browser = new BrowserManager({
  siteName: 'MyApp'
});

await browser.launch();
const page = browser.getPage();
// ... 使用 page
await browser.close();
```

### 2. 显式指定提供商

```javascript
// 使用 AdsPower
const browser = new BrowserManager({
  provider: 'adspower',
  profileId: 'k1728p8l',
  siteName: 'MyApp'
});

// 未来：使用 Playwright Stealth
const browser = new BrowserManager({
  provider: 'playwright-stealth',
  headless: false,
  siteName: 'MyApp'
});
```

### 3. 通过环境变量切换

```bash
# .env 文件
BROWSER_PROVIDER=adspower
ADSPOWER_USER_ID=k1728p8l
ADSPOWER_API=http://local.adspower.net:50325
ADSPOWER_API_KEY=your_api_key
```

```javascript
// 自动从环境变量读取 BROWSER_PROVIDER
const browser = new BrowserManager();
await browser.launch();
```

### 4. 使用工厂直接创建

```javascript
const { BrowserFactory } = require('./src/shared/libs/browser/factory/browser-factory');

// 创建提供商实例
const provider = BrowserFactory.create('adspower', {
  profileId: 'k1728p8l'
});

await provider.launch();
```

---

## API 参考

### BrowserManager

| 方法 | 说明 | 返回值 |
|------|------|--------|
| `constructor(options)` | 创建管理器 | - |
| `launch(options)` | 启动浏览器 | `Promise<{browser, page}>` |
| `getPage()` | 获取页面 | `Page` |
| `getBrowser()` | 获取浏览器 | `Browser` |
| `clearData()` | 清除缓存 | `Promise<void>` |
| `close()` | 关闭浏览器 | `Promise<void>` |
| `newPage()` | 创建新页面 | `Promise<Page>` |
| `getProviderName()` | 获取提供商名称 | `string` |
| `getProviderMetadata()` | 获取提供商元数据 | `Object` |

### BrowserFactory

| 方法 | 说明 | 返回值 |
|------|------|--------|
| `create(name, config)` | 创建提供商 | `BaseBrowserProvider` |
| `getAvailableProviders()` | 列出所有提供商 | `string[]` |
| `getFreeProviders()` | 列出免费提供商 | `string[]` |
| `getPaidProviders()` | 列出付费提供商 | `string[]` |
| `findProvidersByCapability(cap)` | 按能力查找 | `string[]` |
| `getRecommendedProvider(req)` | 获取推荐提供商 | `string` |

---

## 提供商对比

| 提供商 | 类型 | 指纹伪装 | Cloudflare | Stripe | 代理 | 配置文件 |
|--------|------|----------|-----------|--------|------|---------|
| **AdsPower** | 付费 | ✅ | ✅ | ✅ | ✅ | ✅ |
| Playwright Stealth | 免费 | ⚠️ | ⚠️ | ❌ | ✅ | ❌ |
| Puppeteer Stealth | 免费 | ⚠️ | ⚠️ | ❌ | ✅ | ❌ |
| Selenium Undetected | 免费 | ⚠️ | ⚠️ | ❌ | ✅ | ❌ |

**说明：**
- ✅ = 完全支持
- ⚠️ = 部分支持
- ❌ = 不支持

---

## 扩展新提供商

### 1. 创建提供商类

```javascript
// src/shared/libs/browser/providers/my-provider.js
const BaseBrowserProvider = require('./base-provider');

class MyProvider extends BaseBrowserProvider {
  getName() {
    return 'MyProvider';
  }

  isFree() {
    return true; // 或 false
  }

  getCapabilities() {
    return {
      stealth: true,
      fingerprint: false,
      // ...
    };
  }

  async launch(options = {}) {
    // 实现启动逻辑
  }

  async close() {
    // 实现关闭逻辑
  }

  // ... 实现其他抽象方法
}

module.exports = MyProvider;
```

### 2. 注册到工厂

```javascript
// src/shared/libs/browser/factory/browser-factory.js
const MyProvider = require('../providers/my-provider');

class BrowserFactory {
  static _providers = {
    'adspower': AdsPowerProvider,
    'my-provider': MyProvider,  // 添加这里
  };
  // ...
}
```

### 3. 使用新提供商

```javascript
const browser = new BrowserManager({
  provider: 'my-provider',
  // ... 配置
});
```

---

## 配置示例

### AdsPower

```javascript
{
  provider: 'adspower',
  profileId: 'k1728p8l',
  apiBase: 'http://local.adspower.net:50325',
  apiKey: 'your_api_key',
  incognitoMode: true
}
```

### Playwright Stealth (未来)

```javascript
{
  provider: 'playwright-stealth',
  headless: false,
  viewport: { width: 1920, height: 1080 },
  userAgent: 'custom user agent',
  proxy: {
    server: 'http://proxy.com:8080',
    username: 'user',
    password: 'pass'
  }
}
```

---

## 工具命令（未来）

```bash
# 列出所有提供商
npm run browser -- list

# 测试提供商
npm run browser -- test adspower

# 切换默认提供商
npm run browser -- switch playwright-stealth

# 比较提供商
npm run browser -- compare
```

---

## 迁移指南

### 从旧版本迁移

**旧代码：**
```javascript
const BrowserManager = require('./browser-manager');
const browser = new BrowserManager({
  profileId: 'k1728p8l'
});
```

**新代码（完全兼容）：**
```javascript
const BrowserManager = require('./browser-manager');
const browser = new BrowserManager({
  profileId: 'k1728p8l'  // 无需改变！
});
```

**或显式指定：**
```javascript
const browser = new BrowserManager({
  provider: 'adspower',  // 新增：显式指定
  profileId: 'k1728p8l'
});
```

---

## 常见问题

### Q: 如何切换到免费浏览器？

A: 等待 Phase 2 完成后，只需修改配置：
```javascript
provider: 'playwright-stealth'
```

### Q: 可以混用多个提供商吗？

A: 可以！每个实例独立：
```javascript
const browser1 = new BrowserManager({ provider: 'adspower' });
const browser2 = new BrowserManager({ provider: 'playwright-stealth' });
```

### Q: 如何知道当前使用的是哪个提供商？

A:
```javascript
console.log(browser.getProviderName()); // 'adspower'
console.log(browser.getProviderMetadata());
```

---

## 开发路线图

- [x] **Phase 1**: 抽象接口 + AdsPower迁移
- [ ] **Phase 2**: 添加 Playwright Stealth
- [ ] **Phase 3**: 添加 Puppeteer Stealth
- [ ] **Phase 4**: CLI工具
- [ ] **Phase 5**: 文档和测试

---

**版本:** 1.0.0  
**更新时间:** 2025-11-21  
**作者:** AI Assistant
