Framework otomatisasi browser semuanya menerima proxy sebagai opsi peluncuran, tetapi proxy terautentikasi memerlukan penanganan khusus karena Chromium tidak menerima user:pass@ di URL proxy: Playwright menerima kredensial sebagai bidang terpisah (dan dapat mengatur proxy berbeda per konteks browser), Puppeteer memerlukan page.authenticate(), dan Selenium memerlukan ekstensi atau penerus lokal. Panduan ini memberikan kode yang berfungsi untuk masing-masing, lalu membahas bagian yang lebih penting daripada sintaks: browser headless di belakang IP residensial masih dapat diidentifikasi kecuali bagian lain dari ceritanya cocok.

Satu fakta yang membentuk segalanya: Chromium mengabaikan kredensial proxy di URL

Alat baris perintah dan pustaka Python dengan senang hati menerima http://user:pass@host:port. Bendera --proxy-server Chromium hanya menerima host:port (dengan skema opsional); kredensial di dalamnya dibuang secara diam-diam. Ketika proxy menjawab 407, browser menampilkan dialog autentikasi — yang tidak diawasi oleh skrip otomatisasi mana pun. Oleh karena itu, setiap framework memiliki cara sendiri untuk memasok nama pengguna dan kata sandi, dan di situlah sebagian besar masalah “proxy berfungsi di curl tetapi tidak di skrip browser saya” berasal. Firefox lebih toleran di beberapa jalur, tetapi mekanisme khusus framework di bawah ini berfungsi di semua mesin.

Playwright

Playwright memiliki dukungan proxy kelas satu dengan bidang kredensial terpisah, dan — fitur yang menjadikannya pilihan terbaik untuk pekerjaan multi-identitas — proxy dapat diatur per konteks browser, sehingga satu proses browser dapat menampung beberapa sesi terisolasi yang masing-masing keluar dari IP yang berbeda.

Python

from playwright.sync_api import sync_playwright

PROXY = {"server": "http://proxy.example.com:8080",
         "username": "user", "password": "pass"}

with sync_playwright() as p:
    # opsi A: satu proxy untuk seluruh browser
    browser = p.chromium.launch(proxy=PROXY)
    page = browser.new_page()
    page.goto("https://api.ipify.org?format=json")
    print(page.text_content("body"))
    browser.close()

    # opsi B: proxy berbeda per konteks (satu browser, banyak identitas)
    browser = p.chromium.launch(proxy={"server": "per-context"})   # placeholder; proxy asli berasal dari konteks
    ctx_de = browser.new_context(proxy={"server": "http://gate.provider.com:7777",
                                        "username": "customer-country-de-session-a1", "password": "pass"},
                                 locale="de-DE", timezone_id="Europe/Berlin")
    ctx_us = browser.new_context(proxy={"server": "http://gate.provider.com:7777",
                                        "username": "customer-country-us-session-b2", "password": "pass"},
                                 locale="en-US", timezone_id="America/New_York")
    for ctx in (ctx_de, ctx_us):
        pg = ctx.new_page(); pg.goto("https://api.ipify.org?format=json"); print(pg.text_content("body"))
    browser.close()

Dua detail. Proxy per konteks di Chromium mengharuskan browser diluncurkan dengan opsi proxy (nilai apa pun — placeholder yang didokumentasikan adalah {"server": "per-context"}); tanpanya, konteks tidak dapat menimpanya. Dan perhatikan locale dan timezone_id diatur bersama proxy: IP Jerman dengan zona waktu Amerika adalah kontradiksi yang dibobot oleh sistem anti-bot, seperti yang dijelaskan dalam cara kerja sistem anti-bot. Proxy SOCKS5 didukung ("server": "socks5://host:1080") tetapi Chromium tidak mengirim kredensial ke proxy SOCKS, jadi gunakan autentikasi daftar putih IP dengan SOCKS.

Node.js

const { chromium } = require('playwright');

(async () => {
  const browser = await chromium.launch({ proxy: { server: 'per-context' } });
  const context = await browser.newContext({
    proxy: { server: 'http://gate.provider.com:7777',
             username: 'customer-country-de-session-a1', password: 'pass' },
    locale: 'de-DE', timezoneId: 'Europe/Berlin',
  });
  const page = await context.newPage();
  await page.goto('https://api.ipify.org?format=json');
  console.log(await page.textContent('body'));
  await browser.close();
})();

