一、前言
 在Web爬虫技术中,Selenium作为一款强大的浏览器自动化工具,能够模拟真实用户操作,有效应对JavaScript渲染、Ajax加载等复杂场景。而集成代理服务则能够解决IP限制、地域访问限制等问题。本文将详细介绍如何利用Java+Selenium+快代理实现高效的爬虫系统。
二、Selenium简介
 Selenium是一个用于Web应用程序自动化测试的工具集,它主要用于自动化浏览器操作,可以模拟用户与网页的交互行为,如点击按钮、填写表单、滚动页面等。在爬虫领域,Selenium特别适合处理那些需要JavaScript渲染、需要登录或有反爬措施的网站。
三、环境准备
 JDK1.8
 Maven项目管理
 相关依赖
 <!-- Selenium -->
 <dependency>
     <groupId>org.seleniumhq.selenium</groupId>
     <artifactId>selenium-java</artifactId>
     <version>3.141.59</version>
 </dependency>
 <dependency>
     <groupId>io.github.bonigarcia</groupId>
     <artifactId>webdrivermanager</artifactId>
     <version>5.3.2</version>
 </dependency>
 <!-- Selenium -->
 <dependency>
     <groupId>org.seleniumhq.selenium</groupId>
     <artifactId>selenium-java</artifactId>
     <version>3.141.59</version>
 </dependency>
 <dependency>
     <groupId>io.github.bonigarcia</groupId>
     <artifactId>webdrivermanager</artifactId>
     <version>5.3.2</version>
 </dependency>
 
 四、代码实现
 本系统采用的是工厂模式创建WebDriver实例,这样做的好处主要是可以提供统一的创建方法,不管使用那种浏览器都适用,自由配置。其次就是维护方便,浏览器配置变更只需修改工厂类中的相关方法,扩展性也不错,可以轻松添加新的浏览器支持,比如Opera或者Safari等等。
4.1 创建WebDriver工厂类
 import io.github.bonigarcia.wdm.WebDriverManager;
 import org.openqa.selenium.Proxy;
 import org.openqa.selenium.WebDriver;
 import org.openqa.selenium.chrome.ChromeDriver;
 import org.openqa.selenium.chrome.ChromeOptions;
 import org.openqa.selenium.edge.EdgeDriver;
 import org.openqa.selenium.edge.EdgeOptions;
 import org.openqa.selenium.firefox.FirefoxDriver;
 import org.openqa.selenium.firefox.FirefoxOptions;
 import org.openqa.selenium.remote.CapabilityType;
 import org.openqa.selenium.remote.PageLoadStrategy;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.TimeUnit;
