Używanie proxy w Kotlin to dziś podstawowa umiejętność dla każdego, kto buduje scrapery, monitory cen, narzędzia SERP lub klientów API ograniczonych regionalnie. Niezależnie od tego, czy piszesz backend na JVM, czy aplikację na Androida z Ktor Client lub OkHttp, trafisz na ten sam problem: docelowe serwery widzą Twój adres IP, klasyfikują go jako ASN centrum danych i po 50-100 żądaniach zwracają 403 lub 429. Proxy residential rozwiązują ten problem, kierując ruch przez adresy przypisane realnym dostawcom internetu. W tym przewodniku pokazuję, jak skonfigurować proxy w Kotlin z Ktor Client i OkHttp, jak zakodować geo-targeting i sesje sticky w nazwie użytkownika ProxyHat, jak uruchomić SOCKS5 i jak wdrożyć wzorce produkcyjne — retries, pooling, TLS i współbieżność z async/awaitAll oraz Semaphore.
Dlaczego używanie proxy w Kotlin wymaga osobnego podejścia
Kotlin sam w sobie nie ma wbudowanego klienta HTTP — korzysta z silników JVM. To oznacza, że konfiguracja proxy zależy od wybranego klienta i silnika. Ktor Client 3 deleguje transport do silników takich jak CIO, OkHttp, Apache lub Java. OkHttp działa natywnie na JVM i Androidzie. W obu przypadkach uwierzytelnianie proxy jest specyficzne dla silnika: CIO nie obsługuje automatycznie nagłówka Proxy-Authorization dla tunelowania CONNECT, OkHttp wymaga Authenticator dla wyzwań 407, a SOCKS5 na JVM korzysta z właściwości systemowych java.net.socks.username i java.net.socks.password zamiast nagłówka Basic.
To rozdrobnienie jest źródłem większości błędów początkujących. Programista wpisuje http://user:pass@gate.proxyhat.com:8080 w Ktorze z silnikiem CIO i dostaje 407, bo CIO nie wysyła automatycznie Proxy-Authorization dla HTTPS. Albo ustawia SOCKS5 z Proxy.Type.SOCKS i nie rozumie, dlaczego serwer odrzuca logowanie — bo JVM czyta dane logowania SOCKS z właściwości systemowych, a nie z URL. Zrozumienie, gdzie dokładnie w JVM następuje uwierzytelnianie proxy, to klucz do stabilnego scrapingu w Kotlin.
Więcej o architekturze proxy i różnicach między residential, datacenter i mobile znajdziesz na stronie web scraping oraz w dokumentacji ProxyHat.
Konfiguracja projektu Kotlin — Ktor Client i OkHttp
Zależności Gradle (Kotlin DSL)
Załóżmy projekt Kotlin/JVM lub Android z Gradle. Poniżej minimalny zestaw zależności dla Ktor Client 3 z silnikiem CIO oraz OkHttp. Wersje dostosuj do swojego projektu — przykłady testowano z Ktor 3.0 i OkHttp 4.12.
// build.gradle.kts
dependencies {
// Ktor Client 3 + silnik CIO
implementation("io.ktor:ktor-client-core:3.0.0")
implementation("io.ktor:ktor-client-cio:3.0.0")
// Opcjonalnie silnik OkHttp dla Ktora
implementation("io.ktor:ktor-client-okhttp:3.0.0")
// Samodzielny OkHttp
implementation("com.squareup.okhttp3:okhttp:4.12.0")
// Logowanie
implementation("ch.qos.logback:logback-classic:1.5.6")
// Coroutines
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.1")
}
Na Androidzie dodaj uprawnienie INTERNET w manifeście i pamiętaj o NetworkSecurityConfig, jeśli używasz cleartext do proxy HTTP (tutaj używamy HTTPS do celów, ale proxy CONNECT tuneluje przez port 8080).
Baseline: OkHttp z java.net.Proxy
Zanim przejdziemy do Ktora, zacznijmy od czystego OkHttp. To najprostszy sposób na proxy z uwierzytelnianiem Basic i jednocześnie punkt odniesienia dla wszystkich innych przykładów.
import okhttp3.*
import java.net.InetSocketAddress
import java.net.Proxy
import java.util.Base64
fun buildOkHttpProxyClient(user: String, pass: String): OkHttpClient {
val proxy = Proxy(Proxy.Type.HTTP, InetSocketAddress("gate.proxyhat.com", 8080))
val basic = Base64.getEncoder().encodeToString("$user:$pass".toByteArray())
return OkHttpClient.Builder()
.proxy(proxy)
.proxyAuthenticator { _, response ->
response.request.newBuilder()
.header("Proxy-Authorization", "Basic $basic")
.build()
}
.connectTimeout(15, java.util.concurrent.TimeUnit.SECONDS)
.readTimeout(30, java.util.concurrent.TimeUnit.SECONDS)
.retryOnConnectionFailure(true)
.build()
}
fun main() {
val client = buildOkHttpProxyClient("user-country-DE-city-berlin", "TWOJE_HASLO")
val req = Request.Builder()
.url("https://api.ipify.org?format=json")
.header("User-Agent", "Mozilla/5.0 (X11; Linux x86_64)")
.build()
client.newCall(req).execute().use { resp ->
println(resp.code)
println(resp.body?.string())
}
}
To działa, ponieważ proxyAuthenticator jest wywoływane, gdy serwer proxy zwraca 407, i dodaje nagłówek Proxy-Authorization: Basic .... OkHttp obsługuje też automatycznie CONNECT dla HTTPS — tunel nawiązuje proxy, a TLS jest kończone u klienta.
Ktor Client z silnikiem OkHttp
Ktor Client 3 może korzystać z silnika OkHttp, co ułatwia proxy, bo delegujemy konfigurację proxy do OkHttpClient.Builder. To najmniej zaskakująca ścieżka w produkcji.
import io.ktor.client.*
import io.ktor.client.engine.okhttp.*
import io.ktor.client.plugins.*
import io.ktor.client.request.*
import io.ktor.client.statement.*
import java.net.InetSocketAddress
import java.net.Proxy
import java.util.Base64
fun buildKtorOkHttp(user: String, pass: String): HttpClient {
val basic = Base64.getEncoder().encodeToString("$user:$pass".toByteArray())
return HttpClient(OkHttp) {
engine {
proxy = Proxy(Proxy.Type.HTTP, InetSocketAddress("gate.proxyhat.com", 8080))
config {
proxyAuthenticator { _, response ->
response.request.newBuilder()
.header("Proxy-Authorization", "Basic $basic")
.build()
}
connectTimeout(15, java.util.concurrent.TimeUnit.SECONDS)
readTimeout(30, java.util.concurrent.TimeUnit.SECONDS)
}
}
defaultRequest {
header("Proxy-Authorization", "Basic $basic")
}
}
}
suspend fun main() {
val client = buildKtorOkHttp("user-country-US", "TWOJE_HASLO")
val body = client.get("https://api.ipify.org?format=json").bodyAsText()
println(body)
client.close()
}
Zwróć uwagę, że Proxy-Authorization dodajemy w defaultRequest oraz w proxyAuthenticator. W Ktorze z silnikiem OkHttp to zabezpieczenie: niektóre żądania mogą nie otrzymać nagłówka z defaultRequest przy pierwszej próbie CONNECT, a proxyAuthenticator gwarantuje obsługę 407. To wzorzec, który stosuje również ProxyHat SDK.
Ktor Client z silnikiem CIO
Silnik CIO to czysto Kotlinowa implementacja bez zależności od OkHttp. Jest lekka, ale proxy auth jest tu bardziej ręczne — CIO nie ma wbudowanego proxyAuthenticator, więc nagłówek Basic musimy wstrzyknąć w defaultRequest. To wystarcza dla HTTP CONNECT proxy z ProxyHat.
import io.ktor.client.*
import io.ktor.client.engine.cio.*
import io.ktor.client.plugins.*
import io.ktor.client.request.*
import io.ktor.client.statement.*
import java.util.Base64
fun buildKtorCio(user: String, pass: String): HttpClient {
val basic = Base64.getEncoder().encodeToString("$user:$pass".toByteArray())
return HttpClient(CIO) {
engine {
proxy = io.ktor.client.engine.ProxyBuilder.http("http://gate.proxyhat.com:8080")
}
defaultRequest {
header("Proxy-Authorization", "Basic $basic")
}
}
}
suspend fun main() {
val client = buildKtorCio("user-country-FR", "TWOJE_HASLO")
println(client.get("https://api.ipify.org?format=json").bodyAsText())
client.close()
}
Jeśli Ktor CIO zwraca 407 dla HTTPS, przełącz się na silnik OkHttp — to najczęstsza rekomendacja z repozytorium Ktor. Więcej o zachowaniu silników znajdziesz w dokumentacji Ktor.
Geo-targeting i sesje sticky w nazwie użytkownika ProxyHat
ProxyHat koduje parametry sesji w nazwie użytkownika, a nie w osobnych nagłówkach czy parametrach URL. To oznacza, że możesz sterować krajem, miastem i identyfikatorem sesji bez zmiany kodu klienta — wystarczy zmienić ciąg znaków w polu user.
Formaty nazwy użytkownika:
user-country-US— USA, losowe miasto, rotacja per-request.user-country-DE-city-berlin— Niemcy, Berlin.user-country-US-session-abc123— sticky sesja z identyfikatoremabc123; ten sam wychodzący IP dla wszystkich żądań.user-country-DE-city-berlin-session-abc123— geo + sticky.
Sticky sesje są kluczowe, gdy cel wymaga ciągłości IP — np. logowanie do platformy społecznościowej, koszyk e-commerce czy paginacja wyników. Rotacja per-request jest lepsza dla masowego scrapingu SERP, gdzie każdy wynik to niezależne żądanie.
import java.util.Base64
object ProxyHatAuth {
fun basicHeader(user: String, pass: String): String {
val raw = "$user:$pass".toByteArray()
return "Basic " + Base64.getEncoder().encodeToString(raw)
}
fun geo(country: String, city: String? = null, session: String? = null): String {
val sb = StringBuilder("user-country-").append(country.uppercase())
if (city != null) sb.append("-city-").append(city.lowercase())
if (session != null) sb.append("-session-").append(session)
return sb.toString()
}
}
fun main() {
val user = ProxyHatAuth.geo("DE", "berlin", session = "order-42")
println(user) // user-country-DE-city-berlin-session-order-42
println(ProxyHatAuth.basicHeader(user, "TWOJE_HASLO"))
}
Pełną listę lokalizacji znajdziesz na stronie lokalizacji ProxyHat, a cennik residential/mobile/datacenter na stronie cennika.
SOCKS5 na porcie 1080 przez właściwości systemowe JVM
SOCKS5 to alternatywa dla HTTP CONNECT. ProxyHat wystawia SOCKS5 na porcie 1080. Na JVM uwierzytelnianie SOCKS5 jest niestandardowe: dane logowania czyta się z właściwości systemowych java.net.socks.username i java.net.socks.password, a nie z nagłówka Basic. To wymaga ustawienia właściwości przed utworzeniem klienta i blokuje jednoczesne używanie różnych logowań SOCKS w jednej JVM.
import io.ktor.client.*
import io.ktor.client.engine.okhttp.*
import io.ktor.client.request.*
import io.ktor.client.statement.*
import java.net.InetSocketAddress
import java.net.Proxy
fun buildSocks5(user: String, pass: String): HttpClient {
// UWAGA: właściwości systemowe są globalne dla całej JVM.
System.setProperty("java.net.socks.username", user)
System.setProperty("java.net.socks.password", pass)
return HttpClient(OkHttp) {
engine {
proxy = Proxy(Proxy.Type.SOCKS, InetSocketAddress("gate.proxyhat.com", 1080))
}
}
}
suspend fun main() {
val client = buildSocks5("user-country-PL-session-socks1", "TWOJE_HASLO")
println(client.get("https://api.ipify.org?format=json").bodyAsText())
client.close()
}
W produkcji SOCKS5 ma sens, gdy potrzebujesz tunelowania dowolnego protokołu TCP, nie tylko HTTP/HTTPS. Dla czystego scrapingu HTTP/HTTPS lepszy jest port 8080 z obsługą 407 przez Authenticator, bo pozwala na wiele równoległych logowań proxy w jednej JVM.
Dlaczego residential proxy są potrzebne dla celów społecznościowych i e-commerce
Witryny e-commerce i platformy społecznościowe inwestują w ochronę botów. Według raportu Imperva Bad Bot Report 2024, ruch automatyczny stanowi blisko połowę całego ruchu w internecie, a zaawansowane boty odpowiadają za ponad jedną trzecią tego ruchu. Dostawcy CDN i ochrony (Cloudflare, Akamai, PerimeterX) klasyfikują adresy IP według ASN i reputacji — adresy z AWS, Google Cloud, Azure czy OVH są domyślnie podejrzane. Proxy residential omijają tę klasyfikację, bo wychodzą z adresów przypisanych dostawcom internetu dla gospodarstw domowych.
W Kotlinie ten problem uderza szczególnie mocno, bo programiści często uruchamiają scrapery na serwerach chmurowych z datacenter IP. Bez proxy residential success rate dla typowej platformy społecznościowej spada poniżej 20% już po pierwszych 100 żądaniach. Z rotacją residential można utrzymać 90%+ success rate przy 5-10 żądaniach na sekundę na sesję.
Współbieżność z async/awaitAll i Semaphore
Poniżej kompletny przykład scrapingu SERP z rotacją per-request, ograniczeniem współbieżności przez Semaphore i obsługą błędów. To wzorzec, którego używamy w produkcji dla monitorowania wyników wyszukiwania — więcej przypadków użycia na stronie SERP tracking.
import io.ktor.client.*
import io.ktor.client.engine.okhttp.*
import io.ktor.client.plugins.*
import io.ktor.client.request.*
import io.ktor.client.statement.*
import kotlinx.coroutines.*
import kotlinx.coroutines.sync.Semaphore
import kotlinx.coroutines.sync.withPermit
import java.net.InetSocketAddress
import java.net.Proxy
import java.util.Base64
import kotlin.random.Random
val COUNTRIES = listOf("US", "DE", "FR", "GB", "PL")
fun buildRotatingClient(pass: String): HttpClient {
return HttpClient(OkHttp) {
engine {
proxy = Proxy(Proxy.Type.HTTP, InetSocketAddress("gate.proxyhat.com", 8080))
config {
connectTimeout(15, java.util.concurrent.TimeUnit.SECONDS)
readTimeout(30, java.util.concurrent.TimeUnit.SECONDS)
}
}
}
}
suspend fun fetchOne(
client: HttpClient,
pass: String,
query: String,
sem: Semaphore
): String = sem.withPermit {
val country = COUNTRIES[Random.nextInt(COUNTRIES.size)]
val user = "user-country-$country-session-${System.currentTimeMillis()}-${Random.nextInt(9999)}"
val basic = "Basic " + Base64.getEncoder().encodeToString("$user:$pass".toByteArray())
withContext(Dispatchers.IO) {
try {
val resp = client.get("https://www.google.com/search?q=${java.net.URLEncoder.encode(query, "UTF-8")}") {
header("Proxy-Authorization", basic)
header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64)")
header("Accept-Language", "en-US,en;q=0.9")
}
if (resp.status.value in 200..299) {
resp.bodyAsText().take(120)
} else {
"ERR ${resp.status.value}"
}
} catch (e: Exception) {
"EXC ${e.message}"
}
}
}
suspend fun main() = coroutineScope {
val pass = System.getenv("PROXYHAT_PASS") ?: "TWOJE_HASLO"
val queries = (1..200).map { "kotlin proxy example $it" }
val sem = Semaphore(20) // maks. 20 równoległych żądań
val client = buildRotatingClient(pass)
val results = queries.map { q ->
async { fetchOne(client, pass, q, sem) }
}.awaitAll()
val ok = results.count { it.startsWith("ERR").not() && it.startsWith("EXC").not() }
println("Success: $ok / ${queries.size} (${ok * 100 / queries.size}%)")
client.close()
}
Kluczowe elementy tego wzorca:
- Semaphore(20) ogranicza współbieżność — 20 to bezpieczny próg dla jednej sesji proxy residential; więcej wymaga puli sesji.
- Rotacja per-request: każde żądanie ma unikalny
session-..., więc ProxyHat przydziela nowy IP. - Geo-losowanie rozkłada ryzyko blokady regionalnej.
- try/catch w
fetchOneizoluje błędy pojedynczego żądania. - Dispatchers.IO dla operacji blokujących.
Wzmacnianie produkcyjne — 407, retries, pooling, TLS
OkHttp Authenticator dla 407
Niektóre proxy zwracają 407 dopiero po pierwszym żądaniu bez nagłówka. Authenticator w OkHttp jest wywoływany automatycznie i dodaje nagłówek przy ponownej próbie. To bardziej niezawodne niż dodawanie nagłówka tylko w defaultRequest.
import okhttp3.*
import java.net.InetSocketAddress
import java.net.Proxy
import java.util.Base64
fun hardenedOkHttp(user: String, pass: String): OkHttpClient {
val basic = "Basic " + Base64.getEncoder().encodeToString("$user:$pass".toByteArray())
return OkHttpClient.Builder()
.proxy(Proxy(Proxy.Type.HTTP, InetSocketAddress("gate.proxyhat.com", 8080)))
.proxyAuthenticator { _, response ->
// Limit ponowień, żeby uniknąć pętli 407
if (response.priorResponse != null) null
else response.request.newBuilder()
.header("Proxy-Authorization", basic)
.build()
}
.connectTimeout(10, java.util.concurrent.TimeUnit.SECONDS)
.readTimeout(30, java.util.concurrent.TimeUnit.SECONDS)
.writeTimeout(15, java.util.concurrent.TimeUnit.SECONDS)
.retryOnConnectionFailure(true)
.connectionPool(ConnectionPool(50, 5, java.util.concurrent.TimeUnit.MINUTES))
.build()
}
Sprawdzenie response.priorResponse != null zapobiega nieskończonej pętli 407 — jeśli serwer proxy nadal odrzuca po pierwszej ponowiej próbie, przerywamy.
Retries z backoffem w Kotlinie
Do scrapingu produkcyjnego używaj wykładniczego backoffu z jitterem. Poniżej pomocnicza funkcja retry dla coroutine.
import kotlin.math.min
import kotlin.random.Random
import kotlinx.coroutines.delay
suspend fun <T> retryWithBackoff(
maxAttempts: Int = 4,
baseMs: Long = 500,
factor: Double = 2.0,
block: suspend (attempt: Int) -> T
): T {
var lastError: Throwable? = null
for (attempt in 1..maxAttempts) {
try {
return block(attempt)
} catch (e: Exception) {
lastError = e
if (attempt == maxAttempts) break
val sleep = min(baseMs * Math.pow(factor, attempt - 1.0).toLong(), 10_000L)
val jitter = Random.nextLong(0, sleep / 2 + 1)
delay(sleep + jitter)
}
}
throw lastError ?: RuntimeException("retry failed")
}
// Użycie:
// val body = retryWithBackoff { attempt -> client.get(url).bodyAsText() }
TLS i Android NetworkSecurityConfig
Na Androidzie od API 28 (Android 9) cleartext jest domyślnie zablokowany. Proxy HTTP CONNECT tuneluje TLS do celu, więc sam ruch do proxy jest cleartext tylko na poziomie komendy CONNECT — to jest akceptowalne, ale jeśli wolisz, użyj SOCKS5 lub skonfiguruj network_security_config.xml z domeną wyjątku dla proxy.
<!-- res/xml/network_security_config.xml -->
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="false">gate.proxyhat.com</domain>
</domain-config>
</network-security-config>
I dodaj w manifeście:
<application
android:networkSecurityConfig="@xml/network_security_config"
...>
Dla TLS do celów OkHttp i Ktor używają domyślnie TrustManager z JVM. Jeśli potrzebujesz pinowania certyfikatów lub niestandardowego SSLContext, ustaw go w OkHttpClient.Builder.sslSocketFactory(...) lub w konfiguracji silnika Ktor OkHttp.
Connection pooling i concurrency
OkHttp utrzymuje pulę połączeń do proxy. Dla rotacji per-request pula jest mniej użyteczna (każde żądanie może trafić na inny wychodzący IP), ale dla sticky sesji pula zmniejsza latency o 50-200ms na każde żądanie. Ustaw ConnectionPool(maxIdle, keepAlive, unit) adekwatnie do liczby sesji — np. 50 idle connections przez 5 minut.
Jak ProxyHat SDK odzwierciedla ten wzorzec
ProxyHat udostępnia jeden endpoint gate.proxyhat.com z portami 8080 (HTTP) i 1080 (SOCKS5). Wszystkie parametry sesji kodowane są w nazwie użytkownika, więc nie ma osobnego SDK wymaganego w Kotlinie — wystarczy standardowy klient HTTP z nagłówkiem Proxy-Authorization: Basic lub Authenticator. Wzorzec z defaultRequest + proxyAuthenticator jest dokładnie tym, czego używa ProxyHat SDK w innych językach, i jest w pełni reprodukowalny w Kotlinie z Ktor Client i OkHttp.
Szczegóły konfiguracji konta i dostępnych lokalizacji znajdziesz w dokumentacji ProxyHat oraz na stronach cennika i lokalizacji.
Etyczny scraping — publiczne dane, CFAA, GDPR
Techniczna możliwość scrapingu nie oznacza jego legalności. W USA Computer Fraud and Abuse Act (CFAA) bywa stosowany wobec scrapingu naruszającego regulaminy witryn, choć wyrok Van Buren v. United States (2021) i hiQ Labs v. LinkedIn ograniczyły zakres CFAA wobec dostępu do publicznych danych. W UE GDPR ogranicza przetwarzanie danych osobowych — w tym danych w scrapowanych wynikach, które identyfikują osoby. Więcej o GDPR znajdziesz na stronie Komisji Europejskiej.
Praktyczne zasady, których przestrzegamy:
- Scrapuj tylko publicznie dostępne dane, nie za zalogowaniem bez zgody.
- Przestrzegaj
robots.txti regulaminów witryn. - Preferuj oficjalne API, gdy są dostępne — Google Search API, Amazon Product Advertising API, Meta Graph API.
- Ograniczaj rate, aby nie degradować usługi celu.
- Przechowuj tylko dane niezbędne do celu przetwarzania; anonimizuj tam, gdzie to możliwe.
Najczęstsze błędy i przypadki brzegowe
- 407 w Ktor CIO dla HTTPS: CIO nie wysyła automatycznie nagłówka Basic przy CONNECT. Użyj silnika OkHttp lub dodaj
Proxy-AuthorizationwdefaultRequesti przetestuj. - SOCKS5 ignoruje dane w URL: JVM czyta
java.net.socks.username/passwordz właściwości systemowych, nie z URL. - Pętla 407: w
proxyAuthenticatorsprawdzajpriorResponse, żeby przerwać po jednej ponowiej próbie. - Zbyt duża współbieżność: 1000 równoległych żądań z jednej sesji proxy to gwarantowana blokada. Używaj
Semaphorei wielu sesji. - Brak User-Agent: wiele witryn odrzuca żądania z domyślnym nagłówkiem Ktor/OkHttp. Ustaw realny nagłówek przeglądarki.
- Cleartext na Androidzie: dodaj
NetworkSecurityConfigdla domeny proxy. - Niezmienne sesje sticky: jeśli zapomnisz zmienić
session-..., wszystkie żądania pójdą z tego samego IP i zostaną zablokowane.
Kluczowe wnioski
Używanie proxy w Kotlin sprowadza się do trzech rzeczy: wybrania odpowiedniego silnika (OkHttp jest najmniej zaskakujący), wstrzyknięcia
Proxy-Authorization: Basicz parametrami sesji w nazwie użytkownika oraz ograniczenia współbieżności przezSemaphorez retry-em i backoffem.
- OkHttp z
proxyAuthenticatorto najbezpieczniejszy wybór dla HTTP proxy z 407. - Ktor Client z silnikiem OkHttp dziedziczy tę przewagę i dodaje idiomatyczne API Kotlin.
- SOCKS5 na JVM wymaga właściwości systemowych — nie nadaje się do wielu logowań w jednej JVM.
- Geo-targeting i sesje sticky kodowane w nazwie użytkownika ProxyHat (
user-country-DE-city-berlin-session-abc123) eliminują potrzebę osobnego SDK. - Residential proxy są konieczne dla celów blokujących datacenter ASN; success rate rośnie z <20% do 90%+.
- Produkcyjne wzmacnianie: retries z backoffem, connection pooling, realne nagłówki, monitorowanie success rate.
- Etyka: publiczne dane, robots.txt, preferencja oficjalnych API, GDPR dla danych osobowych.
FAQ
Czym jest używanie proxy w Kotlin?
Używanie proxy w Kotlin polega na kierowaniu ruchu HTTP/HTTPS z klienta Ktor Client lub OkHttp przez serwer pośredniczący, tak aby ukryć źródłowy adres IP, sterować lokalizacją geo lub utrzymywać sesje sticky. W Kotlin najczęściej konfiguruje się proxy na poziomie silnika Ktor (CIO, OkHttp) lub bezpośrednio na OkHttpClient.Builder().proxy(java.net.Proxy(...)), a uwierzytelnianie proxy przekazuje się nagłówkiem Proxy-Authorization lub przez Authenticator.
Dlaczego używanie proxy w Kotlin ma znaczenie dla scrapera?
Wiele witryn e-commerce, SERP i platform społecznościowych blokuje adresy z datacenter ASN. Proxy residential pozwalają Kotlin aplikacji wysyłać żądania z adresów przypisanych do realnych dostawców internetu, co podnosi success rate i zmniejsza liczbę wyzwań CAPTCHA. Bez proxy Kotlin scrapery często kończą z 403/429 już przy 50-100 żądaniach na minutę.
Który typ proxy najlepiej działa z Kotlin?
Dla scrapingu i automatyzacji w Kotlin najlepsze są proxy residential z rotacją per-request i opcją sesji sticky. Proxy datacenter są odpowiednie tylko dla celów, które nie blokują ASN dostawców chmurowych. Proxy mobile są najbezpieczniejsze dla aplikacji społecznościowych, ale droższe. ProxyHat oferuje wszystkie trzy typy przez jeden endpoint gate.proxyhat.com:8080.
Jak unikać blokad używając proxy w Kotlin?
Używaj rotacji IP, sesji sticky tylko gdy wymagane, ogranicz współbieżność przez Semaphore, ustaw realne nagłówki User-Agent i Accept-Language, wdróż retries z backoffem dla 407/429/503, monitoruj success rate i loguj kody odpowiedzi. Preferuj oficjalne API tam, gdzie są dostępne, i przestrzegaj robots.txt oraz regulaminów witryn.






