Python Selenium创建带/不带代理的Chrome WebDriver实例时无代理实例加载失败求助
问题描述
使用Python的Selenium创建两个Chrome WebDriver实例,一个带代理,一个不带代理。不带代理的实例打开URL时提示website cannot be reached net::ERR_TUNNEL_CONNECTION_FAILED,已配置独立用户数据目录但问题依旧。
相关代码如下:
代理与无代理实例初始化代码
import os, tempfile from selenium.common.exceptions import TimeoutException from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.common.proxy import Proxy, ProxyType from selenium import webdriver # Set up Selenium with proxy and incognito mode def setup_selenium_with_proxy(proxy): proxy_config = Proxy() proxy_config.proxy_type = ProxyType.MANUAL proxy_config.http_proxy = f"{proxy['ip']}:{proxy['port']}" proxy_config.ssl_proxy = f"{proxy['ip']}:{proxy['port']}" capabilities = webdriver.DesiredCapabilities.CHROME proxy_config.add_to_capabilities(capabilities) options = webdriver.ChromeOptions() options.add_argument("--incognito") options.add_argument("--disable-dev-shm-usage") options.add_argument("--no-sandbox") options.add_argument("--log-level=3") options.add_experimental_option("excludeSwitches", ["enable-automation", "enable-logging"]) # Create a separate user data directory for the proxy browser user_data_dir_proxy = os.path.join(tempfile.gettempdir(), "selenium_proxy_profile") if not os.path.exists(user_data_dir_proxy): os.makedirs(user_data_dir_proxy) options.add_argument(f"--user-data-dir={user_data_dir_proxy}") driver = webdriver.Chrome(options=options, desired_capabilities=capabilities) return driver # Set up Selenium without proxy and incognito mode def setup_selenium_without_proxy(): options = webdriver.ChromeOptions() options.add_argument("--incognito") options.add_argument("--disable-dev-shm-usage") options.add_argument("--no-sandbox") options.add_argument("--log-level=3") options.add_experimental_option("excludeSwitches", ["enable-automation", "enable-logging"]) # Create a separate user data directory for the non-proxy browser user_data_dir_no_proxy = os.path.join(tempfile.gettempdir(), "selenium_no_proxy_profile") if not os.path.exists(user_data_dir_no_proxy): os.makedirs(user_data_dir_no_proxy) options.add_argument(f"--user-data-dir={user_data_dir_no_proxy}") driver = webdriver.Chrome(options=options) return driver
主函数代码
def main(): url = "http://example.com" # Read proxies from 'http.txt' file with open('http.txt', 'r') as file: proxy_list = [{'ip': proxy.split(':')[0], 'port': proxy.split(':')[1].strip()} for proxy in file.readlines()] at_least_one_working_proxy = False proxy_index = 0 while proxy_index < len(proxy_list): proxy = proxy_list[proxy_index] driver = setup_selenium_with_proxy(proxy) driver.set_page_load_timeout(20) try: driver.get(url) # 业务代码 new_driver = setup_selenium_without_proxy() new_driver.set_page_load_timeout(20) except TimeoutException: print(f"Failed to open url using proxy {proxy['ip']}:{proxy['port']} within 20 seconds") except WebDriverException as e: print(f"WebDriverException encountered while using proxy {proxy['ip']}:{proxy['port']}: {e}")
问题原因
- 使用
desired_capabilities配置代理会修改ChromeDriver的全局默认配置,后续创建的无代理实例会继承这些代理设置,即使使用了独立的用户数据目录也无法完全隔离。 - 无代理实例未明确清除代理相关配置,导致Chrome仍然尝试通过之前的代理建立隧道连接。
解决方案
方案1:改用ChromeOptions配置代理(推荐)
放弃使用desired_capabilities,直接通过ChromeOptions的add_argument添加代理参数,避免全局配置污染:
修改setup_selenium_with_proxy函数:
def setup_selenium_with_proxy(proxy): options = webdriver.ChromeOptions() options.add_argument("--incognito") options.add_argument("--disable-dev-shm-usage") options.add_argument("--no-sandbox") options.add_argument("--log-level=3") options.add_experimental_option("excludeSwitches", ["enable-automation", "enable-logging"]) # 通过ChromeOptions直接设置代理 options.add_argument(f"--proxy-server=http://{proxy['ip']}:{proxy['port']}") options.add_argument(f"--proxy-server=https://{proxy['ip']}:{proxy['port']}") # Create a separate user data directory for the proxy browser user_data_dir_proxy = os.path.join(tempfile.gettempdir(), "selenium_proxy_profile") if not os.path.exists(user_data_dir_proxy): os.makedirs(user_data_dir_proxy) options.add_argument(f"--user-data-dir={user_data_dir_proxy}") driver = webdriver.Chrome(options=options) return driver
方案2:在无代理实例中明确禁用代理
在setup_selenium_without_proxy函数中,添加明确禁用代理的参数,覆盖可能的全局配置:
def setup_selenium_without_proxy(): options = webdriver.ChromeOptions() options.add_argument("--incognito") options.add_argument("--disable-dev-shm-usage") options.add_argument("--no-sandbox") options.add_argument("--log-level=3") options.add_experimental_option("excludeSwitches", ["enable-automation", "enable-logging"]) # 明确禁用代理 options.add_argument("--no-proxy-server") options.add_argument("--proxy-server='direct://'") options.add_argument("--proxy-bypass-list=*") # Create a separate user data directory for the non-proxy browser user_data_dir_no_proxy = os.path.join(tempfile.gettempdir(), "selenium_no_proxy_profile") if not os.path.exists(user_data_dir_no_proxy): os.makedirs(user_data_dir_no_proxy) options.add_argument(f"--user-data-dir={user_data_dir_no_proxy}") # 初始化时清除capabilities中的代理设置 capabilities = webdriver.DesiredCapabilities.CHROME.copy() capabilities.pop('proxy', None) driver = webdriver.Chrome(options=options, desired_capabilities=capabilities) return driver
额外注意事项
- 确保在创建新实例前,关闭之前的driver实例(添加
driver.quit()),避免资源占用和配置残留。 - 可以为每个代理实例创建唯一的用户数据目录,避免不同代理之间的配置干扰。
内容的提问来源于stack exchange,提问作者Boundless
相关产品推荐
相关产品推荐

