优秀的编程知识分享平台

网站首页 > 技术文章 正文

Java+Selenium+快代理实现高效爬虫

nanyue 2025-08-03 07:06:57 技术文章 3 ℃

一、前言

在 Web 爬虫技术中,Selenium 作为一款强大的浏览器自动化工具,能够模拟真实用户操作,有效应对 JavaScript 渲染、Ajax 加载等复杂场景。而集成代理服务则能够解决 IP 限制、地域访问限制等问题。

本文将详细介绍如何利用 Java+Selenium+快代理实现高效的爬虫系统。

二、Selenium简介

Selenium 是一个用于 Web 应用程序自动化测试的工具集,它主要用于自动化浏览器操作,可以模拟用户与网页的交互行为,如点击按钮、填写表单、滚动页面等。在爬虫领域,Selenium 特别适合处理那些需要 JavaScript 渲染、需要登录或有反爬措施的网站。

三、环境准备

  • o JDK1.8 #技术分享 #掘金
  • o Maven项目管理
  • o 相关依赖
<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;

publicclassWebDriverFactory { privatestaticfinalLoggerlog= LoggerFactory.getLogger(WebDriverFactory.class); privatebooleanheadless=true; privateintpageLoadTimeoutSeconds=30; privateintscriptTimeoutSeconds=30; privateintimplicitWaitSeconds=10; privatebooleanproxyEnabled=false; private String proxyHost; privateint proxyPort; private String proxyUsername; private String proxyPassword; publicenumBrowserType { CHROME, EDGE, FIREFOX } public WebDriverFactory withHeadless(boolean headless) { this.headless = headless; returnthis; } public WebDriverFactory withPageLoadTimeout(int seconds) { this.pageLoadTimeoutSeconds = seconds; returnthis; } public WebDriverFactory withScriptTimeout(int seconds) { this.scriptTimeoutSeconds = seconds; returnthis; } public WebDriverFactory withImplicitWait(int seconds) { this.implicitWaitSeconds = seconds; returnthis; } public WebDriverFactory withProxy(String host, int port) { this.proxyEnabled = true; this.proxyHost = host; this.proxyPort = port; returnthis; } public WebDriverFactory withProxyAuth(String username, String password) { this.proxyUsername = username; this.proxyPassword = password; returnthis; } public WebDriver createWebDriver(BrowserType browserType) { switch (browserType) { case CHROME: return createChromeDriver(); case EDGE: return createEdgeDriver(); case FIREFOX: return createFirefoxDriver(); default: log.info("未指定浏览器类型,默认使用 Edge 浏览器"); return createEdgeDriver(); } } private WebDriver createEdgeDriver() { WebDriverManager.edgedriver().setup(); EdgeOptionsoptions=newEdgeOptions(); Map<String, Object> edgePrefs = newHashMap<>(); edgePrefs.put("useAutomationExtension", false); List<String> args = getCommonBrowserArgs(); Map<String, Object> edgeOptions = newHashMap<>(); edgeOptions.put("args", args); 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"); options.setPageLoadStrategy(PageLoadStrategy.NORMAL); options.setCapability("ms:edgeChromium", true); options.setCapability("ms:edgeOptions", edgeOptions); options.setCapability("inPrivate", true); configureProxy(options); WebDriverdriver=newEdgeDriver(options); configureTimeouts(driver); log.info("Edge WebDriver 创建成功"); return driver; } private WebDriver createChromeDriver() { WebDriverManager.chromedriver().setup(); ChromeOptionsoptions=newChromeOptions(); if (headless) { options.addArguments("--headless"); } for (String arg : getCommonBrowserArgs()) { options.addArguments(arg); } options.setPageLoadStrategy(PageLoadStrategy.NORMAL); configureProxyForChrome(options); WebDriverdriver=newChromeDriver(options); configureTimeouts(driver); log.info("Chrome WebDriver 创建成功"); return driver; } private WebDriver createFirefoxDriver() { WebDriverManager.firefoxdriver().setup(); FirefoxOptionsoptions=newFirefoxOptions(); if (headless) { options.addArguments("--headless"); } configureProxy(options); WebDriverdriver=newFirefoxDriver(options); configureTimeouts(driver); log.info("Firefox WebDriver 创建成功"); return driver; } private List<String> getCommonBrowserArgs() { List<String> args = newArrayList<>(); if (headless) { args.add("--headless"); args.add("--disable-gpu"); } args.add("--disable-extensions"); args.add("--blink-settings=imagesEnabled=false"); 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"); args.add("--disable-accelerated-2d-canvas"); 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"); args.add("--js-flags=--max-old-space-size=512"); return args; } privatevoidconfigureProxy(Object options) { if (proxyEnabled && proxyHost != null && !proxyHost.isEmpty() && proxyPort > 0) { try { String proxyUrl; if (proxyUsername != null && !proxyUsername.isEmpty() && proxyPassword != null) { proxyUrl = "http://" +

} else { proxyUrl = "http://" +

} Proxyproxy=newProxy(); proxy.setHttpProxy(proxyUrl); proxy.setSslProxy(proxyUrl); if (options instanceof EdgeOptions) { ((EdgeOptions) options).setCapability(CapabilityType.PROXY, proxy); } elseif (options instanceof FirefoxOptions) { ((FirefoxOptions) options).setCapability(CapabilityType.PROXY, proxy); } log.info("WebDriver 配置了代理: {}", proxyHost +

} catch (Exception e) { log.error("配置代理时出错: {}", e.getMessage()); } } } privatevoidconfigureProxyForChrome(ChromeOptions options) { if (proxyEnabled && proxyHost != null && !proxyHost.isEmpty() && proxyPort > 0) { try { String proxyUrl; if (proxyUsername != null && !proxyUsername.isEmpty() && proxyPassword != null) { proxyUrl = "http://" +

} else { proxyUrl = "http://" +

} Proxyproxy=newProxy(); proxy.setHttpProxy(proxyUrl); proxy.setSslProxy(proxyUrl); options.setCapability(CapabilityType.PROXY, proxy); log.info("Chrome WebDriver 配置了代理: {}", proxyHost +

} catch (Exception e) { log.error("配置 Chrome 代理时出错: {}", e.getMessage()); } } } privatevoidconfigureTimeouts(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;

publicclassSeleniumCrawler { privatestaticfinalLoggerlog= LoggerFactory.getLogger(SeleniumCrawler.class); publicstaticvoidmain(String[] args) { StringproxyHost=""; intproxyPort=15818; StringproxyUsername="yourUsername"; StringproxyPassword="yourPassword"; WebDriverFactoryfactory=newWebDriverFactory() .withHeadless(false) .withPageLoadTimeout(30) .withScriptTimeout(30) .withImplicitWait(10) .withProxy(proxyHost, proxyPort) .withProxyAuth(proxyUsername, proxyPassword); WebDriverdriver=null; try { log.info("正在初始化 WebDriver..."); driver = factory.createWebDriver(WebDriverFactory.BrowserType.EDGE); crawlWebsite(driver); } catch (Exception e) { log.error("爬虫执行出错: {}", e.getMessage(), e); } finally { if (driver != null) { driver.quit(); log.info("WebDriver 已关闭,爬虫任务结束"); } } } privatestaticvoidcrawlWebsite(WebDriver driver)throws InterruptedException { log.info("开始访问目标网站"); driver.get("https://www.baidu.com"); log.info("网页标题: {}", driver.getTitle()); WebDriverWaitwait=newWebDriverWait(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) { Stringtext= link.getText().trim(); Stringhref= link.getAttribute("href"); if (href != null && !href.isEmpty()) { log.info("链接: {} -> {}", text.isEmpty() ? "[无文本]" : text, href); } } log.info("等待页面进一步处理..."); Thread.sleep(2000); log.info("爬虫任务完成"); } }

4.3 配置代理的注意事项

在使用代理时,需要注意以下几点:

  • o 选择合适的代理类型: 隧道代理适合大规模爬虫,普通代理适合小规模测试
  • o 正确配置认证信息: 确保用户名和密码正确,特殊字符需要URL编码
  • o 测试代理连通性: 使用前先测试代理是否可用
  • o 合理设置请求频率: 遵循代理服务商的使用建议,避免触发反爬机制
  • o 注意IP切换时机: 适时切换IP,避免同一IP频繁访问目标网站

六、总结与展望

本文详细介绍了如何使用 Java+Selenium+快代理实现高效的网页爬虫。通过工厂模式和构建器模式的应用,我们实现了一个灵活、可扩展且易于使用的爬虫框架。该框架解决了代理认证配置的难题,优化了浏览器参数设置,提高了爬虫的稳定性和效率。

Selenium 与代理服务的结合为我们提供了强大的爬虫能力:Selenium 模拟真实用户行为应对 JavaScript 渲染和复杂交互,而快代理则提供了稳定的 IP 资源池,有效规避 IP 封禁和地域限制问题。这种组合特别适合需要处理登录验证、动态加载内容或有反爬措施的网站。

在实际应用中,请务必遵守相关法律法规和网站的使用条款,合理设置爬虫的请求频率和数量,避免对目标网站造成不必要的负担。同时,定期更新 Selenium 和 WebDriver 版本,以适应浏览器的更新和网站的变化。

如果你在使用过程中遇到问题,可以参考快代理或查阅 Selenium 的相关资料。希望本文对你的爬虫开发有所帮助!

最后,随着网站反爬技术的不断进化,爬虫技术也需要持续更新迭代。未来,我们可以考虑结合机器学习技术识别验证码,或通过更智能的策略调整爬取行为,使爬虫更加智能和高效。

Tags:

最近发表
标签列表