返回博客

通过API自动化代理切换:如何为爬虫和套利设置轮换

通过API自动更换代理的完整指南:代码示例、与解析器和反检测浏览器的集成、常见问题解决方案。

📅2026年2月16日
# HTML контент переведен на китайский язык ```html

在处理数百个请求时手动更换代理是浪费时间和金钱。API轮换允许在被封锁时自动切换IP地址、分配负载并扩展数据采集或多账号管理。在本指南中,我们将介绍如何为不同任务配置自动代理轮换:从电商平台数据采集到Facebook Ads账号养号。

本材料既适合编写Python或Node.js采集器的开发人员,也适合使用带API集成的现成工具的流量套利者。

为什么需要通过API自动化代理轮换

通过API自动轮换IP地址解决了不同领域专家面临的几个关键任务:

用于电商平台和网站数据采集: 从Wildberries、Ozon或Avito收集数据时,每个IP可以发出有限数量的请求(通常每小时50-200次)。API轮换允许在达到限制或遇到验证码时自动切换到新IP,确保持续的数据收集。

用于流量套利和多账号管理: 在管理20-50个Facebook Ads广告账户或Instagram账号时,需要隔离每个配置文件。API允许以编程方式为Dolphin Anty或AdsPower中的每个账号分配唯一代理,在被封锁时自动重新创建会话。

用于SMM自动化: Instagram、TikTok或VK的批量发布服务必须在IP地址之间分配操作,以避免速率限制。API提供了为每个会话或账号组动态获取新代理的能力。

与手动更换相比,API自动化的主要优势:

  • 速度: IP切换在毫秒内以编程方式完成,无需人工参与
  • 可扩展性: 可以通过统一界面同时管理数千个代理
  • 容错性: 自动替换不工作的代理而不停止进程
  • 灵活性: 根据具体任务配置轮换规则:按时间、按请求数量、按地理位置
  • 节省成本: 通过负载均衡优化流量使用

典型使用场景:您正在采集Wildberries上竞争对手的价格。没有API,您需要手动监控封锁,进入代理提供商面板,复制新数据,将其粘贴到脚本中。使用API,所有这些都会自动发生:脚本收到429错误(请求过多),向代理服务API发送请求,获取新IP并继续工作。

代理轮换类型:粘性会话 vs 自动轮换

在配置自动化之前,了解IP地址轮换类型之间的区别很重要。策略的选择取决于您的任务。

粘性会话(会话代理)

使用粘性会话时,一个IP地址在特定时间内(通常为5到30分钟)固定到您的会话。只有在会话时间到期或通过您的API请求后才会更换。

何时使用:

  • 在社交网络(Instagram、Facebook)中使用账号 - 频繁更换IP会引起怀疑
  • 填写需要保持会话的多页表单
  • 在会话期间从特定地区测试广告
  • 采集需要授权的网站,更换IP会导致退出登录

创建粘性会话的API请求示例(通常使用特殊的登录格式):

// 格式: username-session-SESSIONID:password
// SESSIONID — 任意字符串,相同 = 一个IP

proxy = "username-session-abc123:password@gate.proxycove.com:8000"

// 所有带session-abc123的请求在会话期间将获得一个IP
// 对于新IP使用不同的SESSIONID: session-xyz789

每次请求自动轮换

每次新连接到代理服务器时IP地址都会更改。这是住宅代理在不指定会话参数时的标准行为。

何时使用:

  • 无需授权的大规模采集(价格、联系方式、广告)
  • 绕过公共API上的激进速率限制
  • 从10-20次请求后封禁IP的网站收集数据
  • 检查来自不同地区的内容可用性

Python使用示例(每个请求 = 新IP):

import requests

proxy = {
    "http": "http://username:password@gate.proxycove.com:8000",
    "https": "http://username:password@gate.proxycove.com:8000"
}

