Jika skrip Python Anda mendapatkan kesalahan 403, CAPTCHA, atau pemblokiran berdasarkan IP — berarti situs target sudah memperhatikan Anda. Menghubungkan proksi ke pustaka requests menyelesaikan masalah ini: Anda mengubah alamat IP, melewati batasan geografis, dan mendistribusikan beban antara beberapa alamat. Dalam panduan ini — semua dari koneksi dasar hingga rotasi lanjutan dengan contoh kode nyata.
Mengapa proksi diperlukan dalam skrip Python
Sebagian besar situs dan API melacak alamat IP dari permintaan yang masuk. Jika satu alamat melakukan 100+ permintaan per menit — alamat tersebut akan diblokir. Ini adalah perlindungan standar terhadap bot yang digunakan oleh Wildberries, Ozon, Avito, Google, Instagram, dan ratusan platform lainnya. Proksi memungkinkan Anda mengarahkan permintaan melalui server perantara dengan alamat IP yang berbeda, membuat Anda tidak terlihat bagi sistem perlindungan.
Berikut adalah tugas utama di mana proksi di Python sangat diperlukan:
- Pengambilan data dari marketplace — pengumpulan harga dari Wildberries, Ozon, Yandex.Market tanpa pemblokiran berdasarkan IP
- Monitoring pesaing — permintaan rutin ke situs pesaing setiap 5–15 menit
- Kerja dengan API dengan batasan — distribusi permintaan antara beberapa IP untuk tidak melebihi batas permintaan
- Penguji geolokasi — memeriksa bagaimana situs terlihat dari berbagai negara dan wilayah
- Otomatisasi formulir dan pendaftaran — membuat akun atau mengisi formulir dari berbagai IP
- Monitoring SEO — pengambilan posisi dari berbagai wilayah di Rusia dan negara lain
Tanpa proksi, bahkan pengambil data yang ditulis dengan baik akan terjebak dalam pemblokiran hanya setelah beberapa jam kerja. Dengan rotasi IP yang diatur dengan benar, skrip yang sama dapat berjalan selama berminggu-minggu tanpa henti.
Pengaturan dasar proksi di requests
Pustaka requests mendukung proksi secara native — tidak perlu paket tambahan. Proksi disampaikan melalui kamus proxies dalam parameter permintaan.
Contoh paling sederhana — proksi HTTP untuk satu permintaan:
import requests
proxies = {
"http": "http://123.45.67.89:8080",
"https": "http://123.45.67.89:8080",
}
response = requests.get("https://httpbin.org/ip", proxies=proxies)
print(response.json())
# {'origin': '123.45.67.89'}
Perhatikan: dalam kamus proxies Anda perlu menyebutkan kedua kunci — http dan https. Jika hanya satu yang disebutkan, permintaan untuk protokol kedua akan langsung tanpa proksi. Ini adalah kesalahan umum bagi pemula, yang menyebabkan IP asli tetap bocor.
Untuk memastikan bahwa proksi berfungsi, gunakan layanan httpbin.org/ip — ia mengembalikan alamat IP dari mana permintaan datang. Jika dalam respons Anda melihat IP dari server proksi, bukan IP Anda sendiri — semuanya diatur dengan benar.
Proksi HTTP, HTTPS, dan SOCKS5: perbedaan dan contoh kode
Proksi ada dalam berbagai jenis, dan masing-masing cocok untuk tugas tertentu. Dalam konteks Python requests, penting untuk memahami perbedaan antara tiga protokol utama:
| Tipe | Protokol dalam URL | Kecepatan | Dukungan UDP | Skenario terbaik |
|---|---|---|---|---|
| HTTP | http:// |
Tinggi | Tidak | Pengambilan data dari situs HTTP |
| HTTPS | https:// |
Tinggi | Tidak | Pengambilan data dari situs yang dilindungi |
| SOCKS5 | socks5:// |
Sedang | Ya | Anonimitas penuh, semua protokol |
Untuk bekerja dengan SOCKS5 di Python, Anda perlu menginstal paket tambahan:
pip install requests[socks] # atau secara terpisah: pip install PySocks
Setelah instalasi, koneksi proksi SOCKS5 terlihat seperti ini:
import requests
# Proksi SOCKS5
proxies = {
"http": "socks5://123.45.67.89:1080",
"https": "socks5://123.45.67.89:1080",
}
response = requests.get("https://httpbin.org/ip", proxies=proxies)
print(response.json())
SOCKS5 adalah protokol yang lebih disukai untuk tugas di mana anonimitas penting. Berbeda dengan proksi HTTP, SOCKS5 tidak menambahkan header X-Forwarded-For, yang dapat mengungkapkan IP asli Anda.
Proksi dengan otentikasi menggunakan nama pengguna dan kata sandi
Sebagian besar layanan proksi berbayar menggunakan otentikasi dengan nama pengguna dan kata sandi. Ini adalah praktik standar — tanpa otorisasi, proksi tidak akan mengizinkan permintaan Anda. Dalam pustaka requests, data otorisasi disampaikan langsung dalam URL proksi.
import requests # Format: protokol://nama_pengguna:kata_sandi@host:port proxy_url = "http://myuser:[email protected]:8080" proxies = { "http": proxy_url, "https": proxy_url, } response = requests.get("https://httpbin.org/ip", proxies=proxies) print(response.status_code) print(response.json())
Jika ada karakter khusus dalam kata sandi atau nama pengguna (misalnya, @, #, %), mereka perlu di-URL-encode. Untuk ini, gunakan modul urllib.parse:
import requests
from urllib.parse import quote
username = "myuser"
password = "p@ss#word!" # Karakter khusus
# URL-encode nama pengguna dan kata sandi
encoded_user = quote(username, safe="")
encoded_pass = quote(password, safe="")
proxy_url = f"http://{encoded_user}:{encoded_pass}@123.45.67.89:8080"
proxies = {
"http": proxy_url,
"https": proxy_url,
}
response = requests.get("https://httpbin.org/ip", proxies=proxies)
print(response.json())
💡 Tips keamanan
Jangan pernah hardcode nama pengguna dan kata sandi langsung dalam kode skrip. Gunakan variabel lingkungan atau file .env dengan pustaka python-dotenv. Dengan cara ini, Anda dapat menghindari kebocoran kredensial secara tidak sengaja saat mempublikasikan kode di GitHub.
Rotasi proksi: perubahan IP otomatis untuk pengambilan data
Satu proksi — itu masih satu alamat IP, yang dapat diblokir. Perlindungan nyata dari pemblokiran adalah rotasi: setiap permintaan (atau setiap N permintaan) dilakukan dengan IP baru. Di bawah ini adalah beberapa pendekatan untuk menerapkan rotasi.
Metode 1: Pemilihan acak dari daftar
import requests
import random
# Daftar proksi
proxy_list = [
"http://user:[email protected]:8080",
"http://user:[email protected]:8080",
"http://user:[email protected]:8080",
"http://user:[email protected]:8080",
]
def get_random_proxy():
proxy = random.choice(proxy_list)
return {"http": proxy, "https": proxy}
# Mengambil data dari 10 halaman dengan rotasi IP
urls = [f"https://example.com/page/{i}" for i in range(1, 11)]
for url in urls:
proxies = get_random_proxy()
try:
response = requests.get(url, proxies=proxies, timeout=10)
print(f"URL: {url} | IP: {proxies['http'].split('@')[1]} | Status: {response.status_code}")
except requests.RequestException as e:
print(f"Kesalahan: {e}")
Metode 2: Rotasi siklis melalui itertools
import requests
import itertools
proxy_list = [
"http://user:[email protected]:8080",
"http://user:[email protected]:8080",
"http://user:[email protected]:8080",
]
# Membuat siklus tak terbatas dari daftar proksi
proxy_cycle = itertools.cycle(proxy_list)
def get_next_proxy():
proxy = next(proxy_cycle)
return {"http": proxy, "https": proxy}
# Setiap permintaan menggunakan proksi berikutnya secara berurutan
for i in range(9):
proxies = get_next_proxy()
response = requests.get("https://httpbin.org/ip", proxies=proxies, timeout=10)
print(f"Permintaan {i+1}: {response.json()['origin']}")
Untuk tugas industri dengan ribuan permintaan per jam, disarankan untuk menggunakan proksi residensial dengan rotasi otomatis yang terintegrasi — penyedia secara otomatis mengubah IP untuk setiap permintaan melalui satu endpoint, dan Anda tidak perlu mengelola daftar alamat secara manual.
Proksi melalui Session: koneksi permanen dan cookie
Ketika perlu melakukan beberapa permintaan dalam satu sesi (misalnya, login dan kemudian melakukan permintaan), gunakan objek requests.Session(). Ini menyimpan cookie, header, dan pengaturan proksi antara permintaan — tidak perlu menyampaikan proksi di setiap panggilan secara terpisah.
import requests
# Membuat sesi dengan proksi
session = requests.Session()
session.proxies = {
"http": "http://user:[email protected]:8080",
"https": "http://user:[email protected]:8080",
}
# Menambahkan header untuk meniru browser
session.headers.update({
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
"Accept-Language": "ru-RU,ru;q=0.9",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
})
# Langkah 1: Otorisasi
login_data = {"username": "myuser", "password": "mypass"}
session.post("https://example.com/login", data=login_data)
# Langkah 2: Permintaan sudah dengan cookie dan melalui proksi
response = session.get("https://example.com/dashboard")
print(response.status_code)
# Langkah 3: Menutup sesi
session.close()
Menggunakan Session juga lebih efisien dari segi kinerja: koneksi TCP digunakan kembali, bukan dibuka kembali untuk setiap permintaan. Saat mengambil lebih dari 1000 halaman, ini memberikan peningkatan kecepatan yang signifikan.
Penanganan kesalahan, waktu tunggu, dan pengulangan otomatis
Server proksi mungkin tidak tersedia, merespons lambat, atau mengembalikan kesalahan koneksi. Skrip pengambilan data yang andal harus dapat menangani situasi ini dan secara otomatis beralih ke proksi lain saat terjadi kegagalan.
import requests
import random
import time
proxy_list = [
"http://user:[email protected]:8080",
"http://user:[email protected]:8080",
"http://user:[email protected]:8080",
]
def fetch_with_retry(url, max_retries=3, timeout=10):
"""
Melakukan permintaan dengan perubahan proksi otomatis saat terjadi kesalahan.
Mengembalikan objek Response atau None saat percobaan habis.
"""
available_proxies = proxy_list.copy()
random.shuffle(available_proxies)
for attempt, proxy_url in enumerate(available_proxies[:max_retries], 1):
proxies = {"http": proxy_url, "https": proxy_url}
try:
response = requests.get(
url,
proxies=proxies,
timeout=timeout,
headers={"User-Agent": "Mozilla/5.0"}
)
response.raise_for_status() # Menghasilkan pengecualian pada status 4xx/5xx
print(f"✓ Sukses pada percobaan {attempt}")
return response
except requests.exceptions.ProxyError:
print(f"✗ Percobaan {attempt}: proksi tidak tersedia — {proxy_url}")
except requests.exceptions.Timeout:
print(f"✗ Percobaan {attempt}: waktu tunggu — {proxy_url}")
except requests.exceptions.HTTPError as e:
print(f"✗ Percobaan {attempt}: kesalahan HTTP {e.response.status_code}")
if e.response.status_code == 403:
print(" → Diblokir, mencoba proksi berikutnya...")
except requests.exceptions.RequestException as e:
print(f"✗ Percobaan {attempt}: kesalahan umum — {e}")
time.sleep(1) # Jeda antara percobaan
print(f"✗ Semua {max_retries} percobaan habis untuk {url}")
return None
# Penggunaan
result = fetch_with_retry("https://httpbin.org/ip")
if result:
print(result.json())
Perhatikan raise_for_status() — metode ini secara otomatis melempar pengecualian pada status HTTP 4xx dan 5xx. Tanpa itu, skrip akan menganggap respons dengan kode 403 (pemblokiran) atau 429 (melebihi batas permintaan) sebagai sukses.
Proksi melalui variabel lingkungan: penyimpanan data yang aman
Pustaka requests secara otomatis membaca variabel lingkungan HTTP_PROXY dan HTTPS_PROXY. Ini memungkinkan Anda untuk tidak menyimpan kredensial dalam kode dan dengan mudah beralih antara proksi tanpa mengubah skrip.
Mengatur variabel di terminal (Linux/macOS):
export HTTP_PROXY="http://user:[email protected]:8080" export HTTPS_PROXY="http://user:[email protected]:8080" export NO_PROXY="localhost,127.0.0.1"
Atau melalui file .env dengan pustaka python-dotenv:
# File .env (tambahkan ke .gitignore!) HTTP_PROXY=http://user:[email protected]:8080 HTTPS_PROXY=http://user:[email protected]:8080
# Skrip Python
from dotenv import load_dotenv
import requests
import os
load_dotenv() # Memuat variabel dari .env
# requests secara otomatis menggunakan HTTP_PROXY dan HTTPS_PROXY
response = requests.get("https://httpbin.org/ip")
print(response.json())
# Atau secara eksplisit dari variabel lingkungan:
proxies = {
"http": os.getenv("HTTP_PROXY"),
"https": os.getenv("HTTPS_PROXY"),
}
response = requests.get("https://httpbin.org/ip", proxies=proxies)
print(response.json())
⚠️ Penting: variabel NO_PROXY
Variabel NO_PROXY memungkinkan Anda untuk mengecualikan alamat tertentu dari proksifikasi. Pastikan untuk menambahkan localhost dan 127.0.0.1 agar permintaan lokal tidak melalui proksi.
Skenario nyata: pengambilan data dari marketplace, kerja dengan API, dan otomatisasi
Mari kita lihat tiga skenario praktis yang sering dihadapi oleh pengembang.
Skenario 1: Pengambilan harga dari marketplace
Saat memantau harga di Wildberries atau Ozon, penting untuk meniru perilaku pengguna nyata: mengirimkan header browser yang benar, menambahkan jeda antara permintaan, dan merotasi IP. Untuk tugas ini, proksi data center sangat cocok — mereka cepat dan murah saat bekerja dengan volume data besar.
import requests
import time
import random
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": "application/json, text/plain, */*",
"Accept-Language": "ru-RU,ru;q=0.9",
"Referer": "https://www.wildberries.ru/",
}
PROXIES = [
{"http": "http://user:[email protected]:8080",
"https": "http://user:[email protected]:8080"},
{"http": "http://user:[email protected]:8080",
"https": "http://user:[email protected]:8080"},
]
def get_product_price(article_id: int) -> dict:
"""Mendapatkan harga produk berdasarkan artikel dari Wildberries."""
url = f"https://card.wb.ru/cards/v1/detail?appType=1&curr=rub&nm={article_id}"
proxies = random.choice(PROXIES)
try:
resp = requests.get(url, headers=HEADERS, proxies=proxies, timeout=15)
resp.raise_for_status()
data = resp.json()
product = data["data"]["products"][0]
return {
"id": product["id"],
"name": product["name"],
"price": product["salePriceU"] / 100, # harga dalam kopecks
}
except (requests.RequestException, KeyError, IndexError) as e:
return {"error": str(e)}
# Mengambil beberapa artikel dengan jeda
articles = [12345678, 87654321, 11223344]
for article in articles:
result = get_product_price(article)
print(result)
time.sleep(random.uniform(1.5, 3.0)) # Jeda acak 1.5-3 detik
Skenario 2: Kerja dengan API melalui proksi
Beberapa API membatasi jumlah permintaan dari satu IP (batas permintaan). Distribusi permintaan antara beberapa proksi memungkinkan Anda untuk menghindari batasan ini:
import requests
import itertools
from typing import Optional
class ProxyAPIClient:
"""Klien untuk bekerja dengan API melalui rotasi proksi."""
def __init__(self, api_key: str, proxy_list: list):
self.api_key = api_key
self.proxy_cycle = itertools.cycle(proxy_list)
self.session = requests.Session()
self.session.headers.update({
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json",
})
def _get_proxy(self) -> dict:
proxy = next(self.proxy_cycle)
return {"http": proxy, "https": proxy}
def get(self, url: str, **kwargs) -> Optional[dict]:
proxies = self._get_proxy()
try:
resp = self.session.get(url, proxies=proxies, timeout=10, **kwargs)
resp.raise_for_status()
return resp.json()
except requests.RequestException as e:
print(f"Permintaan API gagal: {e}")
return None
# Penggunaan
proxy_list = [
"http://user:[email protected]:8080",
"http://user:[email protected]:8080",
]
client = ProxyAPIClient(api_key="your_api_key", proxy_list=proxy_list)
data = client.get("https://api.example.com/products")
Skenario 3: Pengujian geolokasi
Pemasar dan spesialis SEO sering memeriksa bagaimana situs terlihat dari berbagai wilayah. Dengan menggunakan proksi dari lokasi yang diperlukan, Anda dapat mengotomatisasi proses ini:
import requests
# Proksi dari berbagai wilayah
regional_proxies = {
"Moskow": "http://user:[email protected]:8080",
"Sankt-Peterburg": "http://user:[email protected]:8080",
"Novosibirsk": "http://user:[email protected]:8080",
"AS": "http://user:[email protected]:8080",
}
url = "https://example.com/prices"
for region, proxy_url in regional_proxies.items():
proxies = {"http": proxy_url, "https": proxy_url}
try:
resp = requests.get(url, proxies=proxies, timeout=15)
print(f"[{region}] Status: {resp.status_code} | "
f"Ukuran: {len(resp.content)} byte")
except requests.RequestException as e:
print(f"[{region}] Kesalahan: {e}")
Jenis proksi apa yang harus dipilih untuk tugas Anda
Pemilihan jenis proksi secara langsung mempengaruhi keberhasilan proyek Anda. Proksi data center yang murah mungkin bekerja dengan baik untuk beberapa tugas dan sepenuhnya gagal untuk yang lain. Berikut adalah panduan praktis untuk pemilihan:
| Tugas | Jenis proksi | Mengapa |
|---|---|---|
| Pengambilan data dari marketplace (Wildberries, Ozon) | Residensial | Tampak seperti pengguna biasa, lebih jarang diblokir |
| Pengambilan data terbuka, berita | Data center | Cepat, murah, cukup anonim |
| Kerja dengan API Facebook, Instagram | Mobile | Sosial media lebih percaya pada IP mobile |
| Pengujian geolokasi | Residensial dengan geotargeting | Geolokasi yang tepat, IP nyata dari wilayah yang dibutuhkan |
| Pengambilan data dengan beban tinggi (10k+ permintaan/jam) | Data center (pool) | Kecepatan dan biaya untuk volume besar |
| Otorisasi dan kerja dengan akun | Residensial atau mobile | Lebih sedikit pemicu sistem anti-fraud |
Untuk tugas di mana keandalan maksimum dan risiko minimal pemblokiran saat bekerja dengan situs yang dilindungi sangat penting, pengembang sering memilih proksi mobile — mereka menggunakan alamat IP dari operator seluler nyata (MTS, Beeline, MegaFon), yang sangat jarang masuk dalam daftar blokir.
Checklist pemeriksaan proksi sebelum digunakan
- ✅ Periksa IP melalui
httpbin.org/ip— apakah alamat asli Anda terlihat? - ✅ Periksa kecepatan — waktu respons tidak boleh melebihi 2-3 detik
- ✅ Pastikan proksi tidak ada dalam daftar blokir melalui
blocklist.deatauipqualityscore.com - ✅ Periksa geolokasi melalui
ipinfo.io— apakah sesuai dengan wilayah yang diharapkan? - ✅ Uji di situs target dengan satu permintaan sebelum menjalankan skrip penuh
- ✅ Pastikan lalu lintas HTTPS juga melalui proksi (kedua kunci dalam kamus)
Kesimpulan
Mengatur proksi di Python requests tidaklah sulit, tetapi memerlukan perhatian terhadap detail. Prinsip utama yang perlu diingat: selalu sebutkan kedua kunci (http dan https) dalam kamus proksi, gunakan Session untuk skenario multi-langkah, pastikan untuk menangani kesalahan dan waktu tunggu, dan simpan kredensial dalam variabel lingkungan, bukan dalam kode.
Untuk pengambilan data industri dengan ribuan permintaan per hari, daftar proksi manual tidak cukup — rotasi diperlukan. Jika Anda mengambil data dari marketplace yang dilindungi seperti Wildberries atau Ozon, bekerja dengan media sosial, atau menguji geolokasi, kami merekomendasikan untuk mencoba proksi residensial — mereka memberikan tingkat kepercayaan tinggi dari sistem anti-bot dan mendukung rotasi IP otomatis melalui satu endpoint, yang secara signifikan menyederhanakan kode skrip Anda.