You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Python Selenium中通过插件每5分钟自动切换代理?

在Python Selenium中实现Chrome代理插件定时切换功能

要实现类似Proxy Switcher的定时切换代理功能,需要改造原有的Chrome代理插件,让它支持动态更新代理配置,再结合Python的定时逻辑触发切换。以下是具体实现步骤:

一、改造Chrome代理插件

1. 更新manifest.json

添加runtime权限以支持消息通信,保留原有必要权限:

manifest_json = """
{
    "version": "1.0.0",
    "manifest_version": 2,
    "name": "Dynamic Chrome Proxy",
    "permissions": [
        "proxy",
        "tabs",
        "unlimitedStorage",
        "storage",
        "<all_urls>",
        "webRequest",
        "webRequestBlocking",
        "runtime"
    ],
    "background": {"scripts": ["background.js"]},
    "minimum_chrome_version": "76.0.0"
}
"""

2. 重写background.js

改成支持动态接收代理配置、更新代理设置的逻辑,同时处理认证信息的更新:

background_js = """
// 存储当前代理认证监听器,切换时移除旧监听避免冲突
let authListener = null;

// 设置代理的核心函数
function setProxy(proxyConfig) {
    const config = {
        mode: "fixed_servers",
        rules: {
            singleProxy: {
                scheme: proxyConfig.scheme,
                host: proxyConfig.host,
                port: proxyConfig.port
            },
            bypassList: ["localhost"]
        }
    };

    // 更新代理系统设置
    chrome.proxy.settings.set({value: config, scope: "regular"}, function() {});

    // 移除旧的认证监听器
    if (authListener) {
        chrome.webRequest.onAuthRequired.removeListener(authListener);
    }

    // 代理需要认证时,添加新的监听器
    if (proxyConfig.username && proxyConfig.password) {
        authListener = function callbackFn(details) {
            return {
                authCredentials: {
                    username: proxyConfig.username,
                    password: proxyConfig.password
                }
            };
        };

        chrome.webRequest.onAuthRequired.addListener(
            authListener,
            { urls: ["<all_urls>"] },
            ['blocking']
        );
    }
}

// 监听来自Python的切换指令
chrome.runtime.onMessage.addListener(
    function(request, sender, sendResponse) {
        if (request.action === "switchProxy") {
            setProxy(request.proxy);
            sendResponse({status: "success"});
        }
        return true;
    }
);
"""

二、Python端实现定时切换逻辑

使用Selenium控制Chrome,结合定时任务(此处用time.sleep做简单演示,生产环境可改用schedule库),每次切换时向插件发送消息更新代理:

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

def create_proxy_extension(manifest, background):
    """生成临时Chrome代理插件压缩包"""
    extension_dir = "temp_proxy_extension"
    os.makedirs(extension_dir, exist_ok=True)

    # 写入插件文件
    with open(os.path.join(extension_dir, "manifest.json"), "w") as f:
        f.write(manifest)
    with open(os.path.join(extension_dir, "background.js"), "w") as f:
        f.write(background)

    # 打包为zip格式
    extension_zip = "proxy_extension.zip"
    with zipfile.ZipFile(extension_zip, "w", zipfile.ZIP_DEFLATED) as zf:
        zf.write(os.path.join(extension_dir, "manifest.json"), "manifest.json")
        zf.write(os.path.join(extension_dir, "background.js"), "background.js")
    
    # 清理临时目录
    for file in os.listdir(extension_dir):
        os.remove(os.path.join(extension_dir, file))
    os.rmdir(extension_dir)
    
    return extension_zip

def switch_proxy(driver, proxy):
    """向插件发送消息触发代理切换"""
    response = driver.execute_script("""
        return new Promise((resolve) => {
            chrome.runtime.sendMessage({
                action: "switchProxy",
                proxy: arguments[0]
            }, (response) => {
                resolve(response);
            });
        });
    """, proxy)
    return response