/**
  * WebDriver工厂类,负责创建和配置各种浏览器驱动实例
  * 设计思路:
  * 1. 使用工厂模式统一管理不同浏览器的WebDriver创建逻辑
  * 2. 采用构建器模式(Builder Pattern)使配置更加灵活
  * 3. 封装复杂的浏览器选项设置,简化调用代码
  * 4. 支持多种浏览器类型和代理配置
  * 
  * 好处:
  * 1. 代码复用性高,减少重复代码
  * 2. 配置灵活,通过链式调用设置参数
  * 3. 职责单一,仅负责创建WebDriver
  * 4. 易于扩展,可轻松添加新的浏览器类型支持
  */
 public class WebDriverFactory {
     // 使用SLF4J记录日志,便于问题排查
     private static final Logger log = LoggerFactory.getLogger(WebDriverFactory.class);
     
     // 默认配置,可通过构建器方法修改
     private boolean headless = true;                // 默认无头模式
     private int pageLoadTimeoutSeconds = 30;        // 页面加载超时时间
     private int scriptTimeoutSeconds = 30;          // 脚本执行超时时间
     private int implicitWaitSeconds = 10;           // 隐式等待时间
     
     // 代理配置
     private boolean proxyEnabled = false;           // 是否启用代理
     private String proxyHost;                       // 代理主机地址
     private int proxyPort;                          // 代理端口
     private String proxyUsername;                   // 代理用户名(认证用)
     private String proxyPassword;                   // 代理密码(认证用)
     
     /**
      * 支持的浏览器类型枚举
      * 便于扩展,后续可以增加其他浏览器支持
      */
     public enum BrowserType {
         CHROME, EDGE, FIREFOX
     }
     
     /**
      * 设置是否使用无头模式
      * 无头模式下浏览器不会显示界面,更加节省资源
      * 
      * @param headless true表示使用无头模式,false表示显示浏览器界面
      * @return 当前工厂实例,支持链式调用
      */
     public WebDriverFactory withHeadless(boolean headless) {
         this.headless = headless;
         return this;
     }
     
     /**
      * 设置页面加载超时时间
      * 
      * @param seconds 超时秒数
      * @return 当前工厂实例,支持链式调用
      */
     public WebDriverFactory withPageLoadTimeout(int seconds) {
         this.pageLoadTimeoutSeconds = seconds;
         return this;
     }
     
     /**
      * 设置JavaScript脚本执行超时时间
      * 
      * @param seconds 超时秒数
      * @return 当前工厂实例,支持链式调用
      */
     public WebDriverFactory withScriptTimeout(int seconds) {
         this.scriptTimeoutSeconds = seconds;
         return this;
     }
     
     /**
      * 设置元素查找隐式等待时间
      * 
      * @param seconds 等待秒数
      * @return 当前工厂实例,支持链式调用
      */
     public WebDriverFactory withImplicitWait(int seconds) {
         this.implicitWaitSeconds = seconds;
         return this;
     }
     
     /**
      * 配置代理服务器
      * 
      * @param host 代理主机地址
      * @param port 代理端口
      * @return 当前工厂实例,支持链式调用
      */
     public WebDriverFactory withProxy(String host, int port) {
         this.proxyEnabled = true;
         this.proxyHost = host;
         this.proxyPort = port;
         return this;
     }
     
     /**
      * 配置代理服务器认证信息
      * 
      * @param username 代理用户名
      * @param password 代理密码
      * @return 当前工厂实例,支持链式调用
      */
     public WebDriverFactory withProxyAuth(String username, String password) {
         this.proxyUsername = username;
         this.proxyPassword = password;
         return this;
     }
     
     /**
      * 创建指定类型的WebDriver实例
      * 工厂方法核心,根据指定的浏览器类型创建对应的WebDriver
      * 
      * @param browserType 浏览器类型枚举
      * @return 配置好的WebDriver实例
      */
     public WebDriver createWebDriver(BrowserType browserType) {
         switch (browserType) {
             case CHROME:
                 return createChromeDriver();
             case EDGE:
                 return createEdgeDriver();
             case FIREFOX:
                 return createFirefoxDriver();
             default:
                 // 默认使用Edge浏览器
                 log.info("未指定浏览器类型,默认使用Edge浏览器");
                 return createEdgeDriver();
         }
     }
     
     /**
      * 创建Edge浏览器WebDriver实例
      * 
      * @return 配置好的Edge WebDriver
      */
     private WebDriver createEdgeDriver() {
         // 自动下载与系统浏览器匹配的WebDriver,避免版本不匹配问题
         WebDriverManager.edgedriver().setup();
         
         EdgeOptions options = new EdgeOptions();
         
         // 配置浏览器选项
         Map<String, Object> edgePrefs = new HashMap<>();
         // 禁用自动扩展,减少资源占用和干扰
         edgePrefs.put("useAutomationExtension", false);
         
         // 获取通用浏览器参数
         List<String> args = getCommonBrowserArgs();
         
         Map<String, Object> edgeOptions = new HashMap<>();
         edgeOptions.put("args", args);
         
         // 设置User-Agent,模拟真实浏览器,减少被网站识别为爬虫的可能
         options.setCapability("ms.edge.userAgent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36 Edg/135.0.0.0");
         
         // 设置页面加载策略为NORMAL,确保页面完整加载
         // 可选值:NONE (不等待加载), EAGER (DOM就绪即可), NORMAL (等待完全加载)
         options.setPageLoadStrategy(PageLoadStrategy.NORMAL);
         
         // Edge特有配置
         options.setCapability("ms:edgeChromium", true);
         options.setCapability("ms:edgeOptions", edgeOptions);
         // 使用隐私模式,避免历史记录、cookie等信息的干扰
         options.setCapability("inPrivate", true);
         
         // 配置代理
         configureProxy(options);
         
         // 创建WebDriver实例
         WebDriver driver = new EdgeDriver(options);
         // 配置超时设置
         configureTimeouts(driver);
         
         log.info("Edge WebDriver创建成功");
         return driver;
     }
     
     /**
      * 创建Chrome浏览器WebDriver实例
      * 
      * @return 配置好的Chrome WebDriver
      */
     private WebDriver createChromeDriver() {
         // 自动下载与系统浏览器匹配的WebDriver
         WebDriverManager.chromedriver().setup();
         
         ChromeOptions options = new ChromeOptions();
         
         // 根据配置决定是否使用无头模式
         if (headless) {
             options.addArguments("--headless");
         }
         
         // 添加通用浏览器参数
         for (String arg : getCommonBrowserArgs()) {
             options.addArguments(arg);
         }
         
         // 设置页面加载策略
         options.setPageLoadStrategy(PageLoadStrategy.NORMAL);
         
         // Chrome浏览器特殊处理代理配置
         configureProxyForChrome(options);
         
         // 创建WebDriver实例
         WebDriver driver = new ChromeDriver(options);
         // 配置超时设置
         configureTimeouts(driver);
         
         log.info("Chrome WebDriver创建成功");
         return driver;
     }
     
     /**
      * 创建Firefox浏览器WebDriver实例
      * 
      * @return 配置好的Firefox WebDriver
      */
     private WebDriver createFirefoxDriver() {
         // 自动下载与系统浏览器匹配的WebDriver
         WebDriverManager.firefoxdriver().setup();
         
         FirefoxOptions options = new FirefoxOptions();
         
         // 根据配置决定是否使用无头模式
         if (headless) {
             options.addArguments("--headless");
         }
         
         // 配置代理
         configureProxy(options);
         
         // 创建WebDriver实例
         WebDriver driver = new FirefoxDriver(options);
         // 配置超时设置
         configureTimeouts(driver);
         
         log.info("Firefox WebDriver创建成功");
         return driver;
     }
     
     /**
      * 获取通用浏览器启动参数
      * 这些参数适用于基于Chromium的浏览器(Chrome, Edge)
      * 
      * @return 参数列表
      */
     private List<String> getCommonBrowserArgs() {
         List<String> args = new ArrayList<>();
         
         // 无头模式相关参数
         if (headless) {
             args.add("--headless");  // 不显示浏览器界面
             args.add("--disable-gpu");  // 在某些系统上无头模式需要禁用GPU加速
         }
         
         // 禁用扩展和插件,减少资源占用和干扰
         args.add("--disable-extensions");
         
         // 禁用图片加载,提高性能
         args.add("--blink-settings=imagesEnabled=false");
         
         // 解决在Docker容器中可能出现的共享内存问题
         args.add("--disable-dev-shm-usage");
         
         // 禁用平滑滚动,减少自动滚动问题
         args.add("--disable-smooth-scrolling");
         
         // 设置固定窗口大小,避免响应式变化导致的元素定位问题
         args.add("--window-size=1366,768");
         
         // 禁用站点隔离,减少内存使用
         args.add("--disable-features=site-per-process");
         
         // 禁用默认应用,减少启动时间
         args.add("--disable-default-apps");
         
         // 减少日志输出,提高性能
         args.add("--disable-logging");
         
         // 禁用信息栏,避免干扰
         args.add("--disable-infobars");
         
         // 禁用通知,避免干扰
         args.add("--disable-notifications");
         
         // 添加性能优化参数
         args.add("--disable-web-security");  // 禁用同源策略检查
         args.add("--no-sandbox");  // 禁用沙箱模式,提高性能(注意安全风险)
         args.add("--disable-setuid-sandbox");  // 禁用setuid沙箱,配合--no-sandbox使用
         args.add("--disable-accelerated-2d-canvas");  // 禁用加速2D Canvas,减少GPU使用
         args.add("--disable-crash-reporter");  // 禁用崩溃报告
         args.add("--disable-in-process-stack-traces");  // 禁用进程内堆栈跟踪
         args.add("--disable-breakpad");  // 禁用断点调试
         args.add("--aggressive-cache-discard");  // 积极丢弃缓存,减少内存使用
         args.add("--disable-ipc-flooding-protection");  // 禁用IPC洪水保护
         
         // 限制JavaScript引擎内存使用,防止内存溢出
         args.add("--js-flags=--max-old-space-size=512");
         
         return args;
     }
     
     /**
      * 为浏览器选项配置代理
      * 适用于Edge和Firefox浏览器
      * 
      * @param options 浏览器选项对象
      */
     private void configureProxy(Object options) {
         if (proxyEnabled && proxyHost != null && !proxyHost.isEmpty() && proxyPort > 0) {
             try {
                 // 构建代理URL,处理是否需要认证
                 String proxyUrl;
                 if (proxyUsername != null && !proxyUsername.isEmpty() && proxyPassword != null) {
                     // 带认证的代理格式:http://username:password@host:port
                     proxyUrl = "http://" + proxyUsername + ":" + proxyPassword + "@" + proxyHost + ":" + proxyPort;
                 } else {
                     // 不带认证的代理格式:http://host:port
                     proxyUrl = "http://" + proxyHost + ":" + proxyPort;
                 }
                 
                 // 创建代理对象
                 Proxy proxy = new Proxy();
                 // 同时设置HTTP和HTTPS代理,确保所有请求都通过代理
                 proxy.setHttpProxy(proxyUrl);
                 proxy.setSslProxy(proxyUrl);
                 
                 // 根据浏览器类型设置代理能力
                 if (options instanceof EdgeOptions) {
                     ((EdgeOptions) options).setCapability(CapabilityType.PROXY, proxy);
                 } else if (options instanceof FirefoxOptions) {
                     ((FirefoxOptions) options).setCapability(CapabilityType.PROXY, proxy);
                 }
                 
                 log.info("WebDriver配置了代理: {}", proxyHost + ":" + proxyPort);
             } catch (Exception e) {
                 log.error("配置代理时出错: {}", e.getMessage());
             }
         }
     }
     
     /**
      * 为Chrome浏览器特别配置代理
      * Chrome处理代理的方式与Edge和Firefox略有不同
      * 
      * @param options Chrome浏览器选项对象
      */
     private void configureProxyForChrome(ChromeOptions options) {
         if (proxyEnabled && proxyHost != null && !proxyHost.isEmpty() && proxyPort > 0) {
             try {
                 // 构建代理URL,处理是否需要认证
                 String proxyUrl;
                 if (proxyUsername != null && !proxyUsername.isEmpty() && proxyPassword != null) {
                     // 带认证的代理
                     proxyUrl = "http://" + proxyUsername + ":" + proxyPassword + "@" + proxyHost + ":" + proxyPort;
                 } else {
                     // 不带认证的代理
                     proxyUrl = "http://" + proxyHost + ":" + proxyPort;
                 }
                 
                 // 创建代理对象
                 Proxy proxy = new Proxy();
                 proxy.setHttpProxy(proxyUrl);
                 proxy.setSslProxy(proxyUrl);
                 
                 // 为Chrome设置代理能力
                 options.setCapability(CapabilityType.PROXY, proxy);
                 
                 log.info("Chrome WebDriver配置了代理: {}", proxyHost + ":" + proxyPort);
             } catch (Exception e) {
                 log.error("配置Chrome代理时出错: {}", e.getMessage());
             }
         }
     }
     
     /**
      * 配置WebDriver的各种超时设置
      * 
      * @param driver WebDriver实例
      */
     private void configureTimeouts(WebDriver driver) {
         // 设置页面加载超时时间
         driver.manage().timeouts().pageLoadTimeout(pageLoadTimeoutSeconds, TimeUnit.SECONDS);
         // 设置脚本执行超时时间
         driver.manage().timeouts().setScriptTimeout(scriptTimeoutSeconds, TimeUnit.SECONDS);
         // 设置隐式等待时间,查找元素时使用
         driver.manage().timeouts().implicitlyWait(implicitWaitSeconds, TimeUnit.SECONDS);
         
         log.debug("WebDriver超时配置完成:页面加载={}秒,脚本执行={}秒,隐式等待={}秒",
                 pageLoadTimeoutSeconds, scriptTimeoutSeconds, implicitWaitSeconds);
     }
 }
