Kembali ke blog

Cara Mengatur Proxy di Python Requests untuk Parsing, API, dan Automatisasi: Panduan Lengkap dengan Contoh Kode

Panduan lengkap untuk menghubungkan proxy di pustaka Python requests — dari pengaturan dasar hingga rotasi IP dan mengatasi pemblokiran saat pengambilan data dan otomatisasi.

📅3 April 2026
```html

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.de atau ipqualityscore.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.

```