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:
- Selenium Wire (Python): ekstensi Selenium yang merutekan lalu lintas melalui proxy lokalnya sendiri dan mendukung upstream terautentikasi:
Perhatikan bahwa Selenium Wire tidak lagi dipelihara secara aktif; masih berfungsi dengan Chrome saat ini bagi banyak orang, tetapi anggap sebagai solusi sementara.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) - Ekstensi Chrome yang dihasilkan yang mengatur proxy melalui
chrome.proxydan menjawabonAuthRequireddengan kredensial — pola yang terkenal; ekstensi adalah manifes plus beberapa baris skrip latar belakang, dimuat denganopts.add_extension(...). Tidak berfungsi dalam mode headless dengan Chrome lama (ekstensi tidak didukung di sana); berfungsi di headless=new saat ini. - Proxy penerusan lokal di
127.0.0.1yang menyimpan kredensial dan meneruskan ke upstream; arahkan Chrome ke sana tanpa autentikasi. Framework-agnostik dan kuat. - 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.webdriveradalahtruedi 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
| Playwright | Puppeteer | Selenium | |
|---|---|---|---|
| Proxy terautentikasi | Asli (bidang username/password) | page.authenticate() per halaman | Perlu solusi (Wire, ekstensi, penerus lokal) |
| Proxy berbeda per sesi | Per konteks, satu browser | Satu browser per proxy | Satu driver per proxy |
| SOCKS5 | Ya (tanpa kredensial → daftar putih) | Melalui bendera (tanpa kredensial) | Melalui opsi/preferensi |
| Lokal / zona waktu per sesi | Opsi konteks asli | API emulasi / bendera | Preferensi / CDP |
| Terbaik untuk | Scraping dan pengujian multi-identitas | Otomatisasi Chrome berbasis Node | Suite 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.