import io.github.bonigarcia.wdm.WebDriverManager;
 import org.openqa.selenium.Proxy;
 import org.openqa.selenium.WebDriver;
 import org.openqa.selenium.chrome.ChromeDriver;
 import org.openqa.selenium.chrome.ChromeOptions;
 import org.openqa.selenium.edge.EdgeDriver;
 import org.openqa.selenium.edge.EdgeOptions;
 import org.openqa.selenium.firefox.FirefoxDriver;
 import org.openqa.selenium.firefox.FirefoxOptions;
 import org.openqa.selenium.remote.CapabilityType;
 import org.openqa.selenium.remote.PageLoadStrategy;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.TimeUnit;
/**
  * WebDriver工厂类,负责创建和配置各种浏览器驱动实例
  * 设计思路:
  * 1. 使用工厂模式统一管理不同浏览器的WebDriver创建逻辑
  * 2. 采用构建器模式(Builder Pattern)使配置更加灵活
  * 3. 封装复杂的浏览器选项设置,简化调用代码
  * 4. 支持多种浏览器类型和代理配置
  * 
  * 好处:
  * 1. 代码复用性高,减少重复代码
  * 2. 配置灵活,通过链式调用设置参数
  * 3. 职责单一,仅负责创建WebDriver
  * 4. 易于扩展,可轻松添加新的浏览器类型支持
  */
 public class WebDriverFactory {
     // 使用SLF4J记录日志,便于问题排查
     private static final Logger log = LoggerFactory.getLogger(WebDriverFactory.class);
     
     // 默认配置,可通过构建器方法修改
     private boolean headless = true;                // 默认无头模式
     private int pageLoadTimeoutSeconds = 30;        // 页面加载超时时间
     private int scriptTimeoutSeconds = 30;          // 脚本执行超时时间
     private int implicitWaitSeconds = 10;           // 隐式等待时间
     
     // 代理配置
     private boolean proxyEnabled = false;           // 是否启用代理
     private String proxyHost;                       // 代理主机地址
     private int proxyPort;                          // 代理端口
     private String proxyUsername;                   // 代理用户名(认证用)
     private String proxyPassword;                   // 代理密码(认证用)
     
     /**
      * 支持的浏览器类型枚举
      * 便于扩展,后续可以增加其他浏览器支持
      */
     public enum BrowserType {
         CHROME, EDGE, FIREFOX
     }
     
     /**
      * 设置是否使用无头模式
      * 无头模式下浏览器不会显示界面,更加节省资源
      * 
      * @param headless true表示使用无头模式,false表示显示浏览器界面
      * @return 当前工厂实例,支持链式调用
      */
     public WebDriverFactory withHeadless(boolean headless) {
         this.headless = headless;
         return this;
     }
     
     /**
      * 设置页面加载超时时间
      * 
      * @param seconds 超时秒数
      * @return 当前工厂实例,支持链式调用
      */
     public WebDriverFactory withPageLoadTimeout(int seconds) {
         this.pageLoadTimeoutSeconds = seconds;
         return this;
     }
     
     /**
      * 设置JavaScript脚本执行超时时间
      * 
      * @param seconds 超时秒数
      * @return 当前工厂实例,支持链式调用
      */
     public WebDriverFactory withScriptTimeout(int seconds) {
         this.scriptTimeoutSeconds = seconds;
         return this;
     }
     
     /**
      * 设置元素查找隐式等待时间
      * 
      * @param seconds 等待秒数
      * @return 当前工厂实例,支持链式调用
      */
     public WebDriverFactory withImplicitWait(int seconds) {
         this.implicitWaitSeconds = seconds;
         return this;
     }
     
     /**
      * 配置代理服务器
      * 
      * @param host 代理主机地址
      * @param port 代理端口
      * @return 当前工厂实例,支持链式调用
      */
     public WebDriverFactory withProxy(String host, int port) {
         this.proxyEnabled = true;
         this.proxyHost = host;
         this.proxyPort = port;
         return this;
     }
     
     /**
      * 配置代理服务器认证信息
      * 
      * @param username 代理用户名
      * @param password 代理密码
      * @return 当前工厂实例,支持链式调用
      */
     public WebDriverFactory withProxyAuth(String username, String password) {
         this.proxyUsername = username;
         this.proxyPassword = password;
         return this;
     }
     
     /**
      * 创建指定类型的WebDriver实例
      * 工厂方法核心,根据指定的浏览器类型创建对应的WebDriver
      * 
      * @param browserType 浏览器类型枚举
      * @return 配置好的WebDriver实例
      */
     public WebDriver createWebDriver(BrowserType browserType) {
         switch (browserType) {
             case CHROME:
                 return createChromeDriver();
             case EDGE:
                 return createEdgeDriver();
             case FIREFOX:
                 return createFirefoxDriver();
             default:
                 // 默认使用Edge浏览器
                 log.info("未指定浏览器类型,默认使用Edge浏览器");
                 return createEdgeDriver();
         }
     }
     
     /**
      * 创建Edge浏览器WebDriver实例
      * 
      * @return 配置好的Edge WebDriver
      */
     private WebDriver createEdgeDriver() {
         // 自动下载与系统浏览器匹配的WebDriver,避免版本不匹配问题
         WebDriverManager.edgedriver().setup();
         
         EdgeOptions options = new EdgeOptions();
         
         // 配置浏览器选项
         Map<String, Object> edgePrefs = new HashMap<>();
         // 禁用自动扩展,减少资源占用和干扰
         edgePrefs.put("useAutomationExtension", false);
         
         // 获取通用浏览器参数
         List<String> args = getCommonBrowserArgs();
         
         Map<String, Object> edgeOptions = new HashMap<>();
         edgeOptions.put("args", args);
         
         // 设置User-Agent,模拟真实浏览器,减少被网站识别为爬虫的可能
         options.setCapability("ms.edge.userAgent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36 Edg/135.0.0.0");
         
         // 设置页面加载策略为NORMAL,确保页面完整加载
         // 可选值:NONE (不等待加载), EAGER (DOM就绪即可), NORMAL (等待完全加载)
         options.setPageLoadStrategy(PageLoadStrategy.NORMAL);
         
         // Edge特有配置
         options.setCapability("ms:edgeChromium", true);
         options.setCapability("ms:edgeOptions", edgeOptions);
         // 使用隐私模式,避免历史记录、cookie等信息的干扰
         options.setCapability("inPrivate", true);
         
         // 配置代理
         configureProxy(options);
         
         // 创建WebDriver实例
         WebDriver driver = new EdgeDriver(options);
         // 配置超时设置
         configureTimeouts(driver);
         
         log.info("Edge WebDriver创建成功");
         return driver;
     }
     
     /**
      * 创建Chrome浏览器WebDriver实例
      * 
      * @return 配置好的Chrome WebDriver
      */
     private WebDriver createChromeDriver() {
         // 自动下载与系统浏览器匹配的WebDriver
         WebDriverManager.chromedriver().setup();
         
         ChromeOptions options = new ChromeOptions();
         
         // 根据配置决定是否使用无头模式
         if (headless) {
             options.addArguments("--headless");
         }
         
         // 添加通用浏览器参数
         for (String arg : getCommonBrowserArgs()) {
             options.addArguments(arg);
         }
         
         // 设置页面加载策略
         options.setPageLoadStrategy(PageLoadStrategy.NORMAL);
         
         // Chrome浏览器特殊处理代理配置
         configureProxyForChrome(options);
         
         // 创建WebDriver实例
         WebDriver driver = new ChromeDriver(options);
         // 配置超时设置
         configureTimeouts(driver);
         
         log.info("Chrome WebDriver创建成功");
         return driver;
     }
     
     /**
      * 创建Firefox浏览器WebDriver实例
      * 
      * @return 配置好的Firefox WebDriver
      */
     private WebDriver createFirefoxDriver() {
         // 自动下载与系统浏览器匹配的WebDriver
         WebDriverManager.firefoxdriver().setup();
         
         FirefoxOptions options = new FirefoxOptions();
         
         // 根据配置决定是否使用无头模式
         if (headless) {
             options.addArguments("--headless");
         }
         
         // 配置代理
         configureProxy(options);
         
         // 创建WebDriver实例
         WebDriver driver = new FirefoxDriver(options);
         // 配置超时设置
         configureTimeouts(driver);
         
         log.info("Firefox WebDriver创建成功");
         return driver;
     }
     
     /**
      * 获取通用浏览器启动参数
      * 这些参数适用于基于Chromium的浏览器(Chrome, Edge)
      * 
      * @return 参数列表
      */
     private List<String> getCommonBrowserArgs() {
         List<String> args = new ArrayList<>();
         
         // 无头模式相关参数
         if (headless) {
             args.add("--headless");  // 不显示浏览器界面
             args.add("--disable-gpu");  // 在某些系统上无头模式需要禁用GPU加速
         }
         
         // 禁用扩展和插件,减少资源占用和干扰
         args.add("--disable-extensions");
         
         // 禁用图片加载,提高性能
         args.add("--blink-settings=imagesEnabled=false");
         
         // 解决在Docker容器中可能出现的共享内存问题
         args.add("--disable-dev-shm-usage");
         
         // 禁用平滑滚动,减少自动滚动问题
         args.add("--disable-smooth-scrolling");
         
         // 设置固定窗口大小,避免响应式变化导致的元素定位问题
         args.add("--window-size=1366,768");
         
         // 禁用站点隔离,减少内存使用
         args.add("--disable-features=site-per-process");
         
         // 禁用默认应用,减少启动时间
         args.add("--disable-default-apps");
         
         // 减少日志输出,提高性能
         args.add("--disable-logging");
         
         // 禁用信息栏,避免干扰
         args.add("--disable-infobars");
         
         // 禁用通知,避免干扰
         args.add("--disable-notifications");
         
         // 添加性能优化参数
         args.add("--disable-web-security");  // 禁用同源策略检查
         args.add("--no-sandbox");  // 禁用沙箱模式,提高性能(注意安全风险)
         args.add("--disable-setuid-sandbox");  // 禁用setuid沙箱,配合--no-sandbox使用
         args.add("--disable-accelerated-2d-canvas");  // 禁用加速2D Canvas,减少GPU使用
         args.add("--disable-crash-reporter");  // 禁用崩溃报告
         args.add("--disable-in-process-stack-traces");  // 禁用进程内堆栈跟踪
         args.add("--disable-breakpad");  // 禁用断点调试
         args.add("--aggressive-cache-discard");  // 积极丢弃缓存,减少内存使用
         args.add("--disable-ipc-flooding-protection");  // 禁用IPC洪水保护
         
         // 限制JavaScript引擎内存使用,防止内存溢出
         args.add("--js-flags=--max-old-space-size=512");
         
         return args;
     }
     
     /**
      * 为浏览器选项配置代理
      * 适用于Edge和Firefox浏览器
      * 
      * @param options 浏览器选项对象
      */
     private void configureProxy(Object options) {
         if (proxyEnabled && proxyHost != null && !proxyHost.isEmpty() && proxyPort > 0) {
             try {
                 // 构建代理URL,处理是否需要认证
                 String proxyUrl;
                 if (proxyUsername != null && !proxyUsername.isEmpty() && proxyPassword != null) {
                     // 带认证的代理格式:http://username:password@host:port
                     proxyUrl = "http://" + proxyUsername + ":" + proxyPassword + "@" + proxyHost + ":" + proxyPort;
                 } else {
                     // 不带认证的代理格式:http://host:port
                     proxyUrl = "http://" + proxyHost + ":" + proxyPort;
                 }
                 
                 // 创建代理对象
                 Proxy proxy = new Proxy();
                 // 同时设置HTTP和HTTPS代理,确保所有请求都通过代理
                 proxy.setHttpProxy(proxyUrl);
                 proxy.setSslProxy(proxyUrl);
                 
                 // 根据浏览器类型设置代理能力
                 if (options instanceof EdgeOptions) {
                     ((EdgeOptions) options).setCapability(CapabilityType.PROXY, proxy);
                 } else if (options instanceof FirefoxOptions) {
                     ((FirefoxOptions) options).setCapability(CapabilityType.PROXY, proxy);
                 }
                 
                 log.info("WebDriver配置了代理: {}", proxyHost + ":" + proxyPort);
             } catch (Exception e) {
                 log.error("配置代理时出错: {}", e.getMessage());
             }
         }
     }
     
     /**
      * 为Chrome浏览器特别配置代理
      * Chrome处理代理的方式与Edge和Firefox略有不同
      * 
      * @param options Chrome浏览器选项对象
      */
     private void configureProxyForChrome(ChromeOptions options) {
         if (proxyEnabled && proxyHost != null && !proxyHost.isEmpty() && proxyPort > 0) {
             try {
                 // 构建代理URL,处理是否需要认证
                 String proxyUrl;
                 if (proxyUsername != null && !proxyUsername.isEmpty() && proxyPassword != null) {
                     // 带认证的代理
                     proxyUrl = "http://" + proxyUsername + ":" + proxyPassword + "@" + proxyHost + ":" + proxyPort;
                 } else {
                     // 不带认证的代理
                     proxyUrl = "http://" + proxyHost + ":" + proxyPort;
                 }
                 
                 // 创建代理对象
                 Proxy proxy = new Proxy();
                 proxy.setHttpProxy(proxyUrl);
                 proxy.setSslProxy(proxyUrl);
                 
                 // 为Chrome设置代理能力
                 options.setCapability(CapabilityType.PROXY, proxy);
                 
                 log.info("Chrome WebDriver配置了代理: {}", proxyHost + ":" + proxyPort);
             } catch (Exception e) {
                 log.error("配置Chrome代理时出错: {}", e.getMessage());
             }
         }
     }
     
     /**
      * 配置WebDriver的各种超时设置
      * 
      * @param driver WebDriver实例
      */
     private void configureTimeouts(WebDriver driver) {
         // 设置页面加载超时时间
         driver.manage().timeouts().pageLoadTimeout(pageLoadTimeoutSeconds, TimeUnit.SECONDS);
         // 设置脚本执行超时时间
         driver.manage().timeouts().setScriptTimeout(scriptTimeoutSeconds, TimeUnit.SECONDS);
         // 设置隐式等待时间,查找元素时使用
         driver.manage().timeouts().implicitlyWait(implicitWaitSeconds, TimeUnit.SECONDS);
         
         log.debug("WebDriver超时配置完成:页面加载={}秒,脚本执行={}秒,隐式等待={}秒",
                 pageLoadTimeoutSeconds, scriptTimeoutSeconds, implicitWaitSeconds);
     }
 }
