跳转到内容
Guides 4 分钟阅读 1285 次浏览

Java 代理设置

掌握用于 web scraping 和自动化的 Java 代理配置。本指南涵盖 HttpClient、Jsoup 和 Selenium 应用中的代理设置。

Java 代理设置

为使用 HttpClient、Jsoup 和 Selenium 的 Java 应用配置代理,需要设置代理主机和端口——既可以通过 Java 系统属性进行全局配置,也可以针对各个库的连接对象单独配置,通常还需要包含身份验证的处理方式。

Java 中的代理基础

代理服务器充当网络请求的中间人,可带来更高的安全性、匿名性以及访问受地域限制内容的能力。在 Java 中,代理配置既可以在整个 Java 虚拟机(JVM)范围内生效,也可以只作用于单个 HTTP 客户端。

代理类型

  • HTTP 代理: 处理 HTTP 请求(http://)。
  • HTTPS 代理: 处理 HTTPS 请求(https://)。HTTP 代理通常也可以通过 CONNECT 方法处理 HTTPS 请求。
  • SOCKS 代理: 支持多种网络协议,不限于 HTTP/HTTPS。灵活性更高,可处理 TCP 和 UDP 流量。

代理身份验证

许多代理需要身份验证(用户名/密码)。具体处理方式取决于代理是全局配置还是按客户端配置。

全局代理配置(Java 系统属性)

Java 提供了一组系统属性,用于配置对所有 java.net 连接生效的代理,其中包括由 HttpURLConnection(Jsoup 内部使用)发起的连接,以及默认沿用这些系统设置的其他库。

// 设置 HTTP 代理
System.setProperty("http.proxyHost", "proxy.example.com");
System.setProperty("http.proxyPort", "8080");

// 设置 HTTPS 代理(可与 HTTP 相同,也可不同)
System.setProperty("https.proxyHost", "proxy.example.com");
System.setProperty("https.proxyPort", "8080");

// 设置 SOCKS 代理
System.setProperty("socksProxyHost", "socks.example.com");
System.setProperty("socksProxyPort", "1080");

// 排除不走代理的主机(以逗号分隔的列表,允许使用通配符)
System.setProperty("http.nonProxyHosts", "localhost|127.0.0.1|*.local");

这些属性也可以作为 JVM 参数传入:
java -Dhttp.proxyHost=proxy.example.com -Dhttp.proxyPort=8080 YourApplication

全局代理的身份验证

对于需要身份验证的代理,可以使用 Java 的 Authenticator 类。它会为所有 java.net 连接设置一个默认的验证器。

import java.net.Authenticator;
import java.net.PasswordAuthentication;

public class GlobalProxyAuthenticator {

    public static void setup(String username, String password) {
        Authenticator.setDefault(new Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                // 检查该请求是否针对代理
                if (getRequestorType() == RequestorType.PROXY) {
                    return new PasswordAuthentication(username, password.toCharArray());
                }
                return null; // 其他请求不进行身份验证
            }
        });
    }

    public static void main(String[] args) {
        // 设置全局代理属性
        System.setProperty("http.proxyHost", "authenticated-proxy.example.com");
        System.setProperty("http.proxyPort", "8080");
        System.setProperty("https.proxyHost", "authenticated-proxy.example.com");
        System.setProperty("https.proxyPort", "8080");

        // 配置验证器
        GlobalProxyAuthenticator.setup("proxyuser", "proxypass");

        // 此后,任何基于 HttpURLConnection 的请求都会尝试使用该代理和这组凭据
        // 例如:Jsoup 会隐式使用它。
        try {
            org.jsoup.Connection.Response response = org.jsoup.Jsoup.connect("http://httpbin.org/get")
                    .ignoreContentType(true)
                    .execute();
            System.out.println("Status: " + response.statusCode());
            System.out.println("Body: " + response.body());
        } catch (java.io.IOException e) {
            e.printStackTrace();
        }
    }
}

Apache HttpClient

Apache HttpClient 提供了健壮而灵活的 HTTP 请求方式,广泛用于复杂的集成场景。它支持按客户端实例显式配置代理。

HttpClient 4.x

import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

public class HttpClient4ProxySetup {