def main():
    # 替换为你的代理列表
    proxy_list = [
        {"scheme": "http", "host": "proxy1.example.com", "port": 8080, "username": "user1", "password": "pass1"},
        {"scheme": "http", "host": "proxy2.example.com", "port": 8080, "username": "user2", "password": "pass2"},
        {"scheme": "http", "host": "proxy3.example.com", "port": 8080, "username": "user3", "password": "pass3"}
    ]

    # 创建代理插件
    extension_zip = create_proxy_extension(manifest_json, background_js)

    # 配置Chrome启动选项
    chrome_options = Options()
    chrome_options.add_extension(extension_zip)
    # 可选:启用无头模式
    # chrome_options.add_argument("--headless=new")

    # 启动Chrome浏览器
    driver = webdriver.Chrome(options=chrome_options)

    try:
        proxy_index = 0
        while True:
            current_proxy = proxy_list[proxy_index]
            print(f"切换到代理: {current_proxy['host']}:{current_proxy['port']}")
            switch_proxy(driver, current_proxy)
            
            # 验证代理切换效果(访问IP查询接口)
            driver.get("https://api.ipify.org")
            print(f"当前IP: {driver.page_source}")
            
            # 停留10秒后切换下一个代理,可根据需求调整时间
            time.sleep(10)
            
            # 循环切换代理列表
            proxy_index = (proxy_index + 1) % len(proxy_list)
    except KeyboardInterrupt:
        print("程序已中断")
    finally:
        # 清理临时文件并关闭浏览器
        os.remove(extension_zip)
        driver.quit()

if __name__ == "__main__":
    # 引入插件配置
    manifest_json = """
    {
        "version": "1.0.0",
        "manifest_version": 2,
        "name": "Dynamic Chrome Proxy",
        "permissions": [
            "proxy",
            "tabs",
            "unlimitedStorage",
            "storage",
            "<all_urls>",
            "webRequest",
            "webRequestBlocking",
            "runtime"
        ],
        "background": {"scripts": ["background.js"]},
        "minimum_chrome_version": "76.0.0"
    }
    """
    background_js = """
    // 存储当前代理认证监听器,切换时移除旧监听避免冲突
    let authListener = null;

    // 设置代理的核心函数
    function setProxy(proxyConfig) {
        const config = {
            mode: "fixed_servers",
            rules: {
                singleProxy: {
                    scheme: proxyConfig.scheme,
                    host: proxyConfig.host,
                    port: proxyConfig.port
                },
                bypassList: ["localhost"]
            }
        };

        // 更新代理系统设置
        chrome.proxy.settings.set({value: config, scope: "regular"}, function() {});

        // 移除旧的认证监听器
        if (authListener) {
            chrome.webRequest.onAuthRequired.removeListener(authListener);
        }

        // 代理需要认证时,添加新的监听器
        if (proxyConfig.username && proxyConfig.password) {
            authListener = function callbackFn(details) {
                return {
                    authCredentials: {
                        username: proxyConfig.username,
                        password: proxyConfig.password
                    }
                };
            };

            chrome.webRequest.onAuthRequired.addListener(
                authListener,
                { urls: ["<all_urls>"] },
                ['blocking']
            );
        }
    }

    // 监听来自Python的切换指令
    chrome.runtime.onMessage.addListener(
        function(request, sender, sendResponse) {
            if (request.action === "switchProxy") {
                setProxy(request.proxy);
                sendResponse({status: "success"});
            }
            return true;
        }
    );
    """
    main()

关键说明

  • 插件通过Chrome的runtime.onMessage接口接收Python端的切换指令,动态更新代理配置
  • 切换代理时会移除旧的认证监听器,避免重复触发认证逻辑
  • Python端使用execute_script调用Chrome扩展的消息API,实现与插件的通信
  • 定时逻辑可替换为schedule库,实现更复杂的定时规则(如特定时段切换)

内容的提问来源于stack exchange,提问作者Nime Molla Shuvo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 00:40:43