4.2 创建爬虫主类
 import org.openqa.selenium.By;
 import org.openqa.selenium.WebDriver;
 import org.openqa.selenium.WebElement;
 import org.openqa.selenium.support.ui.ExpectedConditions;
 import org.openqa.selenium.support.ui.WebDriverWait;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
import java.util.List;
/**
  * Selenium爬虫示例主类
  * 演示如何使用WebDriverFactory创建浏览器实例并进行网页爬取
  */
 public class SeleniumCrawler {
     private static final Logger log = LoggerFactory.getLogger(SeleniumCrawler.class);
     
     public static void main(String[] args) {
         // 推荐使用快代理的隧道代理:https://www.kuaidaili.com/?ref=soi1rkc6rd82
         String proxyHost = "";  // 快代理隧道代理主机
         int proxyPort = 15818;                // 端口,根据实际情况修改
         String proxyUsername = "yourUsername"; // 替换为您的快代理用户名
         String proxyPassword = "yourPassword"; // 替换为您的快代理密码
         
         // 创建WebDriver工厂实例,配置爬虫参数
         // 使用构建器模式,代码可读性强,配置灵活
         WebDriverFactory factory = new WebDriverFactory()
             .withHeadless(false)  // 设置为false可以看到浏览器界面,方便调试
             .withPageLoadTimeout(30)  // 页面加载超时设置为30秒
             .withScriptTimeout(30)    // 脚本执行超时设置为30秒  
             .withImplicitWait(10)     // 查找元素隐式等待10秒
             .withProxy(proxyHost, proxyPort)           // 设置快代理的主机和端口
             .withProxyAuth(proxyUsername, proxyPassword);  // 设置代理认证信息
         
         WebDriver driver = null;
         try {
             // 创建Edge浏览器实例,也可以选择Chrome或Firefox
             log.info("正在初始化WebDriver...");
             driver = factory.createWebDriver(WebDriverFactory.BrowserType.EDGE);
             
             // 开始爬虫任务
             crawlWebsite(driver);
             
         } catch (Exception e) {
             // 异常处理,记录详细错误信息便于排错
             log.error("爬虫执行出错: {}", e.getMessage(), e);
         } finally {
             // 确保WebDriver正确关闭,避免资源泄露
             if (driver != null) {
                 driver.quit();
                 log.info("WebDriver已关闭,爬虫任务结束");
             }
         }
     }
     
     /**
      * 爬虫核心逻辑,可根据实际需求扩展
      * 
      * @param driver 已配置好的WebDriver实例
      * @throws InterruptedException 如果线程休眠被中断
      */
     private static void crawlWebsite(WebDriver driver) throws InterruptedException {
         // 访问目标网站
         log.info("开始访问目标网站");
         driver.get("https://www.baidu.com");
         log.info("网页标题: {}", driver.getTitle());
         
         // 显式等待某个元素出现,确保页面加载完成
         // 比简单的Thread.sleep更智能
         WebDriverWait wait = new WebDriverWait(driver, 10);
         wait.until(ExpectedConditions.presenceOfElementLocated(By.tagName("body")));
         
         // 获取页面内容示例:提取所有链接
         log.info("开始提取页面链接");
         List<WebElement> links = driver.findElements(By.tagName("a"));
         log.info("共发现{}个链接", links.size());
         
         // 处理提取到的链接
         for (WebElement link : links) {
             String text = link.getText().trim();
             String href = link.getAttribute("href");
             // 只记录有效链接
             if (href != null && !href.isEmpty()) {
                 log.info("链接: {} -> {}", text.isEmpty() ? "[无文本]" : text, href);
             }
         }
         
         // 模拟更多爬虫操作,例如点击某个元素、填写表单等
         // 这里作为示例,只是简单等待
         log.info("等待页面进一步处理...");
         Thread.sleep(2000);
         
         // 如果需要,可以继续访问更多页面
         // driver.get("https://www.another-site.com");
         // ...
         
         log.info("爬虫任务完成");
     }
 }