Bidang bypass Playwright ("bypass": "localhost,*.internal") mengecualikan host dari proxy, dan launch_persistent_context() menerima opsi proxy yang sama jika Anda memerlukan direktori profil persisten.

Puppeteer

Puppeteer meneruskan proxy sebagai bendera Chromium dan mengautentikasi per halaman:

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch({
    args: ['--proxy-server=http://proxy.example.com:8080'],
  });
  const page = await browser.newPage();
  await page.authenticate({ username: 'user', password: 'pass' });   // menjawab 407 untuk halaman ini
  await page.goto('https://api.ipify.org?format=json');
  console.log(await page.evaluate(() => document.body.innerText));
  await browser.close();
})();

page.authenticate() harus dipanggil sebelum navigasi dan di setiap halaman (tab) yang akan menggunakan proxy. Proxy bersifat browser-wide — Puppeteer tidak memiliki pengaturan proxy per konteks seperti Playwright. Untuk beberapa identitas, Anda memiliki tiga opsi: luncurkan beberapa proses browser (satu proxy masing-masing; berat tetapi sederhana), gunakan --proxy-server yang menunjuk ke proxy switching lokal yang merutekan berdasarkan penanda tertentu, atau pindah ke Playwright. Juga berguna: --proxy-bypass-list=<-loopback> jika Anda perlu memproksi localhost juga, dan puppeteer-extra dengan plugin proxy-nya, yang menangani autentikasi dan dapat berputar per halaman.

Selenium

Selenium mengatur proxy melalui opsi browser. Proxy tanpa autentikasi (daftar putih IP) satu baris; yang terautentikasi adalah kasus yang rumit.

Chrome, autentikasi daftar putih

from selenium import webdriver

opts = webdriver.ChromeOptions()
opts.add_argument("--proxy-server=http://proxy.example.com:8080")
driver = webdriver.Chrome(options=opts)
driver.get("https://api.ipify.org?format=json")
print(driver.find_element("tag name", "body").text)
driver.quit()

Chrome, nama pengguna/kata sandi

Protokol WebDriver Selenium tidak memiliki kait untuk menjawab 407 proxy. Solusi standar:

  1. Selenium Wire (Python): ekstensi Selenium yang merutekan lalu lintas melalui proxy lokalnya sendiri dan mendukung upstream terautentikasi:
    from seleniumwire import webdriver   # pip install selenium-wire
    opts = {"proxy": {"http": "http://user:pass@proxy.example.com:8080",
                      "https": "http://user:pass@proxy.example.com:8080"}}
    driver = webdriver.Chrome(seleniumwire_options=opts)
    Perhatikan bahwa Selenium Wire tidak lagi dipelihara secara aktif; masih berfungsi dengan Chrome saat ini bagi banyak orang, tetapi anggap sebagai solusi sementara.
  2. Ekstensi Chrome yang dihasilkan yang mengatur proxy melalui chrome.proxy dan menjawab onAuthRequired dengan kredensial — pola yang terkenal; ekstensi adalah manifes plus beberapa baris skrip latar belakang, dimuat dengan opts.add_extension(...). Tidak berfungsi dalam mode headless dengan Chrome lama (ekstensi tidak didukung di sana); berfungsi di headless=new saat ini.
  3. Proxy penerusan lokal di 127.0.0.1 yang menyimpan kredensial dan meneruskan ke upstream; arahkan Chrome ke sana tanpa autentikasi. Framework-agnostik dan kuat.
  4. Autentikasi daftar putih dari penyedia, jika mesin Anda memiliki IP statis — menghindari masalah sepenuhnya.

Firefox

opts = webdriver.FirefoxOptions()
opts.set_preference("network.proxy.type", 1)
opts.set_preference("network.proxy.http", "proxy.example.com");  opts.set_preference("network.proxy.http_port", 8080)
opts.set_preference("network.proxy.ssl",  "proxy.example.com");  opts.set_preference("network.proxy.ssl_port", 8080)
opts.set_preference("network.proxy.socks_remote_dns", True)     # DNS jarak jauh jika menggunakan SOCKS
driver = webdriver.Firefox(options=opts)

Firefox masih akan memunculkan dialog autentikasi untuk proxy nama pengguna/kata sandi; pendekatan penerus lokal atau daftar putih berlaku.

