使用 SeleniumBase 多线程并行驱动 + 独立代理配置的完整实践指南

大杰吖_5294

大杰吖_5294

2026-05-01

325人浏览

原创

使用 SeleniumBase 多线程并行驱动 + 独立代理配置的完整实践指南

本文详解如何在 seleniumbase 中通过多线程为每个 webdriver 实例分配唯一代理(支持带认证的 http/socks 代理),避免代理复用导致 ip 冲突,并确保驱动隔离、资源安全销毁。

本文详解如何在 seleniumbase 中通过多线程为每个 webdriver 实例分配唯一代理(支持带认证的 http/socks 代理),避免代理复用导致 ip 冲突,并确保驱动隔离、资源安全销毁。

在 SeleniumBase 中实现「每线程一驱动一代理」的关键障碍,是其默认代理机制会复用同一个 ZIP 扩展文件(用于注入代理认证凭据),导致多线程下所有 Chrome 实例实际共用首个代理配置。解决方案的核心在于显式启用 multi_proxy=True 参数——它将为每个 get_new_driver() 调用生成唯一命名的代理扩展 ZIP 文件,彻底隔离代理上下文。

以下是一个不依赖 pytest、纯 Python concurrent.futures 的生产级示例,完全适配您提出的两阶段任务流(先并发抓取列表页链接,再销毁旧驱动、按新代理池并发解析商品页):

import concurrent.futures
import time
from seleniumbase import Driver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

# ✅ 阶段1:列表页代理池(每页独立代理)
pool_proxies_for_pages = [
    "user1:pass1@proxy1.example.com:8080",
    "user2:pass2@proxy2.example.com:8080",
    "user3:pass3@proxy3.example.com:8080"
]

# ✅ 阶段2:商品页代理池(与列表页解耦,同样独立)
pool_proxies_for_products = [
    "user4:pass4@proxy4.example.com:8080",
    "user5:pass5@proxy5.example.com:8080",
    "user6:pass6@proxy6.example.com:8080"
]

def parse_list_page(page_index: int, proxy: str) -> list:
    """并发抓取单个列表页的所有商品链接,返回 href 列表"""
    driver = Driver(
        uc=True,
        proxy=proxy,
        multi_proxy=True,  # ? 强制启用多代理隔离!必加!
        agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
        headless=True,  # 生产环境建议启用
        incognito=True
    )
    try:
        url = f"https://www.ebay.com/e/_electronics/shop-all-ebay-refurbished-cell-phones?_pgn={page_index + 1}"
        driver.get(url)

        # 智能等待 + 滚动触发懒加载
        wait = WebDriverWait(driver, 15)
        wait.until(EC.presence_of_element_located((By.TAG_NAME, "body")))
        driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
        time.sleep(3)

        # 提取所有商品链接(更健壮的 XPath)
        links = []
        elements = driver.find_elements(By.XPATH, "//a[contains(@href, '/itm/') and @tabindex='-1']")
        for elem in elements[:20]:  # 限制数量防超时
            href = elem.get_attribute("href")
            if href and "ebay.com/itm/" in href:
                links.append(href)
        return links
    finally:
        driver.quit()  # ✅ 确保驱动及时释放

def parse_product_page(link: str, proxy: str, page_idx: int):
    """使用指定代理解析单个商品页(可扩展业务逻辑)"""
    driver = Driver(
        uc=True,
        proxy=proxy,
        multi_proxy=True,  # ? 同样必须开启
        headless=True,
        incognito=True
    )
    try:
        driver.get(link)
        # 示例:提取标题
        title = driver.find_element(By.TAG_NAME, "h1").text[:100] if driver.find_elements(By.TAG_NAME, "h1") else "N/A"
        print(f"[Page-{page_idx}] Parsed {link[:50]}... → '{title}'")
    except Exception as e:
        print(f"[Error on {link}]: {e}")
    finally:
        driver.quit()

