Saat mengembangkan parser, otomatisasi pengumpulan data, atau pengujian layanan web dari Python, sering kali diperlukan untuk menggunakan server proksi. Perpustakaan requests dan aiohttp menyediakan mekanisme fleksibel untuk bekerja dengan proksi, tetapi pengaturannya memiliki nuansa penting. Dalam panduan ini, kita akan membahas pendekatan sinkron dan asinkron, menunjukkan contoh untuk proksi HTTP dan SOCKS5, serta membahas rotasi IP dan penanganan kesalahan.
Pengaturan dasar proksi di requests
Perpustakaan requests adalah standar untuk permintaan HTTP di Python. Pengaturan proksi dilakukan melalui parameter proxies, yang menerima kamus dengan protokol dan alamat server proksi.
Contoh sederhana dengan proksi HTTP:
import requests
# Pengaturan proksi
proxies = {
'http': 'http://123.45.67.89:8080',
'https': 'http://123.45.67.89:8080'
}
# Melakukan permintaan melalui proksi
response = requests.get('https://httpbin.org/ip', proxies=proxies)
print(response.json()) # {'origin': '123.45.67.89'}
Perhatikan: untuk permintaan HTTPS, protokol http:// juga harus ditentukan dalam nilai proksi (bukan https://). Ini karena koneksi ke server proksi dilakukan melalui HTTP, dan kemudian melalui metode CONNECT, terowongan dibuat untuk lalu lintas HTTPS.
Menggunakan variabel lingkungan:
Perpustakaan requests secara otomatis membaca proksi dari variabel lingkungan HTTP_PROXY dan HTTPS_PROXY:
import os
import requests
# Mengatur melalui variabel lingkungan
os.environ['HTTP_PROXY'] = 'http://123.45.67.89:8080'
os.environ['HTTPS_PROXY'] = 'http://123.45.67.89:8080'
# Proksi akan diterapkan secara otomatis
response = requests.get('https://httpbin.org/ip')
print(response.json())
Pendekatan ini nyaman untuk kontainerisasi (Docker) atau ketika proksi diatur di tingkat sistem. Namun, untuk fleksibilitas, disarankan untuk secara eksplisit mengirimkan parameter proxies.
Autentikasi dan SOCKS5 di requests
Sebagian besar layanan proksi komersial memerlukan autentikasi dengan nama pengguna dan kata sandi. Di requests, ini diimplementasikan melalui format URL dengan kredensial.
Proksi HTTP dengan autentikasi:
import requests
# Format: http://username:password@host:port
proxies = {
'http': 'http://user123:pass456@proxy.example.com:8080',
'https': 'http://user123:pass456@proxy.example.com:8080'
}
response = requests.get('https://httpbin.org/ip', proxies=proxies)
print(response.json())
Pengaturan proksi SOCKS5:
Untuk bekerja dengan SOCKS5, diperlukan perpustakaan tambahan requests[socks] atau PySocks. Instalasi:
pip install requests[socks]
Contoh penggunaan SOCKS5:
import requests
# SOCKS5 tanpa autentikasi
proxies = {
'http': 'socks5://123.45.67.89:1080',
'https': 'socks5://123.45.67.89:1080'
}
# SOCKS5 dengan autentikasi
proxies_auth = {
'http': 'socks5://user:pass@123.45.67.89:1080',
'https': 'socks5://user:pass@123.45.67.89:1080'
}
response = requests.get('https://httpbin.org/ip', proxies=proxies_auth)
print(response.json())
Proksi SOCKS5 sangat berguna saat bekerja dengan proksi residensial, karena protokol ini menyediakan tunneling lalu lintas yang lebih andal dan mendukung UDP (diperlukan untuk beberapa aplikasi).
Rotasi proksi di requests
Saat melakukan parsing data dalam jumlah besar, penggunaan satu alamat IP dapat menyebabkan pemblokiran. Rotasi proksi adalah pergantian IP secara siklis untuk mendistribusikan beban dan menghindari batasan laju.
Rotasi sederhana melalui daftar:
import requests
import itertools
# Daftar server proksi
proxy_list = [
'http://user:pass@proxy1.example.com:8080',
'http://user:pass@proxy2.example.com:8080',
'http://user:pass@proxy3.example.com:8080',
]
# Membuat iterator tak terbatas
proxy_pool = itertools.cycle(proxy_list)
# Melakukan permintaan dengan rotasi
for i in range(10):
proxy = next(proxy_pool)
proxies = {'http': proxy, 'https': proxy}
try:
response = requests.get('https://httpbin.org/ip', proxies=proxies, timeout=5)
print(f"Permintaan {i+1}: IP = {response.json()['origin']}")
except Exception as e:
print(f"Kesalahan dengan proksi {proxy}: {e}")
Rotasi dengan sesi untuk menyimpan cookies:
import requests
from itertools import cycle
class ProxyRotator:
def __init__(self, proxy_list):
self.proxy_pool = cycle(proxy_list)
self.session = requests.Session()
def get(self, url, **kwargs):
proxy = next(self.proxy_pool)
self.session.proxies = {'http': proxy, 'https': proxy}
return self.session.get(url, **kwargs)
# Penggunaan
proxy_list = [
'http://user:pass@proxy1.example.com:8080',
'http://user:pass@proxy2.example.com:8080',
]
rotator = ProxyRotator(proxy_list)
for i in range(5):
response = rotator.get('https://httpbin.org/ip', timeout=5)
print(f"Permintaan {i+1}: {response.json()['origin']}")
Rotasi acak untuk ketidakpastian:
import requests
import random
proxy_list = [
'http://user:pass@proxy1.example.com:8080',
'http://user:pass@proxy2.example.com:8080',
'http://user:pass@proxy3.example.com:8080',
]
def get_random_proxy():
proxy = random.choice(proxy_list)
return {'http': proxy, 'https': proxy}
# Setiap permintaan dengan proksi acak
for i in range(5):
response = requests.get('https://httpbin.org/ip', proxies=get_random_proxy(), timeout=5)
print(f"Permintaan {i+1}: {response.json()['origin']}")
Rotasi acak lebih efektif saat bekerja dengan situs yang melacak pola permintaan. Pergantian IP yang berurutan dapat terlihat mencurigakan, sementara pemilihan acak meniru perilaku pengguna yang berbeda.
Pengaturan proksi di aiohttp
Perpustakaan aiohttp dirancang untuk permintaan HTTP asinkron dan sangat penting untuk parser yang memiliki beban tinggi. Pengaturan proksi berbeda dari requests — menggunakan parameter proxy (dalam bentuk tunggal).
Contoh dasar dengan proksi HTTP:
import aiohttp
import asyncio
async def fetch_with_proxy():
proxy = 'http://123.45.67.89:8080'
async with aiohttp.ClientSession() as session:
async with session.get('https://httpbin.org/ip', proxy=proxy) as response:
data = await response.json()
print(data)
# Menjalankan
asyncio.run(fetch_with_proxy())
Proksi dengan autentikasi:
Di aiohttp, autentikasi dikirimkan melalui objek aiohttp.BasicAuth atau langsung dalam URL:
import aiohttp
import asyncio
async def fetch_with_auth_proxy():
# Opsi 1: Kredensial dalam URL
proxy = 'http://user123:pass456@proxy.example.com:8080'
async with aiohttp.ClientSession() as session:
async with session.get('https://httpbin.org/ip', proxy=proxy) as response:
print(await response.json())
# Opsi 2: Melalui BasicAuth (untuk beberapa proksi)
async def fetch_with_basic_auth():
proxy = 'http://proxy.example.com:8080'
proxy_auth = aiohttp.BasicAuth('user123', 'pass456')
async with aiohttp.ClientSession() as session:
async with session.get('https://httpbin.org/ip',
proxy=proxy,
proxy_auth=proxy_auth) as response:
print(await response.json())
asyncio.run(fetch_with_auth_proxy())
SOCKS5 di aiohttp:
Untuk SOCKS5, diperlukan perpustakaan aiohttp-socks:
pip install aiohttp-socks
import asyncio
from aiohttp_socks import ProxyConnector
import aiohttp
async def fetch_with_socks5():
connector = ProxyConnector.from_url('socks5://user:pass@123.45.67.89:1080')
async with aiohttp.ClientSession(connector=connector) as session:
async with session.get('https://httpbin.org/ip') as response:
print(await response.json())
asyncio.run(fetch_with_socks5())
Saat bekerja dengan proksi seluler untuk parsing media sosial atau marketplace, disarankan untuk menggunakan aiohttp — asinkronitas memungkinkan untuk memproses ratusan permintaan secara paralel tanpa memblokir alur eksekusi.
Rotasi asinkron dan kolam proksi
Untuk parser dengan beban tinggi, rotasi proksi yang efektif dengan penanganan kegagalan dan penggantian otomatis IP yang tidak berfungsi sangat penting. Mari kita lihat pola lanjutan untuk aiohttp.
Kelas untuk mengelola kolam proksi:
import aiohttp
import asyncio
from itertools import cycle
from typing import List, Optional
class ProxyPool:
def __init__(self, proxy_list: List[str]):
self.proxy_list = proxy_list
self.proxy_cycle = cycle(proxy_list)
self.failed_proxies = set()
def get_next_proxy(self) -> Optional[str]:
"""Mendapatkan proksi yang berfungsi berikutnya"""
for _ in range(len(self.proxy_list)):
proxy = next(self.proxy_cycle)
if proxy not in self.failed_proxies:
return proxy
return None # Semua proksi tidak tersedia
def mark_failed(self, proxy: str):
"""Menandai proksi sebagai tidak berfungsi"""
self.failed_proxies.add(proxy)
print(f"Proksi {proxy} ditandai sebagai tidak tersedia")
async def fetch(self, session: aiohttp.ClientSession, url: str, **kwargs):
"""Melakukan permintaan dengan pergantian proksi otomatis saat terjadi kesalahan"""
max_retries = 3
for attempt in range(max_retries):
proxy = self.get_next_proxy()
if not proxy:
raise Exception("Semua proksi tidak tersedia")
try:
async with session.get(url, proxy=proxy, timeout=aiohttp.ClientTimeout(total=10), **kwargs) as response:
return await response.json()
except (aiohttp.ClientError, asyncio.TimeoutError) as e:
print(f"Kesalahan dengan proksi {proxy}: {e}")
self.mark_failed(proxy)
continue
raise Exception(f"Gagal melakukan permintaan setelah {max_retries} percobaan")
# Penggunaan
async def main():
proxy_list = [
'http://user:pass@proxy1.example.com:8080',
'http://user:pass@proxy2.example.com:8080',
'http://user:pass@proxy3.example.com:8080',
]
pool = ProxyPool(proxy_list)
async with aiohttp.ClientSession() as session:
# Melakukan 10 permintaan dengan rotasi otomatis
tasks = [pool.fetch(session, 'https://httpbin.org/ip') for _ in range(10)]
results = await asyncio.gather(*tasks, return_exceptions=True)
for i, result in enumerate(results):
if isinstance(result, Exception):
print(f"Permintaan {i+1} berakhir dengan kesalahan: {result}")
else:
print(f"Permintaan {i+1}: IP = {result.get('origin')}")
asyncio.run(main())
Pemrosesan paralel dengan batasan concurrency:
import aiohttp
import asyncio
from itertools import cycle
async def fetch_url(session, url, proxy, semaphore):
async with semaphore: # Pembatasan permintaan simultan
try:
async with session.get(url, proxy=proxy, timeout=aiohttp.ClientTimeout(total=10)) as response:
data = await response.json()
return {'url': url, 'ip': data.get('origin'), 'status': response.status}
except Exception as e:
return {'url': url, 'error': str(e)}
async def main():
urls = [f'https://httpbin.org/ip' for _ in range(50)] # 50 permintaan
proxy_list = [
'http://user:pass@proxy1.example.com:8080',
'http://user:pass@proxy2.example.com:8080',
]
proxy_cycle = cycle(proxy_list)
# Pembatasan: tidak lebih dari 10 permintaan simultan
semaphore = asyncio.Semaphore(10)
async with aiohttp.ClientSession() as session:
tasks = [
fetch_url(session, url, next(proxy_cycle), semaphore)
for url in urls
]
results = await asyncio.gather(*tasks)
# Analisis hasil
successful = [r for r in results if 'ip' in r]
failed = [r for r in results if 'error' in r]
print(f"Permintaan yang berhasil: {len(successful)}")
print(f"Permintaan yang gagal: {len(failed)}")
asyncio.run(main())
Menggunakan asyncio.Semaphore sangat penting saat bekerja dengan proksi — terlalu banyak koneksi simultan melalui satu IP dapat menyebabkan pemblokiran dari situs target atau penyedia proksi.
Penanganan kesalahan dan timeout
Bekerja dengan proksi disertai dengan peningkatan jumlah kesalahan: timeout, pemutusan koneksi, dan kegagalan server proksi. Penanganan kesalahan yang tepat adalah kunci untuk stabilitas parser.
Kesalahan umum saat bekerja dengan proksi:
| Kesalahan | Penyebab | Solusi |
|---|---|---|
ProxyError |
Server proksi tidak tersedia | Beralih ke proksi lain |
ConnectTimeout |
Proksi tidak merespons tepat waktu | Tingkatkan timeout atau ganti proksi |
ProxyAuthenticationRequired |
Nama pengguna/kata sandi tidak valid | Periksa kredensial |
SSLError |
Masalah dengan sertifikat SSL | Nonaktifkan verifikasi SSL (tidak disarankan) |
TooManyRedirects |
Proksi menciptakan loop pengalihan | Ganti proksi atau batasi pengalihan |
Penanganan kesalahan di requests:
import requests
from requests.exceptions import ProxyError, ConnectTimeout, RequestException
def fetch_with_retry(url, proxies, max_retries=3):
for attempt in range(max_retries):
try:
response = requests.get(
url,
proxies=proxies,
timeout=(5, 10), # (connect timeout, read timeout)
allow_redirects=True,
verify=True # Verifikasi sertifikat SSL
)
response.raise_for_status() # Akan memicu pengecualian pada 4xx/5xx
return response.json()
except ProxyError as e:
print(f"Percobaan {attempt + 1}: Proksi tidak tersedia - {e}")
except ConnectTimeout as e:
print(f"Percobaan {attempt + 1}: Timeout koneksi - {e}")
except requests.exceptions.HTTPError as e:
print(f"Percobaan {attempt + 1}: Kesalahan HTTP {e.response.status_code}")
if e.response.status_code == 407: # Proxy Authentication Required
print("Kesalahan autentikasi proksi!")
break # Jangan ulangi pada kesalahan otorisasi
except RequestException as e:
print(f"Percobaan {attempt + 1}: Kesalahan umum - {e}")
if attempt < max_retries - 1:
print(f"Ulangi dalam 2 detik...")
import time
time.sleep(2)
raise Exception(f"Gagal melakukan permintaan setelah {max_retries} percobaan")
# Penggunaan
proxies = {'http': 'http://user:pass@proxy.example.com:8080', 'https': 'http://user:pass@proxy.example.com:8080'}
try:
data = fetch_with_retry('https://httpbin.org/ip', proxies)
print(data)
except Exception as e:
print(f"Kesalahan kritis: {e}")
Penanganan kesalahan di aiohttp:
import aiohttp
import asyncio
from aiohttp import ClientError, ClientProxyConnectionError
async def fetch_with_retry(session, url, proxy, max_retries=3):
for attempt in range(max_retries):
try:
timeout = aiohttp.ClientTimeout(total=10, connect=5)
async with session.get(url, proxy=proxy, timeout=timeout) as response:
response.raise_for_status()
return await response.json()
except ClientProxyConnectionError as e:
print(f"Percobaan {attempt + 1}: Kesalahan koneksi ke proksi - {e}")
except asyncio.TimeoutError:
print(f"Percobaan {attempt + 1}: Timeout")
except aiohttp.ClientHttpProxyError as e:
print(f"Percobaan {attempt + 1}: Kesalahan HTTP proksi - {e}")
if e.status == 407:
print("Kesalahan autentikasi proksi!")
break
except ClientError as e:
print(f"Percobaan {attempt + 1}: Kesalahan umum klien - {e}")
if attempt < max_retries - 1:
await asyncio.sleep(2)
raise Exception(f"Gagal melakukan permintaan setelah {max_retries} percobaan")
async def main():
proxy = 'http://user:pass@proxy.example.com:8080'
async with aiohttp.ClientSession() as session:
try:
data = await fetch_with_retry(session, 'https://httpbin.org/ip', proxy)
print(data)
except Exception as e:
print(f"Kesalahan kritis: {e}")
asyncio.run(main())
Pengaturan timeout:
Pengaturan timeout yang tepat sangat penting untuk stabilitas. Nilai yang disarankan:
- Connect timeout: 5-10 detik (waktu untuk membangun koneksi dengan proksi)
- Read timeout: 10-30 detik (waktu untuk menerima respons dari situs target)
- Total timeout: 30-60 detik (total waktu permintaan)
Untuk proksi residensial yang lambat, disarankan untuk meningkatkan timeout hingga 20-30 detik per koneksi, karena routing melalui penyedia nyata dapat memakan waktu lebih lama.
Praktik terbaik dan optimisasi
Bekerja secara efektif dengan proksi memerlukan kepatuhan pada seperangkat aturan untuk meminimalkan pemblokiran dan memaksimalkan kinerja.
1. Menggunakan Session untuk mendaur ulang koneksi:
# requests: Session mendaur ulang koneksi TCP
session = requests.Session()
session.proxies = {'http': proxy, 'https': proxy}
for url in urls:
response = session.get(url) # Lebih cepat daripada requests.get()
# aiohttp: Session diperlukan untuk asinkronitas
async with aiohttp.ClientSession() as session:
tasks = [session.get(url, proxy=proxy) for url in urls]
await asyncio.gather(*tasks)
2. Mengatur User-Agent dan header yang realistis:
import requests
headers = {
'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',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'Accept-Language': 'en-US,en;q=0.5',
'Accept-Encoding': 'gzip, deflate, br',
'DNT': '1',
'Connection': 'keep-alive',
'Upgrade-Insecure-Requests': '1'
}
proxies = {'http': proxy, 'https': proxy}
response = requests.get('https://example.com', headers=headers, proxies=proxies)
3. Membatasi rate limit (permintaan per detik):
import time
import requests
class RateLimiter:
def __init__(self, max_requests_per_second):
self.max_requests = max_requests_per_second
self.interval = 1.0 / max_requests_per_second
self.last_request_time = 0
def wait(self):
elapsed = time.time() - self.last_request_time
if elapsed < self.interval:
time.sleep(self.interval - elapsed)
self.last_request_time = time.time()
# Penggunaan: tidak lebih dari 2 permintaan per detik
limiter = RateLimiter(2)
proxies = {'http': proxy, 'https': proxy}
for url in urls:
limiter.wait()
response = requests.get(url, proxies=proxies)
4. Logging dan pemantauan proksi:
import logging
from collections import defaultdict
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
class ProxyMonitor:
def __init__(self):
self.stats = defaultdict(lambda: {'success': 0, 'failed': 0, 'total_time': 0})
def log_request(self, proxy, success, response_time):
stats = self.stats[proxy]
if success:
stats['success'] += 1
else:
stats['failed'] += 1
stats['total_time'] += response_time
# Logging setiap 10 permintaan
total = stats['success'] + stats['failed']
if total % 10 == 0:
avg_time = stats['total_time'] / total
success_rate = stats['success'] / total * 100
logger.info(f"Proksi {proxy}: {total} permintaan, keberhasilan {success_rate:.1f}%, rata-rata {avg_time:.2f}s")
monitor = ProxyMonitor()
# Dalam kode permintaan
import time
start = time.time()
try:
response = requests.get(url, proxies=proxies, timeout=10)
monitor.log_request(proxy, True, time.time() - start)
except Exception as e:
monitor.log_request(proxy, False, time.time() - start)
logger.error(f"Kesalahan dengan proksi {proxy}: {e}")
5. Cache DNS untuk mempercepat:
# aiohttp dengan caching DNS
import aiohttp
from aiohttp.resolver import AsyncResolver
resolver = AsyncResolver(nameservers=['8.8.8.8', '8.8.4.4'])
connector = aiohttp.TCPConnector(resolver=resolver, ttl_dns_cache=300)
async with aiohttp.ClientSession(connector=connector) as session:
# Permintaan akan menggunakan cache DNS selama 5 menit
async with session.get(url, proxy=proxy) as response:
data = await response.json()
6. Penanganan CAPTCHA dan pemblokiran:
Tip: Saat menerima status 403, 429, atau CAPTCHA, disarankan untuk:
- Ganti proksi dengan IP dari subnet yang berbeda
- Tingkatkan jeda antara permintaan (hingga 5-10 detik)
- Ubah User-Agent dan header lainnya
- Gunakan cookies dari sesi sukses sebelumnya
Perbandingan requests dan aiohttp untuk proksi
Pemilihan antara requests dan aiohttp tergantung pada tugas dan volume data. Mari kita lihat perbedaan kunci.
| Kriteria | requests | aiohttp |
|---|---|---|
| Sinkronisasi | Sinkron (memblokir) | Asinkron (tidak memblokir) |
| Kinerja | ~10-50 permintaan/detik | ~100-1000 permintaan/detik |
| Kesederhanaan kode | Lebih sederhana untuk pemula | Memerlukan pengetahuan tentang async/await |
| Pengaturan proksi | Kamus proxies |
Parameter proxy |
| Dukungan SOCKS5 | Melalui requests[socks] |
Melalui aiohttp-socks |
| Penggunaan memori | Lebih sedikit (satu thread) | Lebih banyak (banyak tugas) |
| Lebih baik untuk | Skrip sederhana, <100 permintaan | Parser, >1000 permintaan |
Kapan menggunakan requests:
- Skrip sederhana untuk tugas sekali jalan
- Prototyping dan pengujian
- Volume permintaan kecil (hingga 100 per menit)
- Ketika kesederhanaan kode dan keterbacaan penting
- Integrasi dengan perpustakaan sinkron
Kapan menggunakan aiohttp:
- Parsing data dalam jumlah besar (ribuan halaman)
- Pemantauan banyak sumber secara real-time
- Layanan API dengan beban tinggi
- Ketika kecepatan pemrosesan sangat penting
- Bekerja dengan WebSocket melalui proksi
Perbandingan praktis kinerja:
# Tes: 100 permintaan melalui proksi
# requests (sinkron) - ~50 detik
import requests
import time
start = time.time()
proxies = {'http': proxy, 'https': proxy}
for i in range(100):
response = requests.get('https://httpbin.org/ip', proxies=proxies)
print(f"requests: {time.time() - start:.2f} detik")
# aiohttp (asinkron) - ~5 detik
import aiohttp
import asyncio
async def fetch_all():
async with aiohttp.ClientSession() as session:
tasks = [
session.get('https://httpbin.org/ip', proxy=proxy)
for _ in range(100)
]
await asyncio.gather(*tasks)
start = time.time()
asyncio.run(fetch_all())
print(f"aiohttp: {time.time() - start:.2f} detik")
Saat menggunakan proksi pusat data untuk parsing dengan kecepatan tinggi, aiohttp menunjukkan keuntungan 10-20 kali dibandingkan requests berkat pemrosesan permintaan secara paralel.
Kesimpulan
Pengaturan proksi di Python melalui perpustakaan requests dan aiohttp adalah keterampilan dasar untuk mengembangkan parser, otomatisasi pengumpulan data, dan menghindari batasan geografis. Perpustakaan requests cocok untuk skrip sederhana dan prototyping berkat API sinkron yang mudah dipahami, sementara aiohttp menyediakan kinerja tinggi saat memproses ribuan permintaan melalui arsitektur asinkron.
Poin kunci untuk bekerja secara efektif dengan proksi di Python: penanganan kesalahan dan timeout yang tepat, implementasi rotasi alamat IP untuk mendistribusikan beban, penggunaan Session untuk mendaur ulang koneksi, pengaturan header dan User-Agent yang realistis, serta pemantauan kinerja server proksi. Untuk proksi SOCKS5, diperlukan perpustakaan tambahan — requests[socks] atau aiohttp-socks.
Saat memilih jenis proksi untuk parsing, pertimbangkan spesifikasi tugas: untuk parser dengan beban tinggi yang melakukan ribuan permintaan, proksi pusat data yang cepat cocok, untuk menghindari sistem anti-bot yang ketat dan bekerja dengan media sosial, disarankan menggunakan proksi residensial dengan IP nyata dari pengguna rumah, dan untuk tugas yang memerlukan anonimitas maksimum serta simulasi lalu lintas seluler, proksi seluler dengan IP dari operator seluler adalah yang paling optimal.
Jika Anda berencana untuk mengembangkan parser berkinerja tinggi atau mengotomatiskan pengumpulan data dari banyak sumber, kami merekomendasikan untuk mencoba proksi residensial — mereka memberikan tingkat anonimitas yang tinggi, risiko pemblokiran yang minimal, dan kinerja yang stabil dengan sebagian besar layanan web yang dilindungi. Untuk tugas teknis dengan kecepatan pemrosesan tinggi, proksi pusat data dengan latensi rendah dan kapasitas tinggi juga cocok.