跳转到内容

Java 代码示例

以下示例展示如何用 Java 获取并使用短效代理 IP,基于 Java 11+ 内置的 HttpClient

JSON 解析使用 jackson-databind,在 pom.xml 中添加依赖:

<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.17.0</version>
</dependency>

fetch 方法接受一条完整的提取链接——写法 A 直接传入从用户中心【复制链接】得到的地址;写法 BbuildUrl 在代码里按需拼接。

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
public class BeesProxy {
private static final String API_URL = "https://api.beesproxy.com/api/v1/proxies/";
private static final String ORDER_ID = "YOUR_ORDER_ID"; // 用户中心【短效代理】页
private static final String USER_TOKEN = "YOUR_USER_TOKEN"; // 用户中心【总览】页
public record ProxyInfo(String host, String port, String cityCn) {}
/** 写法 B:在代码里拼接参数,需要动态调整 ipNum 时用 */
public static String buildUrl(int ipNum) {
return API_URL
+ "?order_id=" + enc(ORDER_ID)
+ "&user_token=" + enc(USER_TOKEN)
+ "&format=json"
+ "&ip_num=" + ipNum;
}
private static String enc(String v) {
return URLEncoder.encode(v, StandardCharsets.UTF_8);
}
/** 传入一条完整的提取链接(写法 A 直接传复制来的地址) */
public static List<ProxyInfo> fetch(String targetUrl) throws Exception {
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(targetUrl))
.GET()
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
// 出错时 HTTP 状态码同样是 200,必须解析 body 检查 code 字段
JsonNode root = new ObjectMapper().readTree(response.body());
int code = root.path("code").asInt(-1);
if (code != 0) {
throw new RuntimeException("获取代理失败:[" + code + "] " + root.path("message").asText());
}
List<ProxyInfo> proxies = new ArrayList<>();
for (JsonNode item : root.path("result")) {
proxies.add(new ProxyInfo(
item.path("host").asText(),
item.path("port").asText(),
item.path("city_cn").asText()
));
}
return proxies;
}
public static void main(String[] args) throws Exception {
// 写法 A:直接使用从用户中心复制的链接
// List<ProxyInfo> proxies = fetch("https://api.beesproxy.com/api/v1/proxies/?order_id=...&user_token=...");
// 写法 B:代码拼接
List<ProxyInfo> proxies = fetch(buildUrl(5));
for (ProxyInfo p : proxies) {
System.out.println(p.host() + ":" + p.port() + " (" + p.cityCn() + ")");
}
}
}

ip_num 超过订单的 IP 提取数时会被静默截断,代理池不足时也可能少给——不要假设返回条数一定等于请求条数

import java.net.*;
import java.net.http.*;
import java.time.Duration;
import java.util.List;
public class ProxyRequest {
public static String fetchWithProxy(String proxyHost, int proxyPort, String targetUrl) throws Exception {
HttpClient client = HttpClient.newBuilder()
.proxy(ProxySelector.of(new InetSocketAddress(proxyHost, proxyPort)))
.connectTimeout(Duration.ofSeconds(10))
.build();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(targetUrl))
.GET()
.build();
return client.send(request, HttpResponse.BodyHandlers.ofString()).body();
}
public static void main(String[] args) throws Exception {
List<BeesProxy.ProxyInfo> proxies = BeesProxy.fetch(BeesProxy.buildUrl(1));
BeesProxy.ProxyInfo proxy = proxies.get(0);
String result = fetchWithProxy(proxy.host(), Integer.parseInt(proxy.port()), "https://httpbin.org/ip");
System.out.println(result);
}
}

这一步连不上,通常是白名单问题,见 白名单配置

import java.util.List;
public class ProxyRotation {
public static void fetchWithRotation(List<String> urls) throws Exception {
List<BeesProxy.ProxyInfo> proxies = BeesProxy.fetch(BeesProxy.buildUrl(10));
if (proxies.isEmpty()) {
throw new IllegalStateException("代理池暂时没有可用 IP,请稍后重试");
}
for (int i = 0; i < urls.size(); i++) {
BeesProxy.ProxyInfo proxy = proxies.get(i % proxies.size());
try {
ProxyRequest.fetchWithProxy(
proxy.host(),
Integer.parseInt(proxy.port()),
urls.get(i)
);
System.out.println("URL: " + urls.get(i) + " -> OK");
} catch (Exception e) {
System.out.println("URL: " + urls.get(i) + " -> ERROR: " + e.getMessage());
}
}
}
}