HttpClient, Jsoup ve Selenium kullanan Java uygulamalarında proxy kurulumu, proxy host ve portunun ya Java sistem özellikleri üzerinden global olarak ya da her kütüphanenin bağlantı nesnelerinde ayrı ayrı yapılandırılmasını gerektirir; buna çoğu zaman kimlik doğrulama düzenekleri de eklenir.
Java'da proxy temelleri
Proxy sunucuları ağ istekleri için aracı görevi görür ve daha yüksek güvenlik, anonimlik ve coğrafi kısıtlamalı içeriğe erişim gibi avantajlar sağlar. Java'da proxy yapılandırmaları ya tüm Java Virtual Machine (JVM) genelinde ya da tek tek HTTP istemcilerine özel olarak uygulanabilir.
Proxy türleri
- HTTP proxy: HTTP isteklerini (
http://) işler. - HTTPS proxy: HTTPS isteklerini (
https://) işler. Çoğu zaman bir HTTP proxy,CONNECTmetodu aracılığıyla HTTPS isteklerini de işleyebilir. - SOCKS proxy: Yalnızca HTTP/HTTPS değil, çeşitli ağ protokollerini destekler. Daha fazla esneklik sunar, TCP ve UDP trafiğini işleyebilir.
Proxy kimlik doğrulaması
Birçok proxy kimlik doğrulaması (kullanıcı adı/parola) gerektirir. Bu, proxy'nin global olarak mı yoksa istemci başına mı yapılandırıldığına göre farklı biçimlerde ele alınır.
Global proxy kurulumu (Java sistem özellikleri)
Java, tüm java.net bağlantıları için geçerli olan proxy'leri yapılandırmaya yönelik sistem özellikleri sunar; buna HttpURLConnection (Jsoup'un dahili olarak kullandığı) üzerinden yapılan bağlantılar ve varsayılan olarak bu sistem ayarlarını kullanan diğer kütüphaneler de dahildir.
// HTTP proxy'yi ayarla
System.setProperty("http.proxyHost", "proxy.example.com");
System.setProperty("http.proxyPort", "8080");
// HTTPS proxy'yi ayarla (HTTP ile aynı ya da farklı olabilir)
System.setProperty("https.proxyHost", "proxy.example.com");
System.setProperty("https.proxyPort", "8080");
// SOCKS proxy'yi ayarla
System.setProperty("socksProxyHost", "socks.example.com");
System.setProperty("socksProxyPort", "1080");
// Host'ları proxy'den hariç tut (virgülle ayrılmış liste, joker karakterlere izin verilir)
System.setProperty("http.nonProxyHosts", "localhost|127.0.0.1|*.local");
Bu özellikler JVM argümanı olarak da geçirilebilir:
java -Dhttp.proxyHost=proxy.example.com -Dhttp.proxyPort=8080 YourApplication
Global proxy kimlik doğrulaması
Kimlik doğrulaması gerektiren proxy'ler için Java'nın Authenticator sınıfı kullanılabilir. Bu, tüm java.net bağlantıları için varsayılan bir authenticator tanımlar.
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() {
// İsteğin bir proxy için olup olmadığını kontrol et
if (getRequestorType() == RequestorType.PROXY) {
return new PasswordAuthentication(username, password.toCharArray());
}
return null; // Diğer istekler için kimlik doğrulama yok
}
});
}
public static void main(String[] args) {
// Global proxy özelliklerini ayarla
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");
// Authenticator'ı kur
GlobalProxyAuthenticator.setup("proxyuser", "proxypass");
// Bundan sonra HttpURLConnection tabanlı her istek bu proxy'yi ve kimlik bilgilerini kullanmayı dener
// Örnek: Jsoup bunu örtük olarak kullanır.
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 istekleri yapmak için sağlam ve esnek yöntemler sunar ve karmaşık entegrasyonlarda yaygın olarak kullanılır. İstemci örneği başına açık proxy yapılandırmasını destekler.
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. Proxy host'unu tanımla
HttpHost proxy = new HttpHost("proxy.example.com", 8080, "http"); // ya da "https" ya da "socks"
// 2. İsteği proxy ile yapılandır
RequestConfig config = RequestConfig.custom()
.setProxy(proxy)
.build();
// 3. (İsteğe bağlı) Kimlik doğrulamalı proxy için: credentials provider
CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(
new AuthScope(proxy.getHostName(), proxy.getPort()),
new UsernamePasswordCredentials("proxyuser", "proxypass"));
// 4. HttpClient'ı oluştur
CloseableHttpClient httpClient = HttpClients.custom()
.setDefaultRequestConfig(config)
.setDefaultCredentialsProvider(credentialsProvider) // Kimlik doğrulamalı proxy'ler için
.build();
// 5. İsteği çalıştır
HttpGet request = new HttpGet("http://httpbin.org/get");
request.setConfig(config); // İsteğin bu yapılandırmayı kullanmasını garanti et
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. Proxy host'unu tanımla
HttpHost proxy = new HttpHost("http", "proxy.example.com", 8080); // Şema, host, port
// 2. (İsteğe bağlı) Kimlik doğrulamalı proxy için: credentials provider
BasicCredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(
new AuthScope(proxy.getHostName(), proxy.getPort()),
new UsernamePasswordCredentials("proxyuser", "proxypass".toCharArray()));
// 3. HttpClient'ı oluştur
CloseableHttpClient httpClient = HttpClients.custom()
.setProxy(proxy) // Proxy'yi doğrudan istemci builder'ında ayarla
.setDefaultCredentialsProvider(credentialsProvider) // Kimlik doğrulamalı proxy'ler için
.build();
// 4. İsteği çalıştır
HttpGet request = new HttpGet("http://httpbin.org/get");
// Gerekirse istek bazında geçersiz kılmalar için RequestConfig hâlâ kullanılabilir
RequestConfig requestConfig = RequestConfig.custom()
// .setProxy(proxy) // İstek bazında proxy için burada da ayarlanabilir
.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, gerçek dünya HTML'i ile çalışmak için bir Java kütüphanesidir. URL'leri çekmek ve HTML ayrıştırmak için basit bir API sunar. Jsoup'un Connection arayüzü doğrudan proxy yapılandırmasına izin verir.
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 {
// Yöntem 1: proxy(host, port) kullanımı
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");
// Yöntem 2: java.net.Proxy nesnesinin kullanımı
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();
}
// Kimlik doğrulamalı proxy'lerde Jsoup, global Java sistem özelliklerine ve Authenticator'a dayanır.
// Ayrıntılar için "Global proxy kurulumu" bölümüne bakın.
}
}
Jsoup ile kimlik doğrulamalı proxy'ler kullanırken önerilen yaklaşım, "Global proxy kurulumu" bölümünde gösterildiği gibi global Java sistem özelliklerini ve java.net.Authenticator sınıfını yapılandırmaktır. Jsoup'un dahili HttpURLConnection nesnesi bu ayarları otomatik olarak alır.
Selenium WebDriver
Selenium web tarayıcılarını otomatikleştirir. Selenium WebDriver'da proxy yapılandırması genellikle tarayıcıya özel seçenekler üzerinden yapılır.
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 çalıştırılabilir dosyasının yolunu ayarla
// 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 trafiği için
proxy.setSslProxy(proxyAddress); // HTTPS trafiği için (genellikle HTTP ile aynı)
proxy.setSocksProxy(proxyAddress); // SOCKS trafiği için
// proxy.setSocksUsername("socksuser"); // SOCKS5 kimlik doğrulaması için
// proxy.setSocksPassword("sockspass");
ChromeOptions options = new ChromeOptions();
options.setCapability("proxy", proxy);
// options.addArguments("--proxy-server=" + proxyAddress); // Basit HTTP/HTTPS proxy için alternatif
WebDriver driver = new ChromeDriver(options);
try {
driver.get("http://httpbin.org/get");
System.out.println("Page title: " + driver.getTitle());
// Sayfayla diğer etkileşimler...
} 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 çalıştırılabilir dosyasının yolunu ayarla
// 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'da proxy kimlik doğrulaması
Selenium WebDriver, proxy kimlik doğrulamasını (HTTP/HTTPS proxy'leri için kullanıcı adı/parola) doğrudan kendisi işlemez. Yaygın yaklaşımlar şunlardır:
- Tarayıcı eklentileri: Proxy kimlik doğrulamasını işleyen bir tarayıcı eklentisi kullanın. Bu eklentiler
ChromeOptionsveyaFirefoxOptionsüzerinden yüklenebilir. - URL içinde proxy: Bazı HTTP proxy'lerinde kimlik bilgileri proxy URL'sine gömülebilir (örneğin
user:[email protected]:8080), ancak bu her yerde desteklenmez ve güvenli değildir. - SOCKS5 kimlik doğrulaması: Selenium'un
Proxysınıfı, SOCKS5 proxy'leri içinsetSocksUsername()vesetSocksPassword()metotlarını destekler. - Upstream proxy sunucusu: Trafiği, hedef proxy ile kimlik doğrulamasını yöneten başka bir yerel proxy sunucusu (örneğin BrowserMob Proxy) üzerinden yönlendirin.
Proxy kurulum yöntemlerinin karşılaştırması
| Özellik | Java sistem özellikleri (-D) |
Apache HttpClient (4.x/5.x) | Jsoup (.proxy()) |
Selenium WebDriver (Proxy sınıfı) |
|---|---|---|---|---|
| Kapsam | Global (JVM genelinde) | HttpClient örneği başına |
Connection örneği başına |
WebDriver örneği başına |
| Kimlik doğrulama | java.net.Authenticator (global) |
CredentialsProvider (istemci başına) |
java.net.Authenticator (global ise) |
SOCKS5 (setSocksUsername/Password); HTTP/HTTPS genellikle eklenti/harici araçlarla |
| Esneklik | Düşük (tüm java.net bağlantılarını etkiler) |
Yüksek (ince ayarlı kontrol, istek bazında yapılandırma) | Orta (bağlantı başına, ancak kimlik doğrulamada global ayara bağlı) | Yüksek (tarayıcıya özel seçenekler, SOCKS kimlik doğrulaması) |
| Kullanım kolaylığı | Yüksek (basit özellikler) | Orta ila yüksek (daha fazla kod gerektirir) | Yüksek (basit metot çağrıları) | Orta (Proxy nesnesi oluşturmayı ve seçenek ayarlamayı gerektirir) |
| Desteklenen protokoller | HTTP, HTTPS, SOCKS | HTTP, HTTPS, SOCKS | HTTP, HTTPS (HttpURLConnection üzerinden) |
HTTP, HTTPS, SOCKS (tarayıcı yetenekleri) |
| Kullanım senaryoları | Uygulama genelinde basit, tek tip proxy ihtiyaçları | Karmaşık HTTP etkileşimleri, API istemcileri | Web scraping, basit sayfa çekme | Tarayıcı otomasyonu, test, web scraping |
