R'da proxy kullanımı, veri bilimcilerin ve analistlerin coğrafi engelleri aşarak, hız limitlerini yöneterek ve IP tabanlı blokları atlatarak güvenilir veri toplaması için kritik bir beceridir. Bu rehber, modern R HTTP yığını olan httr2 ve HTML ayrıştırma paketi rvest ile residential proxy'leri nasıl entegre edeceğinizi adım adım gösterir. Tüm örnekler ProxyHat'ın gate.proxyhat.com gateway'ini kullanır.
R'da Proxy Kullanımı Neden Gereklidir?
Web scraping in R, uzun süredir httr ve rvest kombinasyonuyla yapılıyordu. Ancak modern httr2 paketi, istek zincirleri (request pipelines), retry mekanizmaları ve proxy desteği açısından çok daha güçlü bir yaklaşım sunar. R proxy ihtiyacı ise şu senaryolarda ortaya çıkar:
- Coğrafi engeller: Bazı siteler yalnızca belirli ülkelerden gelen trafiğe izin verir. Örneğin İngiltere merkezli bir e-ticaret sitesi ABD IP'lerini engelleyebilir.
- IP tabanlı hız limitleri: Birçok site tek IP'den gelen çok sayıda isteği 429 Too Many Requests yanıtıyla reddeder.
- Bot tespiti: Datacenter IP aralıkları sık sık engellenir; residential IP'ler ise gerçek kullanıcı trafiğine benzer görünür.
- Yüksek erişilebilirlik: Tek bir IP bloke olduğunda, proxy havuzu otomatik rotasyonla kesintiyi önler.
httr2 resmi dokümantasyonu, proxy desteğini req_proxy() fonksiyonuyla sağlar. rvest paketi ise HTML ayrıştırma için tidyverse ekosisteminin standardıdır. Bu ikisini birleştirmek, production-grade veri toplama için ideal bir yığın oluşturur.
Residential vs Datacenter Proxy'ler
Proxy seçimi, scraping projelerinin başarısını doğrudan etkiler. Residential proxy'ler, gerçek ISS'lerden (ISP) tahsis edilmiş IP'lerdir ve gerçek kullanıcı trafiğinden ayırt edilmeleri zordur. Datacenter proxy'ler ise hosting sağlayıcılarının IP bloklarından gelir; hızlı ve ucuzdurlar ama kolayca tespit edilirler.
| Özellik | Residential Proxy | Datacenter Proxy |
|---|---|---|
| IP Kaynağı | Gerçek ISS (ISP) | Veri merkezi blokları |
| Tespit Edilme Riski | Düşük | Yüksek |
| Hız | Orta (50-200ms ek gecikme) | Yüksek (1-20ms) |
| Fiyat | Daha yüksek ($2-15/GB) | Düşük ($0.5-2/GB) |
| Uygun Senaryo | SERP, e-ticaret, sosyal medya | Basit API'ler, açık veri |
Engellenme riski yüksek olan hedeflerde residential proxy'ler kaçınılmazdır. Datacenter IP'leri ise robots.txt'e saygı duyan, resmi API sunmayan ama erişimi serbest olan kaynaklar için yeterlidir.
httr2 ile Temel Proxy Kurulumu
İlk olarak gerekli paketleri yükleyin ve ProxyHat gateway'ine bağlanın. ProxyHat'ın HTTP proxy portu 8080, SOCKS5 portu ise 1080'dir.
# Paket kurulumu (ilk seferlik)
# install.packages(c("httr2", "rvest", "purrr", "dplyr", "tibble"))
library(httr2)
library(rvest)
library(purrr)
library(dplyr)
# ProxyHat kimlik bilgileri
proxy_user <- "your_username"
proxy_pass <- "your_password"
# Temel istek + proxy ekleme
req <- request("https://httpbin.org/ip") %>%
req_proxy(
url = "http://gate.proxyhat.com",
port = 8080,
username = proxy_user,
password = proxy_pass
) %>%
req_user_agent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36") %>%
req_timeout(30)
resp <- req %>% req_perform()
resp %>% resp_body_json()
Bu örnekte req_proxy() fonksiyonu, tüm HTTP trafiğini ProxyHat gateway'inden yönlendirir. req_user_agent() ile gerçekçi bir tarayıcı kimliği belirlemek, basit bot filtrelerini aşmanın ilk adımıdır.
Geo-Targeting ve Sticky Sessions
ProxyHat, kullanıcı adı alanında bayraklar kullanarak geo-targeting ve sticky session yönetimini destekler. Örneğin İngiltere/Londra IP'si için kullanıcı adını user-country-GB-city-london biçiminde ayarlarsınız. Sticky session için ise user-session-abc123 formatını kullanırsınız.
# Geo-targeting: İngiltere / Londra
geo_user <- paste0(proxy_user, "-country-GB-city-london")
req_uk <- request("https://httpbin.org/ip") %>%
req_proxy(
url = "http://gate.proxyhat.com",
port = 8080,
username = geo_user,
password = proxy_pass
) %>%
req_user_agent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36")
req_uk %>% req_perform() %>% resp_body_json()
# Sticky session: aynı IP'yi koru
session_user <- paste0(proxy_user, "-session-page123")
req_sticky <- request("https://httpbin.org/ip") %>%
req_proxy(
url = "http://gate.proxyhat.com",
port = 8080,
username = session_user,
password = proxy_pass
)
req_sticky %>% req_perform() %>% resp_body_json()
SOCKS5 Proxy ile Daha Güvenli Bağlantı
Bazı hedefler HTTP proxy'leri engellerken SOCKS5 trafiğine izin verir. ProxyHat'ın SOCKS5 portu 1080'dir. httr2, SOCKS5 proxy'leri socks5:// şemasıyla destekler.
# SOCKS5 üzerinden bağlantı (port 1080)
socks_user <- paste0(proxy_user, "country-DE")
req_socks <- request("https://httpbin.org/ip") %>%
req_proxy(
url = "socks5://gate.proxyhat.com",
port = 1080,
username = socks_user,
password = proxy_pass
) %>%
req_timeout(30)
req_socks %>% req_perform() %>% resp_body_json()
SOCKS5, TCP katmanında çalıştığı için HTTPS trafiğini ek şifreleme katmanı olmadan tünelleyebilir. Bu, bazı CDN'lerin HTTP proxy tespitini atlatmaya yardımcı olur.
rvest ile HTML Ayrıştırma ve Tablo Çekme
Proxy üzerinden gelen yanıtı rvest ile ayrıştırmak için resp_body_string() ile HTML'i alın ve read_html() ile ayrıştırın. html_elements() ve html_table() fonksiyonları, tablo halindeki verileri tidy data frame'e dönüştürür.
# Proxy üzerinden HTML çek ve tabloyu ayrıştır
fetch_html <- function(url, proxy_username, proxy_password) {
req <- request(url) %>%
req_proxy(
url = "http://gate.proxyhat.com",
port = 8080,
username = proxy_username,
password = proxy_password
) %>%
req_user_agent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36") %>%
req_headers(
Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
`Accept-Language` = "en-GB,en;q=0.9"
) %>%
req_timeout(30)
resp <- req %>% req_perform()
html_content <- resp %>% resp_body_string()
read_html(html_content)
}
# Örnek: HTML tablosunu data frame'e çevir
html_doc <- fetch_html(
"https://example.com/data-table",
paste0(proxy_user, "-country-GB"),
proxy_pass
)
tables <- html_doc %>% html_table()
df <- tables[[1]] %>% as_tibble()
print(df)
Sayfalı Tablo Toplama: purrr + req_retry + req_throttle
Gerçek dünyada veriler genellikle sayfalara bölünmüştür. Her sayfa için ayrı bir sticky session kullanmak, IP rotasyonu sağlar ve bloklanma riskini azaltır. purrr::map() ile sayfaları dolaşır, req_retry() ile başarısız istekleri yeniden dener ve req_throttle() ile istek hızını kontrol altında tutarsınız.
# Sayfalı veri toplama — session başına IP rotasyonu
library(purrr)
library(dplyr)
library(tibble)
fetch_page <- function(page_num, base_url, proxy_user, proxy_pass) {
# Her sayfa için yeni sticky session = yeni IP
session_id <- paste0("page-", page_num, "-", floor(runif(1) * 1e6))
username <- paste0(proxy_user, "-session-", session_id, "-country-GB")
url <- paste0(base_url, "?page=", page_num)
req <- request(url) %>%
req_proxy(
url = "http://gate.proxyhat.com",
port = 8080,
username = username,
password = proxy_pass
) %>%
req_user_agent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36") %>%
req_headers(
Accept = "text/html,application/xhtml+xml",
`Accept-Language` = "en-GB,en;q=0.9"
) %>%
req_retry(max_tries = 3, max_seconds = 60) %>%
req_throttle(delay = 2) %>% # saniyede en fazla 0.5 istek
req_timeout(30)
tryCatch({
resp <- req %>% req_perform()
html_content <- resp %>% resp_body_string()
html_doc <- read_html(html_content)
tables <- html_doc %>% html_table()
if (length(tables) > 0) {
df <- tables[[1]] %>% as_tibble()
df$page <- page_num
return(df)
} else {
return(tibble())
}
}, error = function(e) {
message("Sayfa ", page_num, " başarısız: ", conditionMessage(e))
return(tibble())
})
}
# 1-20 arası sayfaları topla
pages <- 1:20
results <- map(pages, ~fetch_page(
.x,
"https://example.com/products",
proxy_user,
proxy_pass
))
# Tüm sayfaları birleştir
final_df <- bind_rows(results)
print(paste("Toplam satır:", nrow(final_df)))
Bu örnekte dikkat edilmesi gereken noktalar:
req_retry(max_tries = 3)— başarısız istekleri en fazla 3 kez dener.req_throttle(delay = 2)— her istek arasında en az 2 saniye bekler; saniyede 0.5 istek = dakikada 30 istek.tryCatch— bir sayfa başarısız olursa tüm pipeline çökmez.- Her sayfa için yeni
session_id— ProxyHat otomatik olarak yeni bir IP atar.
JavaScript ile Render Edilen Sayfalar: read_html_live()
Bazı siteler içeriği JavaScript ile yükler; statik HTML'de veri yoktur. rvest'in read_html_live() fonksiyonu, chromote paketi üzerinden gerçek bir Chromium tarayıcısı çalıştırır. Bu tarayıcıya da proxy ayarlayabilirsiniz.
# JS render edilen sayfa için canlı tarayıcı
library(rvest)
library(chromote)
# Chromium'ı proxy ile başlat
chromote_proxy <- new_chromote_session(
proxy = list(
url = "http://gate.proxyhat.com:8080",
username = paste0(proxy_user, "-country-GB-city-london"),
password = proxy_pass
)
)
# JS render edilmiş sayfayı çek
live_html <- read_html_live(
"https://example.com/js-rendered-data",
session = chromote_proxy,
timeout = 30000 # 30 saniye bekle
)
# Tabloları ayrıştır
tables <- live_html %>% html_table()
df <- tables[[1]] %>% as_tibble()
print(df)
# Tarayıcı oturumunu kapat
chromote_proxy$close()
read_html_live() ile proxy kullanırken, Chromium başlatma süresi 3-5 saniye sürebilir. Bu nedenle bu yöntemi yalnızca gerçekten JS gerektiren sayfalar için kullanın. Statik HTML için read_html() çok daha hızlıdır.
Gerçekçi İstek Başlıkları ve Bot Tespiti
Modern anti-bot sistemleri yalnızca IP'ye değil, istek desenlerine de bakar. Aşağıdaki başlık seti, gerçek bir tarayıcı profilini taklit eder:
# Kapsamlı başlık seti
realistic_req <- request("https://example.com") %>%
req_proxy(
url = "http://gate.proxyhat.com",
port = 8080,
username = paste0(proxy_user, "-country-GB"),
password = proxy_pass
) %>%
req_user_agent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36") %>%
req_headers(
Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
`Accept-Language` = "en-GB,en-US;q=0.9,en;q=0.8",
`Accept-Encoding` = "gzip, deflate, br",
Connection = "keep-alive",
`Upgrade-Insecure-Requests` = "1",
`Sec-Fetch-Dest` = "document",
`Sec-Fetch-Mode` = "navigate",
`Sec-Fetch-Site` = "none",
`Sec-Fetch-User` = "?1"
) %>%
req_timeout(30)
Anti-bot sistemleri, başlıkların tutarlılığını da kontrol eder. Örneğin Accept-Language başlığı ile geo-targeting ülkesi uyuşmalıdır. İngiltere IP'si ile en-GB kullanmak tutarlıdır; ja-JP kullanmak şüphe uyandırır.
ProxyHat SDK ile Karışık Pipeline'lar
Eğer R pipeline'ınızı Python veya Node.js servisleriyle birleştiriyorsanız, ProxyHat SDK aynı bağlantı desenini takip eder. Python'da requests ile:
# Python — ProxyHat ile aynı desen
import requests
proxies = {
"http": "http://user-country-GB:pass@gate.proxyhat.com:8080",
"https": "http://user-country-GB:pass@gate.proxyhat.com:8080",
}
resp = requests.get("https://httpbin.org/ip", proxies=proxies, timeout=30)
print(resp.json())
R ve Python arasındaki tutarlılık, tek bir proxy sağlayıcı üzerinden tüm ekosistemi yönetmeyi kolaylaştırır. ProxyHat fiyatlandırması sayfasından farklı planları inceleyebilir, mevcut lokasyonları kontrol edebilirsiniz. Daha fazla teknik detay için ProxyHat dokümantasyonuna bakın.
Etiğe Saygı ve Yasal Uygunluk
Veri toplama, teknik olarak mümkün olmasıyla yasal olarak izin verildiği anlamına gelmez. Aşağıdaki ilkeleri izleyin:
- robots.txt'i kontrol edin:
/robots.txtdosyası, hangi yolların taranmasına izin verildiğini belirtir. Buna saygı duyun. - Hız sınırlarına uyun: Bir siteye saniyede 50 istek göndermek, hem etik dışı hem de IP bloklarına yol açar.
- GDPR ve KVKK: AB'deki veri öznelerine ait kişisel verileri toplarken GDPR kurallarına uyun. Türkiye'de KVKK benzer yükümlülükler getirir.
- Hizmet şartları: Hedef sitenin ToS'u scraping'i yasaklıyorsa, resmi API'leri tercih edin.
- Kamu verisi: Yalnızca herkese açık, kamu kaynaklı verileri toplayın. Giriş gerektiren içerik için izin alın.
Resmi API sunan siteler için her zaman API'yi tercih edin. API'ler daha istikrarlıdır, hız limitleri belgelenmiştir ve yasal risk taşımaz. Web scraping kullanım senaryoları ve SERP tracking sayfalarımızda bu konuları daha derinlemesine ele alıyoruz.
Yaygın Hatalar ve Çözümleri
1. Proxy Kimlik Bilgilerini Koda Gömme
Kullanıcı adı ve şifreyi doğrudan koda yazmak, sürüm kontrolüne sızdırma riski taşır. Bunun yerine environment variable kullanın:
# .Renviron dosyasına ekleyin:
# PROXYHAT_USER=your_username
# PROXYHAT_PASS=your_password
proxy_user <- Sys.getenv("PROXYHAT_USER")
proxy_pass <- Sys.getenv("PROXYHAT_PASS")
if (proxy_user == "") {
stop("PROXYHAT_USER environment variable ayarlı değil!")
}
2. Timeout Belirtmeme
Proxy üzerinden istekler bazen takılabilir. req_timeout(30) her zaman ekleyin; aksi takdirde R oturumu sonsuza kadar bekleyebilir.
3. Tutarlı User-Agent Kullanmama
Varsayılan httr2 user-agent'ı httr2/1.0.0 gibi görünür ve anında bot olarak işaretlenir. Her zaman gerçekçi bir tarayıcı user-agent'ı belirleyin.
4. Retry Stratejisi Olmama
req_retry() olmadan, geçici bir 503 hatası tüm pipeline'ı durdurur. En az 3 deneme ve 60 saniye maksimum süre ayarlayın.
Önemli Çıkarımlar
Key Takeaways:
- R'da proxy kullanımı için
httr2::req_proxy()modern ve güçlü çözümdür;rvestile sorunsuz çalışır.- ProxyHat geo-targeting ve sticky session'ları kullanıcı adı bayraklarıyla yönetir:
user-country-GB-city-london.- Residential proxy'ler, datacenter IP'lere göre 5-10x daha düşük bloklanma riski sunar.
req_retry()vereq_throttle(), production scraping için zorunludur.- JS render edilen sayfalar için
read_html_live()+ chromote + proxy kombinasyonu kullanın.- Etiğe ve yasalara uyun: robots.txt, GDPR ve ToS kurallarına saygı gösterin.
SSS
Aşağıdaki sorular, R'da proxy kullanımıyla ilgili en sık karşılaşılan soruları yanıtlar.
R'da proxy kullanımı nedir?
R'da proxy kullanımı, HTTP isteklerini bir proxy sunucusu üzerinden yönlendirerek IP adresinizi gizleme, coğrafi konum değiştirme ve hız limitlerini aşma işlemidir. httr2 paketinin req_proxy() fonksiyonu, proxy kimlik doğrulaması ve bağlantı yönetimini basitleştirir. rvest ile birlikte kullanıldığında, engellenmiş veya coğrafi olarak kısıtlı sitelerden veri toplamak mümkün olur.
R'da proxy kullanımı neden önemlidir?
Proxy kullanımı, IP tabanlı blokları aşmanın, coğrafi engelleri kaldırmanın ve hız limitlerini yönetmenin temel yoludur. Residential proxy'ler, gerçek ISS IP'leri sağladığı için bot tespit sistemlerinden kaçmak için kritiktir. R ile web scraping yaparken proxy olmadan, birkaç yüz istek sonra IP'niz bloklanabilir ve veri toplama süreciniz durabilir.
R'da proxy kullanımı için hangi proxy tipi en iyisidir?
Engellenme riski yüksek hedefler için residential proxy'ler en iyi seçimdir. Gerçek ISS IP'leri sağladıkları için bot filtrelerinden geçerler ve coğrafi targeting desteklerler. Datacenter proxy'ler ise açık API'ler ve robots.txt'e saygı duyan kaynaklar için yeterlidir; daha hızlı ve daha ucuzdurlar. ProxyHat her iki tipi de sunar; ihtiyacınıza göre fiyatlandırma sayfasından seçim yapabilirsiniz.
R'da proxy kullanırken blokları nasıl önlersiniz?
Blokları önlemek için: (1) her istekte yeni sticky session ile IP rotasyonu yapın; (2) req_throttle() ile istek hızını saniyede 0.5-1 isteğe düşürün; (3) gerçekçi user-agent ve header seti kullanın; (4) req_retry() ile geçici hataları otomatik yeniden deneyin; (5) geo-targeting ile hedef ülkeye uygun IP kullanın; (6) robots.txt kurallarına uyun. Bu kombinasyon, 99% başarı oranına ulaşmanıza yardımcı olur.