    public static void main(String[] args) throws Exception {
        // 1. 定义代理主机
        HttpHost proxy = new HttpHost("proxy.example.com", 8080, "http"); // 或 "https" 或 "socks"

        // 2. 用代理配置请求
        RequestConfig config = RequestConfig.custom()
                .setProxy(proxy)
                .build();

        // 3.(可选)用于需要验证的代理:凭据提供器
        CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
        credentialsProvider.setCredentials(
                new AuthScope(proxy.getHostName(), proxy.getPort()),
                new UsernamePasswordCredentials("proxyuser", "proxypass"));

        // 4. 构建 HttpClient
        CloseableHttpClient httpClient = HttpClients.custom()
                .setDefaultRequestConfig(config)
                .setDefaultCredentialsProvider(credentialsProvider) // 用于需要验证的代理
                .build();

        // 5. 执行请求
        HttpGet request = new HttpGet("http://httpbin.org/get");
        request.setConfig(config); // 确保请求使用该配置

        try (CloseableHttpResponse response = httpClient.execute(request)) {
            System.out.println("Status: " + response.getStatusLine());
            System.out.println("Body: " + EntityUtils.toString(response.getEntity()));
        } finally {
            httpClient.close();
        }
    }
}

HttpClient 5.x

import org.apache.hc.client5.http.auth.AuthScope;
import org.apache.hc.client5.http.auth.UsernamePasswordCredentials;
import org.apache.hc.client5.http.impl.auth.BasicCredentialsProvider;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.client5.http.classic.methods.HttpGet;
import org.apache.hc.client5.http.config.RequestConfig;
import org.apache.hc.core5.http.HttpHost;
import org.apache.hc.core5.http.io.entity.EntityUtils;
import org.apache.hc.core5.http.ClassicHttpResponse;

public class HttpClient5ProxySetup {

    public static void main(String[] args) throws Exception {
        // 1. 定义代理主机
        HttpHost proxy = new HttpHost("http", "proxy.example.com", 8080); // 协议、主机、端口

        // 2.(可选)用于需要验证的代理:凭据提供器
        BasicCredentialsProvider credentialsProvider = new BasicCredentialsProvider();
        credentialsProvider.setCredentials(
                new AuthScope(proxy.getHostName(), proxy.getPort()),
                new UsernamePasswordCredentials("proxyuser", "proxypass".toCharArray()));

        // 3. 构建 HttpClient
        CloseableHttpClient httpClient = HttpClients.custom()
                .setProxy(proxy) // 直接在客户端 builder 上设置代理
                .setDefaultCredentialsProvider(credentialsProvider) // 用于需要验证的代理
                .build();

        // 4. 执行请求
        HttpGet request = new HttpGet("http://httpbin.org/get");

        // 如有需要,仍可用 RequestConfig 做单次请求级别的覆盖
        RequestConfig requestConfig = RequestConfig.custom()
                // .setProxy(proxy) // 也可在此设置单次请求使用的代理
                .build();
        request.setConfig(requestConfig);

        try (CloseableHttpClient client = httpClient) {
            client.execute(request, response -> {
                System.out.println("Status: " + response.getCode());
                System.out.println("Body: " + EntityUtils.toString(response.getEntity()));
                return null;
            });
        }
    }
}

Jsoup

Jsoup 是一个用于处理真实世界 HTML 的 Java 库,提供了抓取 URL 和解析 HTML 的简洁 API。Jsoup 的 Connection 接口允许直接配置代理。

import org.jsoup.Jsoup;
import org.jsoup.Connection;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Proxy;

public class JsoupProxySetup {

    public static void main(String[] args) {
        String url = "http://httpbin.org/get";
        String proxyHost = "proxy.example.com";
        int proxyPort = 8080;

        try {
            // 方法 1:使用 proxy(host, port)
            Connection.Response response1 = Jsoup.connect(url)
                    .proxy(proxyHost, proxyPort)
                    .ignoreContentType(true)
                    .execute();
            System.out.println("Jsoup (Method 1) Status: " + response1.statusCode());
            System.out.println("Jsoup (Method 1) Body: " + response1.body().substring(0, 100) + "...\n");

            // 方法 2:使用 java.net.Proxy 对象
            Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyHost, proxyPort));
            Connection.Response response2 = Jsoup.connect(url)
                    .proxy(proxy)
                    .ignoreContentType(true)
                    .execute();
            System.out.println("Jsoup (Method 2) Status: " + response2.statusCode());
            System.out.println("Jsoup (Method 2) Body: " + response2.body().substring(0, 100) + "...\n");

        } catch (IOException e) {
            System.err.println("Error connecting via Jsoup proxy: " + e.getMessage());
            e.printStackTrace();
        }

        // 对于需要验证的代理,Jsoup 依赖 Java 全局系统属性和 Authenticator。
        // 详见“全局代理配置”一节。
    }
}

在 Jsoup 中使用需要验证的代理时,推荐的做法是按照“全局代理配置”一节所示,配置 Java 全局系统属性和 java.net.Authenticator。Jsoup 内部的 HttpURLConnection 会自动读取这些设置。

Selenium WebDriver

Selenium 用于自动化 Web 浏览器。Selenium WebDriver 的代理配置通常通过各浏览器专属的选项完成。

