Selenium启动Chrome如何配置ip:port:username:password格式带认证代理
问题原因
Chrome 原生启动参数 --proxy-server 仅支持无认证的 ip:port 格式代理,无法直接解析拼接在后面的用户名密码信息,直接传入ip:port:username:password格式的字符串会导致代理连接失败。
另外原代码存在一处明显错误:webdriver.Chrome 第一个参数传入的是导入的pathlib.Path类,并非ChromeDriver可执行文件路径,Selenium 4.6+ 版本已内置驱动自动管理能力,不需要手动传入驱动路径。
修复方案
优先选择CDP(Chrome DevTools Protocol)注入方案,无额外依赖、稳定性高,Chrome 88及以上版本都支持。
- 方案1:CDP注入认证信息(推荐):启动Chrome时仅传入无认证信息的代理地址,通过CDP接口拦截代理认证请求,自动填充用户名密码完成认证
- 方案2:动态生成代理插件(兼容低版本Chrome):如果使用的Chrome版本低于88,可通过动态生成最小化Chrome代理扩展的方式实现认证,启动时自动加载临时生成的插件即可
完整修复后代码
from selenium import webdriver from selenium.webdriver.chrome.options import Options import random import os import tempfile # 读取代理列表 with open('proxy.txt', 'r', encoding='utf-8') as f: # 过滤空行,去掉每行首尾空白字符 proxies = [line.strip() for line in f.readlines() if line.strip()] while True: proxy_str = random.choice(proxies) print('Current Proxy:', proxy_str) # 拆分代理字段,严格按照ip:port:username:password格式拆分 proxy_host, proxy_port, proxy_user, proxy_pass = proxy_str.split(':') chrome_options = Options() # 关闭Chrome自动化控制条提示,可选配置 chrome_options.add_experimental_option('excludeSwitches', ['enable-automation']) chrome_options.add_experimental_option('useAutomationExtension', False) # ---------- 方案1:CDP方式(推荐,Chrome88+可用) ---------- driver = webdriver.Chrome(options=chrome_options) # 配置代理服务器 driver.execute_cdp_cmd("Network.setProxy", { "proxyServer": f"http://{proxy_host}:{proxy_port}", "proxyBypassList": ["localhost", "127.0.0.1"] }) # 开启认证请求拦截 driver.execute_cdp_cmd("Fetch.enable", {"handleAuthRequests": True}) # 定义认证处理逻辑 def handle_auth(event): driver.execute_cdp_cmd("Fetch.continueWithAuth", { "requestId": event["requestId"], "authChallengeResponse": { "response": "ProvideCredentials", "username": proxy_user, "password": proxy_pass } }) # 绑定认证事件 driver.log.add_listener("Fetch.authRequired", handle_auth) # -------------------------------------------------------- # ---------- 方案2:插件方式(低版本Chrome用,注释掉方案1再启用) ---------- # # 创建临时插件目录 # plugin_dir = tempfile.mkdtemp() # # 写manifest.json配置 # manifest_json = """ # { # "version": "1.0.0", # "manifest_version": 2, # "name": "Proxy Auth", # "permissions": [ # "proxy", # "tabs", # "unlimitedStorage", # "storage", # "<all_urls>", # "webRequest", # "webRequestBlocking" # ], # "background": { # "scripts": ["background.js"] # } # } # """ # # 写后台代理逻辑脚本 # background_js = f""" # var config = {{ # mode: "fixed_servers", # rules: {{ # singleProxy: {{ # scheme: "http", # host: "{proxy_host}", # port: parseInt({proxy_port}) # }}, # bypassList: ["localhost"] # }} # }}; # chrome.proxy.settings.set({{value: config, scope: "regular"}}, function() {{}}); # function callbackFn(details) {{ # return {{ # authCredentials: {{ # username: "{proxy_user}", # password: "{proxy_pass}" # }} # }}; # }} # chrome.webRequest.onAuthRequired.addListener( # callbackFn, # {{urls: ["<all_urls>"]}}, # ['blocking'] # ); # """ # with open(os.path.join(plugin_dir, 'manifest.json'), 'w') as f: # f.write(manifest_json) # with open(os.path.join(plugin_dir, 'background.js'), 'w') as f: # f.write(background_js) # # 加载临时插件 # chrome_options.add_argument(f'--load-extension={plugin_dir}') # driver = webdriver.Chrome(options=chrome_options) # ----------------------------------------------------------------------- # 后续业务逻辑写在这里 driver.get('https://httpbin.org/ip') # 可用于测试代理是否生效 # 业务逻辑跑完记得调用driver.quit()关闭实例 # driver.quit()
注意事项
proxy.txt中每行必须严格遵循ip:port:username:password格式,不能存在多余空格、特殊字符,空行会被代码自动过滤- 如果代理是Socks5协议,只需要把
proxyServer对应的http://前缀改成socks5://即可 - 原代码中导入的
lib2to3.pgen2.driver、xml.dom.minidom.Element、re.search等模块均未使用,已在修复代码中移除,减少冗余导入 - 使用临时插件方案时,用完可调用
shutil.rmtree(plugin_dir)删除临时文件,避免垃圾文件堆积 - 业务逻辑执行完成后记得调用
driver.quit()关闭浏览器实例,否则会残留大量Chrome进程占用内存
内容的提问来源于stack exchange,提问作者JDMTOKEN
相关产品推荐
相关产品推荐