# 每个请求将获得新IP
for i in range(10):
    response = requests.get("https://api.ipify.org", proxies=proxy)
    print(f"请求 {i+1}, IP: {response.text}")

定时轮换

您以编程方式控制何时更换IP:每N分钟、M次请求后或收到特定错误时。这是通过代理服务API实现的混合方法。

何时使用:

  • 优化流量消耗 - 仅在必要时更换
  • 处理跟踪模式的网站(过于频繁的更换 = 封禁)
  • 在匿名性和会话稳定性之间取得平衡
轮换类型 IP更换频率 任务 流量消耗
粘性会话 5-30分钟 多账号管理、授权
自动轮换 每次请求 数据采集、绕过速率限制 中等
定时轮换 可配置 通用 优化的

代理服务API工作基础

大多数现代代理提供商提供两种管理方式:通过Web面板和通过API。API提供对功能的编程访问:获取代理列表、创建新会话、检查余额、使用统计。

代理服务的典型API方法

虽然每个提供商都有自己的文档,但标准方法通常包括:

  • GET /api/v1/proxy/list — 获取可用代理列表,按国家、类型过滤
  • POST /api/v1/proxy/rotate — 强制更换活动会话中的IP
  • GET /api/v1/account/balance — 检查余额中的流量或资金余额
  • GET /api/v1/stats — 使用统计:流量、请求数量、错误
  • POST /api/v1/session/create — 创建带参数的新粘性会话(国家、城市、持续时间)

身份验证通常通过请求头中的API密钥进行:

curl -X GET "https://api.provider.com/v1/proxy/list?country=US" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json"

响应通常以JSON格式返回:

{
  "status": "success",
  "data": {
    "proxies": [
      {
        "ip": "123.45.67.89",
        "port": 8000,
        "country": "US",
        "city": "New York",
        "protocol": "http",
        "username": "user123",
        "password": "pass456"
      }
    ],
    "total": 150,
    "available": 147
  }
}

通过API管理会话

对于需要控制IP生命周期的任务(多账号管理、账号操作),使用通过API创建命名会话。这允许以编程方式管理数十和数百个隔离的IP地址。

创建带参数会话的示例:

POST /api/v1/session/create
{
  "country": "US",
  "state": "California",
  "session_duration": 600,  // 10分钟
  "session_id": "facebook_account_001"
}

// 响应:
{
  "status": "success",
  "session": {
    "id": "facebook_account_001",
    "proxy": "gate.provider.com:8000",
    "username": "user-session-facebook_account_001",
    "password": "your_password",
    "ip": "45.67.89.123",
    "expires_at": "2024-01-15T15:30:00Z"
  }
}

现在您可以在脚本或反检测浏览器中使用此代理,IP将在10分钟内保持不变。要延长会话,使用相同的session_id发送重复请求。

Python自动化示例:requests、Selenium、Scrapy

Python是数据采集和自动化最流行的语言。让我们看看将API代理轮换与主要工具集成的示例。

requests中的自动代理轮换

requests库用于简单的HTTP请求。为了自动轮换,我们将创建一个包装类,在出错时更换代理:

import requests
import random
import time

class RotatingProxySession:
    def __init__(self, proxy_list):
        """
        proxy_list: 代理数据字典列表
        [{"http": "http://user:pass@ip:port", "https": "..."}]
        """
        self.proxy_list = proxy_list
        self.current_proxy = None
        self.session = requests.Session()
        self.rotate()
    
    def rotate(self):
        """从列表中选择随机代理"""
        self.current_proxy = random.choice(self.proxy_list)
        self.session.proxies.update(self.current_proxy)
        print(f"切换到代理: {self.current_proxy['http']}")
    
    def get(self, url, max_retries=3, **kwargs):
        """出错时自动轮换的GET请求"""
        for attempt in range(max_retries):
            try:
                response = self.session.get(url, timeout=10, **kwargs)
                
                # 如果被封锁 — 更换代理
                if response.status_code in [403, 429, 503]:
                    print(f"收到 {response.status_code},更换代理...")
                    self.rotate()
                    time.sleep(2)
                    continue
                
                return response
                
            except requests.exceptions.ProxyError:
                print(f"代理不工作,尝试 {attempt+1}/{max_retries}")
                self.rotate()
                time.sleep(2)
            
            except requests.exceptions.Timeout:
                print("超时,更换代理...")
                self.rotate()
                time.sleep(2)
        
        raise Exception(f"{max_retries}次尝试后无法执行请求")