import org.openqa.selenium.By;
 import org.openqa.selenium.WebDriver;
 import org.openqa.selenium.WebElement;
 import org.openqa.selenium.support.ui.ExpectedConditions;
 import org.openqa.selenium.support.ui.WebDriverWait;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
import java.util.List;
/**
  * Selenium爬虫示例主类
  * 演示如何使用WebDriverFactory创建浏览器实例并进行网页爬取
  */
 public class SeleniumCrawler {
     private static final Logger log = LoggerFactory.getLogger(SeleniumCrawler.class);
     
     public static void main(String[] args) {
         // 推荐使用快代理的隧道代理:https://www.kuaidaili.com/?ref=soi1rkc6rd82
         String proxyHost = "";  // 快代理隧道代理主机
         int proxyPort = 15818;                // 端口,根据实际情况修改
         String proxyUsername = "yourUsername"; // 替换为您的快代理用户名
         String proxyPassword = "yourPassword"; // 替换为您的快代理密码
         
         // 创建WebDriver工厂实例,配置爬虫参数
         // 使用构建器模式,代码可读性强,配置灵活
         WebDriverFactory factory = new WebDriverFactory()
             .withHeadless(false)  // 设置为false可以看到浏览器界面,方便调试
             .withPageLoadTimeout(30)  // 页面加载超时设置为30秒
             .withScriptTimeout(30)    // 脚本执行超时设置为30秒  
             .withImplicitWait(10)     // 查找元素隐式等待10秒
             .withProxy(proxyHost, proxyPort)           // 设置快代理的主机和端口
             .withProxyAuth(proxyUsername, proxyPassword);  // 设置代理认证信息
         
         WebDriver driver = null;
         try {
             // 创建Edge浏览器实例,也可以选择Chrome或Firefox
             log.info("正在初始化WebDriver...");
             driver = factory.createWebDriver(WebDriverFactory.BrowserType.EDGE);
             
             // 开始爬虫任务
             crawlWebsite(driver);
             
         } catch (Exception e) {
             // 异常处理,记录详细错误信息便于排错
             log.error("爬虫执行出错: {}", e.getMessage(), e);
         } finally {
             // 确保WebDriver正确关闭,避免资源泄露
             if (driver != null) {
                 driver.quit();
                 log.info("WebDriver已关闭,爬虫任务结束");
             }
         }
     }
     
     /**
      * 爬虫核心逻辑,可根据实际需求扩展
      * 
      * @param driver 已配置好的WebDriver实例
      * @throws InterruptedException 如果线程休眠被中断
      */
     private static void crawlWebsite(WebDriver driver) throws InterruptedException {
         // 访问目标网站
         log.info("开始访问目标网站");
         driver.get("https://www.baidu.com");
         log.info("网页标题: {}", driver.getTitle());
         
         // 显式等待某个元素出现,确保页面加载完成
         // 比简单的Thread.sleep更智能
         WebDriverWait wait = new WebDriverWait(driver, 10);
         wait.until(ExpectedConditions.presenceOfElementLocated(By.tagName("body")));
         
         // 获取页面内容示例:提取所有链接
         log.info("开始提取页面链接");
         List<WebElement> links = driver.findElements(By.tagName("a"));
         log.info("共发现{}个链接", links.size());
         
         // 处理提取到的链接
         for (WebElement link : links) {
             String text = link.getText().trim();
             String href = link.getAttribute("href");
             // 只记录有效链接
             if (href != null && !href.isEmpty()) {
                 log.info("链接: {} -> {}", text.isEmpty() ? "[无文本]" : text, href);
             }
         }
         
         // 模拟更多爬虫操作,例如点击某个元素、填写表单等
         // 这里作为示例,只是简单等待
         log.info("等待页面进一步处理...");
         Thread.sleep(2000);
         
         // 如果需要,可以继续访问更多页面
         // driver.get("https://www.another-site.com");
         // ...
         
         log.info("爬虫任务完成");
     }
 }