Apa yang tidak diperbaiki proxy di browser headless

Browser asli membawa Anda melewati sidik jari TLS dan HTTP/2 — jabat tangan benar-benar milik Chrome (lihat sidik jari TLS). Itu tidak, dengan sendirinya, membawa Anda melewati lapisan JavaScript:

  • navigator.webdriver adalah true di bawah otomatisasi; situs memeriksanya terlebih dahulu.
  • Mode headless memiliki perbedaan rendering dan API (plugin hilang, string renderer WebGL tertentu, dimensi jendela) yang diuji oleh skrip sidik jari. Headless baru Chrome (headless=new) jauh lebih dekat dengan headful tetapi tidak identik.
  • WebRTC masih dapat mengekspos IP asli mesin kecuali dinonaktifkan atau dipalsukan; proxy tidak menyentuhnya. Uji — Cara menguji proxy.
  • Zona waktu, lokal, dan geolokasi berasal dari mesin kecuali Anda mengaturnya (Playwright: timezone_id, locale, geolocation); ketidakcocokan dengan negara proxy adalah tanda klasik.
  • Perilaku: navigasi instan, tanpa gerakan mouse, waktu yang identik setiap kali dijalankan.

Plugin siluman (puppeteer-extra-plugin-stealth, playwright-stealth) menambal artefak yang paling jelas; browser antideteksi melangkah lebih jauh dengan memberikan sidik jari yang koheren per profil dan mengekspos port debugging yang dilampirkan skrip Playwright/Puppeteer Anda — yang merupakan jawaban produksi untuk pekerjaan akun. Lihat apa itu browser antideteksi dan, untuk memilih jenis IP di belakang setiap profil, peringkat proxy antideteksi kami.

Memilih framework untuk pekerjaan proxy

PlaywrightPuppeteerSelenium
Proxy terautentikasiAsli (bidang username/password)page.authenticate() per halamanPerlu solusi (Wire, ekstensi, penerus lokal)
Proxy berbeda per sesiPer konteks, satu browserSatu browser per proxySatu driver per proxy
SOCKS5Ya (tanpa kredensial → daftar putih)Melalui bendera (tanpa kredensial)Melalui opsi/preferensi
Lokal / zona waktu per sesiOpsi konteks asliAPI emulasi / benderaPreferensi / CDP
Terbaik untukScraping dan pengujian multi-identitasOtomatisasi Chrome berbasis NodeSuite lama, grid lintas browser

Pertanyaan yang sering diajukan

Bagaimana cara menggunakan proxy terautentikasi di Playwright?

Berikan proxy={"server": "http://host:port", "username": "…", "password": "…"} ke launch() atau, per konteks, ke new_context() (luncurkan dengan proxy={"server": "per-context"} terlebih dahulu).

Bagaimana cara menggunakan proxy dengan autentikasi di Puppeteer?

Luncurkan dengan args: ['--proxy-server=host:port'] dan panggil await page.authenticate({username, password}) sebelum page.goto() di setiap halaman.

Mengapa Chrome mengabaikan user:pass@ di --proxy-server?

Bendera Chromium hanya menerima skema://host:port; kredensial tidak diuraikan. Ia merespons 407 proxy dengan dialog interaktif, jadi otomatisasi harus memasok kredensial melalui mekanisme framework sebagai gantinya.

Bisakah saya menggunakan proxy berbeda untuk setiap tab?

Tidak per tab. Playwright melakukannya per konteks browser (setiap konteks adalah sesi terisolasi); Puppeteer dan Selenium memerlukan satu instance browser per proxy, atau proxy switching lokal.

Apakah proxy membuat Chrome headless tidak terdeteksi?

Tidak. Ini memperbaiki lapisan IP dan, karena browser asli, lapisan TLS. Bendera otomatisasi, artefak headless, WebRTC, ketidakcocokan zona waktu, dan perilaku adalah sinyal terpisah yang memerlukan penanganan terpisah.

Haruskah proxy residensial atau datacenter untuk otomatisasi browser?

Apapun yang dibutuhkan kebijakan IP target — browser tidak mengubah kalkulus itu. Datacenter jika ditoleransi; residensial atau seluler di situs yang dilindungi; statis (ISP) untuk profil masuk yang persisten. Lihat perbandingan jenis proxy.