# 使用:
proxies = [
    {"http": "http://user1:pass@gate1.com:8000", "https": "http://user1:pass@gate1.com:8000"},
    {"http": "http://user2:pass@gate2.com:8000", "https": "http://user2:pass@gate2.com:8000"},
]

session = RotatingProxySession(proxies)

# 采集Wildberries
for page in range(1, 50):
    url = f"https://www.wildberries.ru/catalog/page={page}"
    response = session.get(url)
    print(f"页面 {page}: {response.status_code}")

与Selenium集成用于浏览器自动化

Selenium用于采集带JavaScript的网站和浏览器中的操作自动化。要更换代理,需要重新创建驱动程序,因为代理设置在初始化时设定:

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

class SeleniumRotatingProxy:
    def __init__(self, proxy_list):
        self.proxy_list = proxy_list
        self.driver = None
        self.current_proxy_index = 0
    
    def create_driver(self):
        """使用当前代理创建新驱动程序"""
        if self.driver:
            self.driver.quit()
        
        proxy = self.proxy_list[self.current_proxy_index]
        
        chrome_options = Options()
        chrome_options.add_argument(f'--proxy-server={proxy}')
        chrome_options.add_argument('--headless')  # 无GUI
        
        self.driver = webdriver.Chrome(options=chrome_options)
        print(f"创建带代理的驱动程序: {proxy}")
    
    def rotate(self):
        """切换到下一个代理"""
        self.current_proxy_index = (self.current_proxy_index + 1) % len(self.proxy_list)
        self.create_driver()
    
    def get_with_retry(self, url, max_retries=3):
        """出错时自动更换代理打开URL"""
        for attempt in range(max_retries):
            try:
                if not self.driver:
                    self.create_driver()
                
                self.driver.get(url)
                
                # 检查封锁(例如,搜索验证码)
                if "captcha" in self.driver.page_source.lower():
                    print("检测到验证码,更换代理...")
                    self.rotate()
                    time.sleep(3)
                    continue
                
                return self.driver.page_source
                
            except Exception as e:
                print(f"错误: {e},更换代理(尝试 {attempt+1})")
                self.rotate()
                time.sleep(3)
        
        raise Exception("无法加载页面")

# 使用:
proxies = [
    "http://user:pass@gate1.com:8000",
    "http://user:pass@gate2.com:8000",
]

bot = SeleniumRotatingProxy(proxies)

# 采集Ozon
for i in range(10):
    html = bot.get_with_retry(f"https://www.ozon.ru/category/page-{i}")
    print(f"获得页面HTML {i},长度: {len(html)}")

bot.driver.quit()

Scrapy与代理轮换中间件

Scrapy — 大规模采集框架。代理轮换通过中间件实现,自动应用于所有请求:

# middlewares.py

import random
from scrapy.exceptions import IgnoreRequest

class RotatingProxyMiddleware:
    def __init__(self, proxy_list):
        self.proxy_list = proxy_list
    
    @classmethod
    def from_crawler(cls, crawler):
        # 从设置获取代理列表
        proxy_list = crawler.settings.getlist('ROTATING_PROXY_LIST')
        return cls(proxy_list)
    
    def process_request(self, request, spider):
        # 为每个请求分配随机代理
        proxy = random.choice(self.proxy_list)
        request.meta['proxy'] = proxy
        spider.logger.info(f'使用代理: {proxy}')
    
    def process_exception(self, request, exception, spider):
        # 代理出错时 — 使用另一个重试
        proxy = random.choice(self.proxy_list)
        spider.logger.warning(f'代理错误,切换到: {proxy}')
        request.meta['proxy'] = proxy
        return request  # 重试请求