Chrome WebDriver

import org.openqa.selenium.Proxy;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;

public class SeleniumChromeProxySetup {

    public static void main(String[] args) {
        // 设置 ChromeDriver 可执行文件的路径
        // System.setProperty("webdriver.chrome.driver", "/path/to/chromedriver");

        String proxyHost = "proxy.example.com";
        int proxyPort = 8080;
        String proxyAddress = proxyHost + ":" + proxyPort;

        Proxy proxy = new Proxy();
        proxy.setHttpProxy(proxyAddress); // 用于 HTTP 流量
        proxy.setSslProxy(proxyAddress);  // 用于 HTTPS 流量(通常与 HTTP 相同)
        proxy.setSocksProxy(proxyAddress); // 用于 SOCKS 流量
        // proxy.setSocksUsername("socksuser"); // 用于 SOCKS5 身份验证
        // proxy.setSocksPassword("sockspass");

        ChromeOptions options = new ChromeOptions();
        options.setCapability("proxy", proxy);
        // options.addArguments("--proxy-server=" + proxyAddress); // 简单 HTTP/HTTPS 代理的替代写法

        WebDriver driver = new ChromeDriver(options);

        try {
            driver.get("http://httpbin.org/get");
            System.out.println("Page title: " + driver.getTitle());
            // 后续与页面的交互……
        } finally {
            driver.quit();
        }
    }
}

Firefox WebDriver

import org.openqa.selenium.Proxy;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

public class SeleniumFirefoxProxySetup {

    public static void main(String[] args) {
        // 设置 GeckoDriver 可执行文件的路径
        // System.setProperty("webdriver.gecko.driver", "/path/to/geckodriver");

        String proxyHost = "proxy.example.com";
        int proxyPort = 8080;
        String proxyAddress = proxyHost + ":" + proxyPort;

        Proxy proxy = new Proxy();
        proxy.setHttpProxy(proxyAddress);
        proxy.setSslProxy(proxyAddress);
        proxy.setSocksProxy(proxyAddress);
        // proxy.setSocksUsername("socksuser");
        // proxy.setSocksPassword("sockspass");

        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("proxy", proxy);

        WebDriver driver = new FirefoxDriver(options);

        try {
            driver.get("http://httpbin.org/get");
            System.out.println("Page title: " + driver.getTitle());
        } finally {
            driver.quit();
        }
    }
}

Selenium 中的代理身份验证

Selenium WebDriver 本身并不直接处理代理身份验证(HTTP/HTTPS 代理的用户名/密码)。常见做法包括:

  • 浏览器扩展: 使用能够处理代理身份验证的浏览器扩展。这些扩展可通过 ChromeOptionsFirefoxOptions 加载。
  • URL 中携带代理凭据: 对部分 HTTP 代理,可以把凭据嵌入代理 URL(例如 user:[email protected]:8080),但这并非普遍支持,也不安全。
  • SOCKS5 身份验证: Selenium 的 Proxy 类为 SOCKS5 代理提供 setSocksUsername()setSocksPassword()
  • 上游代理服务器: 将流量转发到另一个本地代理服务器(例如 BrowserMob Proxy),由它负责与目标代理完成身份验证。

各种代理配置方式对比

特性 Java 系统属性(-D Apache HttpClient(4.x/5.x) Jsoup(.proxy() Selenium WebDriver(Proxy 类)
作用范围 全局(整个 JVM) 每个 HttpClient 实例 每个 Connection 实例 每个 WebDriver 实例
身份验证 java.net.Authenticator(全局) CredentialsProvider(按客户端) java.net.Authenticator(若已全局配置) SOCKS5(setSocksUsername/Password);HTTP/HTTPS 通常靠扩展/外部工具
灵活性 低(影响所有 java.net 连接) 高(可精细控制,支持按请求配置) 中(按连接配置,但身份验证依赖全局设置) 高(浏览器专属选项、SOCKS 验证)
易用性 高(属性设置简单) 中到高(需要更多代码) 高(方法调用简单) 中(需创建 Proxy 对象并设置选项)
支持的协议 HTTP、HTTPS、SOCKS HTTP、HTTPS、SOCKS HTTP、HTTPS(通过 HttpURLConnection HTTP、HTTPS、SOCKS(取决于浏览器能力)
适用场景 全应用统一、简单的代理需求 复杂 HTTP 交互、API 客户端 Web scraping、简单页面抓取 浏览器自动化、测试、web scraping
已更新: 03.03.2026
返回分类

试用我们的代理

遍布 100+ 国家的 20,000+ 代理

support_agent
GProxy Support
Usually replies within minutes
Hi there!
Send us a message and we'll reply as soon as possible.