4.3 配置代理的注意事项
 在使用代理时,需要注意以下几点:
选择合适的代理类型:隧道代理适合大规模爬虫,普通代理适合小规模测试
 正确配置认证信息:确保用户名和密码正确,特殊字符需要URL编码
 测试代理连通性:使用前先测试代理是否可用
 合理设置请求频率:遵循代理服务商的使用建议,避免触发反爬机制
 注意IP切换时机:适时切换IP,避免同一IP频繁访问目标网站
 六、总结与展望
 本文详细介绍了如何使用Java+Selenium+快代理实现高效的网页爬虫。通过工厂模式和构建器模式的应用,我们实现了一个灵活、可扩展且易于使用的爬虫框架。该框架解决了代理认证配置的难题,优化了浏览器参数设置,提高了爬虫的稳定性和效率。
Selenium与代理服务的结合为我们提供了强大的爬虫能力:Selenium模拟真实用户行为应对JavaScript渲染和复杂交互,而快代理则提供了稳定的IP资源池,有效规避IP封禁和地域限制问题。这种组合特别适合需要处理登录验证、动态加载内容或有反爬措施的网站。
在实际应用中,请务必遵守相关法律法规和网站的使用条款,合理设置爬虫的请求频率和数量,避免对目标网站造成不必要的负担。同时,定期更新Selenium和WebDriver版本,以适应浏览器的更新和网站的变化。
如果你在使用过程中遇到问题,可以参考快代理或查阅Selenium的相关资料。希望本文对你的爬虫开发有所帮助!
最后,随着网站反爬技术的不断进化,爬虫技术也需要持续更新迭代。未来,我们可以考虑结合机器学习技术识别验证码,或通过更智能的策略调整爬取行为,使爬虫更加智能和高效。
欢迎在评论区分享你的使用经验和改进建议!
 ————————————————
                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
                         
 原文链接:https://blog.csdn.net/weixin_66401877/article/details/147825058