# settings.py

DOWNLOADER_MIDDLEWARES = {
    'myproject.middlewares.RotatingProxyMiddleware': 350,
}

ROTATING_PROXY_LIST = [
    'http://user:pass@gate1.com:8000',
    'http://user:pass@gate2.com:8000',
    'http://user:pass@gate3.com:8000',
]

# 出错时重试请求
RETRY_TIMES = 5
RETRY_HTTP_CODES = [403, 429, 500, 502, 503]

现在每个Scrapy请求都会自动从列表中获得随机代理,出错时将使用另一个IP重试。

Node.js自动化:axios、Puppeteer、Playwright

Node.js因其异步性和与浏览器工具的良好集成而在创建采集器和机器人方面很受欢迎。让我们看看主要库中代理轮换的示例。

Axios自动轮换

Axios — HTTP请求库。我们将创建一个带代理池的类,在出错时自动替换:

const axios = require('axios');
const HttpsProxyAgent = require('https-proxy-agent');

class RotatingProxyClient {
  constructor(proxyList) {
    this.proxyList = proxyList;
    this.currentIndex = 0;
  }

  getProxy() {
    const proxy = this.proxyList[this.currentIndex];
    this.currentIndex = (this.currentIndex + 1) % this.proxyList.length;
    return proxy;
  }

  async request(url, options = {}, maxRetries = 3) {
    for (let i = 0; i < maxRetries; i++) {
      const proxy = this.getProxy();
      const agent = new HttpsProxyAgent(proxy);

      try {
        const response = await axios.get(url, {
          ...options,
          httpsAgent: agent,
          timeout: 10000
        });

        // 如果被封锁 — 下次尝试
        if ([403, 429, 503].includes(response.status)) {
          console.log(`状态 ${response.status},更换代理...`);
          continue;
        }

        return response.data;

      } catch (error) {
        console.log(`代理错误 ${proxy}: ${error.message}`);
        if (i === maxRetries - 1) throw error;
      }
    }
  }
}

// 使用:
const proxies = [
  'http://user:pass@gate1.com:8000',
  'http://user:pass@gate2.com:8000',
];

const client = new RotatingProxyClient(proxies);

(async () => {
  for (let page = 1; page <= 20; page++) {
    const data = await client.request(`https://api.example.com/products?page=${page}`);
    console.log(`页面 ${page}: 获得 ${data.length} 个商品`);
  }
})();

Puppeteer代理轮换

Puppeteer控制Chrome浏览器。代理在启动浏览器时设置,因此要更换需要重新创建实例:

const puppeteer = require('puppeteer');

class PuppeteerRotatingProxy {
  constructor(proxyList) {
    this.proxyList = proxyList;
    this.currentIndex = 0;
    this.browser = null;
  }

  async createBrowser() {
    if (this.browser) await this.browser.close();

    const proxy = this.proxyList[this.currentIndex];
    console.log(`启动带代理的浏览器: ${proxy}`);

    this.browser = await puppeteer.launch({
      headless: true,
      args: [`--proxy-server=${proxy}`]
    });
  }

  rotate() {
    this.currentIndex = (this.currentIndex + 1) % this.proxyList.length;
  }

  async scrape(url, maxRetries = 3) {
    for (let i = 0; i < maxRetries; i++) {
      try {
        if (!this.browser) await this.createBrowser();

        const page = await this.browser.newPage();
        
        // 代理认证(如果需要)
        await page.authenticate({
          username: 'your_username',
          password: 'your_password'
        });

        await page.goto(url, { waitUntil: 'networkidle2', timeout: 30000 });

        // 检查验证码
        const content = await page.content();
        if (content.includes('captcha')) {
          console.log('检测到验证码,更换代理...');
          this.rotate();
          await this.createBrowser();
          continue;
        }

        return content;

      } catch (error) {
        console.log(`错误: ${error.message},尝试 ${i+1}`);
        this.rotate();
        await this.createBrowser();
      }
    }
    throw new Error('无法加载页面');
  }
}