# ? 主流程:两阶段并发执行
if __name__ == "__main__":
    # 阶段1:并发获取所有列表页链接
    print("? Stage 1: Fetching product links from list pages...")
    with concurrent.futures.ThreadPoolExecutor(max_workers=len(pool_proxies_for_pages)) as executor:
        list_futures = [
            executor.submit(parse_list_page, i, pool_proxies_for_pages[i])
            for i in range(len(pool_proxies_for_pages))
        ]
        all_links = []
        for future in concurrent.futures.as_completed(list_futures):
            links = future.result()
            all_links.extend(links)

    print(f"✅ Collected {len(all_links)} product links")

    # 阶段2:销毁旧驱动后,按新代理池并发解析商品页
    print("? Stage 2: Parsing product pages with dedicated proxies...")
    with concurrent.futures.ThreadPoolExecutor(max_workers=len(pool_proxies_for_products)) as executor:
        # 将链接轮询分配给代理(避免某代理过载)
        for idx, link in enumerate(all_links):
            proxy = pool_proxies_for_products[idx % len(pool_proxies_for_products)]
            executor.submit(parse_product_page, link, proxy, idx)

⚠️ 关键注意事项:

  • multi_proxy=True 是硬性要求:缺失该参数将导致所有线程共享同一代理 ZIP,IP 地址必然重复;
  • 代理格式必须规范:user:pass@host:port(HTTP)或 user:pass@host:port(SOCKS5 需额外指定 --proxy-server=socks5://host:port,SeleniumBase v4.19+ 原生支持);
  • 资源清理不可省略:每个 Driver() 实例必须调用 .quit(),否则残留进程会耗尽系统句柄;
  • 避免全局共享状态:切勿在函数外定义 driver 或复用 WebDriverWait 实例,所有对象应在函数内创建;
  • 线程安全增强:若遇到 Chrome failed to start 等竞争错误,可在 Driver() 中添加 disable_gpu=True, no_sandbox=True(仅限 Linux 服务器)。

通过以上结构,您即可实现真正意义上的「每线程专属代理 + 驱动生命周期自治」,完美支撑高并发、高匿名性的网页采集任务。

驱动精灵
驱动精灵

驱动精灵基于驱动之家十余年的专业数据积累,驱动支持度高,已经为数亿用户解决了各种电脑驱动问题、系统故障,是目前有效的驱动软件,有需要的小伙伴快来保存下载体验吧!

下载

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
python打包成可执行文件
python打包成可执行文件

本专题为大家带来python打包成可执行文件相关的文章,大家可以免费的下载体验。

2023.07.20

1811

4

python能做什么
python能做什么

python能做的有:可用于开发基于控制台的应用程序、多媒体部分开发、用于开发基于Web的应用程序、使用python处理数据、系统编程等等。本专题为大家提供python相关的各种文章、以及下载和课程。

2023.07.25

4844

7

format在python中的用法
format在python中的用法

Python中的format是一种字符串格式化方法,用于将变量或值插入到字符串中的占位符位置。通过format方法,我们可以动态地构建字符串,使其包含不同值。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.07.31

1769

3

python教程
python教程

Python已成为一门网红语言,即使是在非编程开发者当中,也掀起了一股学习的热潮。本专题为大家带来python教程的相关文章,大家可以免费体验学习。

2023.08.03

28937

23

python环境变量的配置
python环境变量的配置

Python是一种流行的编程语言,被广泛用于软件开发、数据分析和科学计算等领域。在安装Python之后,我们需要配置环境变量,以便在任何位置都能够访问Python的可执行文件。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.04

3467

5

python eval
python eval

eval函数是Python中一个非常强大的函数,它可以将字符串作为Python代码进行执行,实现动态编程的效果。然而,由于其潜在的安全风险和性能问题,需要谨慎使用。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.04

3467

5

scratch和python区别
scratch和python区别

scratch和python的区别:1、scratch是一种专为初学者设计的图形化编程语言,python是一种文本编程语言;2、scratch使用的是基于积木的编程语法,python采用更加传统的文本编程语法等等。本专题为大家提供scratch和python相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.11

1223

5

python合并两个列表
python合并两个列表

Python是一种强大的编程语言,具有许多方便的功能和工具。在Python中,有多种方法可以合并两个列表。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.10

616

4

python是前端还是后端
python是前端还是后端

Python属于前端也属于后端,其灵活性和丰富的生态系统使得开发人员能够在不同的领域中灵活运用。本专题为大家提供python相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.11

2683

5

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
热门推荐
/
最新课程
phpStudy极速入门视频教程
phpStudy极速入门视频教程

共6课时 | 54.7万人学习

独孤九贱(4)_PHP视频教程
独孤九贱(4)_PHP视频教程

共89课时 | 134.1万人学习