// 使用:
const proxies = ['gate1.com:8000', 'gate2.com:8000'];
const scraper = new PuppeteerRotatingProxy(proxies);

(async () => {
  const html = await scraper.scrape('https://www.avito.ru/moskva');
  console.log(`获得HTML长度: ${html.length}`);
  await scraper.browser.close();
})();

Playwright支持轮换

Playwright — Puppeteer的现代替代品,性能更好。代理配置类似:

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

async function scrapeWithRotation(urls, proxyList) {
  let proxyIndex = 0;

  for (const url of urls) {
    const proxy = proxyList[proxyIndex];
    
    const browser = await chromium.launch({
      headless: true,
      proxy: {
        server: proxy,
        username: 'your_user',
        password: 'your_pass'
      }
    });

    const page = await browser.newPage();
    
    try {
      await page.goto(url, { timeout: 30000 });
      const title = await page.title();
      console.log(`${url} → ${title} (代理: ${proxy})`);
    } catch (error) {
      console.log(`${url}错误: ${error.message}`);
    }

    await browser.close();
    
    // 下一个URL使用下一个代理
    proxyIndex = (proxyIndex + 1) % proxyList.length;
  }
}

const urls = [
  'https://www.wildberries.ru',
  'https://www.ozon.ru',
  'https://www.avito.ru'
];

const proxies = [
  'http://gate1.com:8000',
  'http://gate2.com:8000'
];

scrapeWithRotation(urls, proxies);

API与反检测浏览器集成:Dolphin Anty、AdsPower

对于从事多账号管理的流量套利者和SMM专家,在Dolphin Anty或AdsPower中为每个配置文件手动分配代理需要数小时。这些浏览器的API允许自动化创建配置文件和绑定代理。

通过API自动化Dolphin Anty

Dolphin Anty提供本地API(通常在http://localhost:3001/v1.0),通过它可以创建配置文件、分配代理、以编程方式启动浏览器。

Python脚本示例,用于批量创建带唯一代理的配置文件:

import requests
import json

DOLPHIN_API = "http://localhost:3001/v1.0"
API_TOKEN = "your_dolphin_api_token"

# 来自您的提供商的代理列表(通过其API获得)
proxies = [
    {"host": "gate1.com", "port": 8000, "login": "user1", "password": "pass1"},
    {"host": "gate2.com", "port": 8000, "login": "user2", "password": "pass2"},
]

def create_profile_with_proxy(name, proxy):
    """在Dolphin中创建带代理绑定的配置文件"""
    
    payload = {
        "name": name,
        "tags": ["Facebook Ads", "Auto-created"],
        "proxy": {
            "type": "http",  # 或socks5
            "host": proxy["host"],
            "port": proxy["port"],
            "login": proxy["login"],
            "password": proxy["password"]
        },
        "fingerprint": {
            "os": "win",
            "webRTC": {
                "mode": "altered",
                "fillBasedOnIp": True
            },
            "canvas": {
                "mode": "noise"
            }
        }
    }
    
    headers = {
        "Authorization": f"Bearer {API_TOKEN}",
        "Content-Type": "application/json"
    }
    
    response = requests.post(
        f"{DOLPHIN_API}/browser_profiles",
        headers=headers,
        data=json.dumps(payload)
    )
    
    if response.status_code == 200:
        profile = response.json()
        print(f"✓ 创建配置文件: {name}, ID: {profile['id']}")
        return profile['id']
    else:
        print(f"✗ 创建错误 {name}: {response.text}")
        return None

# 创建50个带代理轮换的配置文件
for i in range(50):
    proxy = proxies[i % len(proxies)]  # 循环轮换
    profile_name = f"FB_Account_{i+1:03d}"
    create_profile_with_proxy(profile_name, proxy)

现在您在Dolphin Anty中有50个配置文件,每个都有唯一的浏览器指纹和代理。以编程方式启动配置文件:

def start_profile(profile_id):
    """启动浏览器配置文件"""
    response = requests.get(
        f"{DOLPHIN_API}/browser_profiles/{profile_id}/start",
        headers={"Authorization": f"Bearer {API_TOKEN}"}
    )
    
    if response.status_code == 200:
        data = response.json()
        print(f"配置文件已启动,WebDriver端口: {data['automation']['port']}")
        return data['automation']['port']
    else:
        print(f"启动错误: {response.text}")

# 启动配置文件并通过Selenium控制
port = start_profile("profile_id_here")

from selenium import webdriver
driver = webdriver.Remote(
    command_executor=f'http://127.0.0.1:{port}',
    options=webdriver.ChromeOptions()
)
driver.get("https://facebook.com")

AdsPower自动化

AdsPower也提供本地API。逻辑与Dolphin类似,但端点不同:

import requests

ADSPOWER_API = "http://local.adspower.net:50325/api/v1"

def create_adspower_profile(name, proxy):
    payload = {
        "name": name,
        "group_id": "0",  # 配置文件组ID
        "domain_name": "facebook.com",
        "open_urls": ["https://facebook.com"],
        "repeat_config": ["0"],
        "username": proxy["login"],
        "password": proxy["password"],
        "proxy_type": "http",
        "proxy_host": proxy["host"],
        "proxy_port": proxy["port"],
        "proxy_user": proxy["login"],
        "proxy_password": proxy["password"]
    }
    
    response = requests.post(
        f"{ADSPOWER_API}/user/create",
        json=payload
    )
    
    if response.json()["code"] == 0:
        user_id = response.json()["data"]["id"]
        print(f"✓ 创建AdsPower配置文件: {name}, ID: {user_id}")
        return user_id
    else:
        print(f"✗ 错误: {response.json()['msg']}")

# 创建配置文件
for i, proxy in enumerate(proxies):
    create_adspower_profile(f"TikTok_Account_{i+1}", proxy)

这种自动化在处理数十个账号时至关重要。您无需手动将代理数据复制到每个配置文件,而是运行脚本并在几分钟内获得现成的基础设施。

错误处理和自动故障转移

使用代理时不可避免地会出现以下情况:IP被目标网站封锁、代理服务器无响应、流量用完。正确的错误处理是稳定自动化的关键。

错误类型和处理策略

错误 原因 解决方案
HTTP 403 Forbidden IP在网站黑名单中 更换代理,添加延迟
HTTP 429 Too Many Requests 超过速率限制 更换IP,增加间隔
ProxyError / Timeout 代理服务器无响应 从池中移除,取下一个
407 Proxy Authentication Required 用户名/密码错误 检查凭据,更新
页面上的验证码 网站检测到机器人 更换IP,使用移动代理

实现智能重试系统

我们将创建一个带指数延迟和不工作代理黑名单的系统,而不是简单地重复请求:

import requests
import time
from collections import defaultdict

class SmartProxyRotator:
    def __init__(self, proxy_list):
        self.proxy_list = proxy_list
        self.blacklist = set()  # 不工作的IP
        self.error_count = defaultdict(int)  # 按IP的错误计数器
        self.max_errors = 3  # 3次错误后 — 加入黑名单
    
    def get_working_proxy(self):
        """获取不在黑名单中的代理"""
        available = [p for p in self.proxy_list if p not in self.blacklist]
        if not available:
            # 所有代理都被封 — 清除黑名单
            print("⚠ 所有代理被封锁,重置黑名单")
            self.blacklist.clear()
            self.error_count.clear()
            available = self.proxy_list
        return available[0]
    
    def mark_error(self, proxy):
        """标记代理错误"""
        self.error_count[proxy] += 1
        if self.error_count[proxy] >= self.max_errors:
            self.blacklist.add(proxy)
            print(f"✗ 代理 {proxy} 已添加到黑名单")
    
    def request_with_retry(self, url, max_retries=5):
        """带智能重试的请求"""
        for attempt in range(max_retries):
            proxy = self.get_working_proxy()
            
            try:
                # 指数延迟: 1s, 2s, 4s, 8s...
                if attempt > 0:
                    delay = 2 ** attempt
                    print(f"等待{delay}秒后尝试 {attempt+1}")
                    time.sleep(delay)
                
                response = requests.get(
                    url,
                    proxies={"http": proxy, "https": proxy},
                    timeout=15
                )
                
                # 成功 — 重置错误计数器
                if response.status_code == 200:
                    self.error_count[proxy] = 0
                    return response
                
                # 封锁 — 更换代理
                elif response.status_code in [403, 429]:
                    print(f"状态 {response.status_code},更换代理")
                    self.mark_error(proxy)
                    continue
                
            except requests.exceptions.ProxyError:
                print(f"ProxyError与 {proxy}")
                self.mark_error(proxy)
                
            except requests.exceptions.Timeout:
                print(f"Timeout与 {proxy}")
                self.mark_error(proxy)
        
        raise Exception(f"{max_retries}次尝试后无法执行请求")

# 使用:
proxies = [
    "http://user:pass@gate1.com:8000",
    "http://user:pass@gate2.com:8000",
    "http://user:pass@gate3.com:8000",
]

rotator = SmartProxyRotator(proxies)

for i in range(100):
    try:
        response = rotator.request_with_retry(f"https://api.example.com/data?page={i}")
        print(f"✓ 页面 {i}: {len(response.text)} 字节")
    except Exception as e:
        print(f"✗ 页面{i}严重错误: {e}")

监控和警报

对于生产系统,实时跟踪代理池的健康状况很重要。添加指标日志记录:

import logging
from datetime import datetime

class ProxyMonitor:
    def __init__(self):
        self.stats = {
            "total_requests": 0,
            "successful": 0,
            "failed": 0,
            "proxy_errors": defaultdict(int),
            "start_time": datetime.now()
        }
        
        # 配置日志记录
        logging.basicConfig(
            filename='proxy_rotation.log',
            level=logging.INFO,
            format='%(asctime)s - %(levelname)s - %(message)s'
        )
    
    def log_request(self, proxy, success, error=None):
        self.stats["total_requests"] += 1
        
        if success:
            self.stats["successful"] += 1
            logging.info(f"✓ 成功与 {proxy}")
        else:
            self.stats["failed"] += 1
            self.stats["proxy_errors"][proxy] += 1
            logging.error(f"✗ 错误与 {proxy}: {error}")
    
    def get_report(self):
        uptime = datetime.now() - self.stats["start_time"]
        success_rate = (self.stats["successful"] / self.stats["total_requests"] * 100) if self.stats["total_requests"] > 0 else 0
        
        return f"""
=== 代理轮换报告 ===
运行时间: {uptime}
总请求数: {self.stats["total_requests"]}
成功: {self.stats["successful"]} ({success_rate:.1f}%)
错误: {self.stats["failed"]}

问题代理:
{self._format_errors()}
        """
    
    def _format_errors(self):
        sorted_errors = sorted(
            self.stats["proxy_errors"].items(),
            key=lambda x: x[1],
            reverse=True
        )
        return "\n".join([f"  {proxy}: {count} 个错误" for proxy, count in sorted_errors[:5]])

# 与rotator集成
monitor = ProxyMonitor()

# 在请求循环中:
try:
    response = rotator.request_with_retry(url)
    monitor.log_request(current_proxy, success=True)
except Exception as e:
    monitor.log_request(current_proxy, success=False, error=str(e))

最佳实践和流量消耗优化

为了最大化代理轮换效率并最小化成本,请遵循以下建议:

1. 使用会话而不是每次请求轮换

对于需要多个请求的任务(授权、购物车、表单),使用粘性会话。这将流量消耗减少3-5倍,因为不需要为每个请求建立新连接。

2. 实施智能延迟

在请求之间添加随机延迟(1-3秒)。这模仿人类行为并减少被封锁的机会。对于激进的网站,使用指数延迟。

3. 缓存结果

如果您采集静态数据(产品描述、价格),实施缓存。这将避免重复请求相同的页面并节省流量。

4. 按地理位置分段代理

为不同的任务使用来自不同国家的代理。例如,用于采集俄罗斯网站的俄罗斯IP,用于Facebook Ads的美国IP。这提高了信任度并减少封锁。

5. 监控代理质量

定期检查代理速度和可用性。从池中移除慢速或不稳定的IP。使用监控系统跟踪成功率和响应时间。

流量消耗优化示例

import requests
import time
import hashlib
from functools import lru_cache

class OptimizedProxyScraper:
    def __init__(self, proxy_list, cache_ttl=3600):
        self.proxy_list = proxy_list
        self.current_proxy_index = 0
        self.cache_ttl = cache_ttl  # 缓存生存时间(秒)
        self.request_delays = {
            "default": (1, 3),  # 最小和最大延迟
            "aggressive": (3, 7)  # 对于激进的网站
        }
    
    @lru_cache(maxsize=1000)
    def _cache_key(self, url):
        """为URL创建缓存键"""
        return hashlib.md5(url.encode()).hexdigest()
    
    def get_with_cache(self, url, delay_type="default"):
        """带缓存和智能延迟的请求"""
        cache_key = self._cache_key(url)
        
        # 检查缓存(这里简化,实际中使用Redis或memcached)
        # cached = redis.get(cache_key)
        # if cached:
        #     return cached
        
        # 智能延迟
        min_delay, max_delay = self.request_delays[delay_type]
        delay = random.uniform(min_delay, max_delay)
        time.sleep(delay)
        
        # 请求
        proxy = self.proxy_list[self.current_proxy_index]
        response = requests.get(url, proxies={"http": proxy, "https": proxy})
        
        # 保存到缓存
        # redis.setex(cache_key, self.cache_ttl, response.text)
        
        # 轮换代理
        self.current_proxy_index = (self.current_proxy_index + 1) % len(self.proxy_list)
        
        return response.text

# 使用:
scraper = OptimizedProxyScraper(proxies)

# 采集产品页面(缓存1小时)
for product_id in range(1000):
    url = f"https://shop.com/product/{product_id}"
    html = scraper.get_with_cache(url, delay_type="default")
    # 处理数据...

结论

通过API自动化代理轮换是现代数据采集、流量套利和多账号管理的基础。正确实施的自动化可以:

  • 将数据收集速度提高10-50倍
  • 减少手动工作和人为错误
  • 优化流量消耗并降低成本
  • 提高系统对封锁和错误的抵抗力
  • 允许轻松扩展到数千个账号或请求

关键成功因素:

  1. 选择正确的轮换类型 — 粘性会话用于账号,自动轮换用于采集
  2. 实施强大的错误处理 — 带重试、黑名单和监控
  3. 优化流量 — 缓存、智能延迟、会话
  4. 使用高质量代理 — 来自可靠提供商的住宅或移动IP
  5. 监控和分析 — 跟踪指标并及时响应问题

从本文中的简单示例开始,根据您的任务逐步使其复杂化。测试不同的策略,测量结果并优化。通过正确的方法,代理自动化将成为您业务中强大的工具。

需要可靠的代理用于自动化?

ProxyCove提供带API的住宅和移动代理,用于任何任务:从数据采集到多账号管理。灵活的轮换设置、高速度和24/7支持。

```