Başlatma argümanlarına, cURL'de alıştığınız gibi --proxy-server=http://user:pass@host:port yazıyorsunuz ve ilk page.goto() çağrısı net::ERR_NO_SUPPORTED_PROXIES hatasıyla duruyor. Kimlik bilgilerini adresten çıkarınca bu kez net::ERR_INVALID_AUTH_CREDENTIALS geliyor. Puppeteer'ın kendine ait bir proxy seçeneği yoktur. Chrome'u başlatır, proxy'nin nasıl kullanılacağına Chrome karar verir; bu yüzden cevapların çoğu Puppeteer'ın API'sinde değil, Chrome'un kurallarındadır.
Bu yazıda başlatma bayrağını ve page.authenticate() çağrısını, her browser context için ayrı proxy'yi, sticky ve rotating oturumları, SOCKS5'i, bypass listesini, çıkış IP'sinin kontrolünü, karşınıza çıkacak hataları ve yeniden denemeli tam bir betiği ele alıyoruz. Bütün örnekleri 6 Ekim 2026'da, Puppeteer 25.12.0 ve onun indirdiği Chrome 154 ile çalıştırdık. Test düzeneğinde kullanıcı adı ve parola isteyen yerel bir HTTP proxy'si ve yerel bir SOCKS5 sunucusu vardı; aktardığımız hata mesajları bu testlerde aldıklarımızdır.
Puppeteer trafiği proxy'den nasıl geçirir?
Puppeteer, gerçek bir tarayıcıyı koddan yöneten bir Node.js kütüphanesidir. Ağ bağlantılarını kendisi açmaz, tarayıcı açar. Dolayısıyla proxy bir Chrome ayarıdır ve iki yerde verilir: tarayıcı başlarken komut satırı bayrağı olarak ya da bir browser context oluşturulurken seçenek olarak. Browser context (tarayıcı bağlamı), tek tarayıcının içinde kendi çerezleri, önbelleği ve depolaması olan yalıtılmış bir oturumdur; gizli pencereye benzer. Yazının devamında kısaca context diyeceğiz.
Proxy'ye giriş ayrı bir adımdır, çünkü Chrome proxy adresindeki kimlik bilgisini okumaz. Test proxy'mizin tek bir HTTPS sayfası için kaydettiği sıra şöyleydi:
- Chrome proxy'ye
CONNECT httpbin.org:443gönderir, yani siteye bir tünel açmasını ister.http://ile başlayan bir sayfada isteğin kendisini gönderir. - İstekte kimlik bilgisi olmadığı için proxy
407 Proxy Authentication Requiredcevabı verir. RFC 9110, 407'yi 401'in proxy'deki karşılığı olarak tanımlar. - Puppeteer bu doğrulama talebini yakalar ve
page.authenticate()çağrısına verilen kullanıcı adı ve parolayla cevaplar. - Chrome isteği
Proxy-Authorizationbaşlığıyla tekrarlar, proxy200döner ve siteyle şifreli bağlantı tünelin içinde kurulur. Proxy sayfanın içeriğini değil, yalnızca sunucu adını görür. - Chrome kimlik bilgisini context'in kimlik doğrulama önbelleğine yazar ve sonraki bağlantılarda doğrudan gönderir.
Aşağıdaki testlerde kimlik bilgisinin sayfaya değil context'e ait çıkmasının nedeni bu beşinci adımdır.
--proxy-server ve page.authenticate() ile proxy nasıl ayarlanır?
npm i puppeteer kütüphaneyi kurar ve onunla uyumlu bir Chrome indirir; puppeteer-core ise indirme yapmayan aynı API'dir. En sade kurulum şöyledir:
import puppeteer from "puppeteer";
const browser = await puppeteer.launch({
args: ["--proxy-server=http://pr.proxynet.io:8000"],
});
const page = await browser.newPage();
await page.authenticate({ username: "user", password: "pass" });
await page.goto("https://httpbin.org/ip");
console.log(await page.$eval("body", (el) => el.innerText)); // sitenin gördüğü çıkış IP'si
await browser.close();Bayraktaki http:// sayfaları değil, proxy'ye giden bağlantıyı anlatır. HTTP proxy https:// siteleri de tünel üzerinden taşır ve içerik Chrome ile site arasında şifreli kalır. page.authenticate() belgesi bir not ekler: Puppeteer bu iş için arka planda istek yakalamayı (request interception) açar, bu da performansı biraz etkileyebilir; null verildiğinde kapanır.
Testlerde üç şey ters gitti ve her birinin net bir kuralı var:
page.authenticate()ilkgoto()çağrısından önce gelmeli. Sonra çağrıldığında ilk gezinmenet::ERR_INVALID_AUTH_CREDENTIALSile düştü, ikincisi ise geçti.- Kimlik bilgisi bayrağa yazılmamalı. Adreste
user:pass@olunca Chrome 154 değerin tamamını reddetti venet::ERR_NO_SUPPORTED_PROXIESverdi. Eski rehberler burada407aldığınızı yazar; bugünkü sürümde istek proxy'ye hiç ulaşmıyor. Proxy-Authorizationbaşlığını kendiniz göndermeyin. Başlığıpage.setExtraHTTPHeaders()ile eklediğimizde Chrome gezinmeyinet::ERR_INVALID_ARGUMENTile reddetti.
--proxy-server değeri | Chrome 154'teki sonuç |
|---|---|
http://pr.proxynet.io:8000 | Çalışır; HTTPS sayfalar CONNECT tünelinden geçer |
pr.proxynet.io:8000 | Çalışır; şema yazılmazsa Chrome HTTP proxy varsayar |
http://user:pass@pr.proxynet.io:8000 | net::ERR_NO_SUPPORTED_PROXIES |
socks5://host:port | Yalnızca sunucu parola istemiyorsa çalışır |
socks5h://host:port | net::ERR_NO_SUPPORTED_PROXIES; Chrome bu şemayı tanımaz |
Her browser context'e ayrı proxy nasıl verilir?
Puppeteer 22, eski rehberlerde hâlâ geçen createIncognitoBrowserContext() adını browser.createBrowserContext() olarak değiştirdi. Bu çağrının BrowserContextOptions seçeneklerinde iki proxy alanı var: proxyServer ve proxyBypassList. Tarayıcı proxy'siz başlayabilir, her context kendi proxy'sini alır:
import puppeteer from "puppeteer";
const PROXY = "http://pr.proxynet.io:8000";
// Her context'e bir sticky oturum: aynı oturum kimliği, 600 saniyeye kadar aynı çıkış IP'si
const sessions = ["a1b2c3", "d4e5f6"];
const browser = await puppeteer.launch(); // tarayıcının kendisi proxy'siz başlar
for (const id of sessions) {
const context = await browser.createBrowserContext({ proxyServer: PROXY });
const page = await context.newPage();
await page.authenticate({ username: `user-session-${id}-ttl-600`, password: "pass" });
for (let i = 0; i < 2; i++) {
await page.goto("https://httpbin.org/ip");
console.log(id, await page.$eval("body", (el) => el.innerText));
}
await context.close(); // çerezler, önbellek ve proxy ayarı context'le birlikte kapanır
}
await browser.close();Test proxy'miz çıkış adreslerini, bir ağ geçidinin (gateway) yaptığı gibi oturum kimliğine göre dağıtıyor. Denemede iki context iki ayrı adresten çıktı ve her biri ikinci istekte de kendi adresinde kaldı. Gerçek işler için iki sonuç daha önemli:
- Kimlik bilgisi sayfaya değil, context'e aittir. Aynı context'te açtığımız ikinci sayfa
page.authenticate()çağrısını başka bir kullanıcı adıyla yaptı, ama gönderdiği her istek yine ilk kullanıcı adını taşıdı. Bu çağrıyı hiç yapmayan bir sayfa da aynı önbellekteki bilgiyle geçti. proxySerververilmeyen context, başlatma bayrağındaki proxy'yi devralır ama kendi kimlik bilgisini tutar. Tarayıcıda--proxy-servervarken kendi oturum kimliğiyle giriş yapan iki context yine iki ayrı çıkış IP'si aldı.
--proxy-server bayrağı | createBrowserContext({ proxyServer }) | |
|---|---|---|
| Kapsam | Bütün tarayıcı | Yalnızca o context |
| Tek tarayıcıda ayrı çıkışlar | Evet, her context'e bir kullanıcı adı | Evet, hatta ayrı proxy sunucuları |
| Proxy'yi değiştirmek | Tarayıcıyı yeniden başlatmak | Context'i kapatıp yenisini açmak |
| Uygun olduğu iş | Tek betik, tek çıkış | Paralel çalışan çok sayıda bağımsız oturum |
Buradan çıkan kural: bir oturum, bir context, bir kullanıcı adı.
Rotating mi sticky mi: tarayıcıya hangi oturum türü uyar?
Tarayıcı bir sayfa için tek istek göndermez. Bir ürün sayfası; HTML belgesini, betikleri, stil dosyalarını, görselleri ve arka plandaki API çağrılarını çoğu zaman birkaç sunucudan ve birkaç bağlantı üzerinden çeker. Rotating bir ağ geçidinde her yeni bağlantı yeni bir çıkış IP'si alabilir; testimizde sayfanın favicon'u bile sayfadan farklı bir adresten çıktı. Birbirinden bağımsız sayfalarda bunun zararı yoktur. Girişte, sepette ya da çok adımlı bir formda ise site tek bir ziyaretçinin adresler arasında atladığını görür ve oturumu sonlandırabilir.
Ağ geçidi oturum türünü kullanıcı adından okur; tam kullanıcı adını paneldeki Endpoint Oluşturucu sizin için yazar. Parçaları kolay okunur: -country-de çıkış ülkesini seçer (şehir de aynı araçtan seçilir), -session-a1b2c3-ttl-600 o oturum kimliğini verilen saniye boyunca aynı çıkışta tutar; süre 1 ile 60 dakika arasında olabilir. Oturum parçası olmayan kullanıcı adı ise rotating çalışır.
Kategori listesi ya da arama sonucu gibi bağımsız sayfalar için Rotating Proxy kullanın ve bu sayfaları kısa ömürlü context'lerde açın.
Durum tutan her iş için Sticky Proxy kullanın: tek context ve süresi akıştan uzun tutulan tek oturum kimliği. İş bitince context'i kapatın ki çerezler ve IP birlikte sona ersin.
Rotasyon bağımsız işi farklı çıkışlara dağıtır; bir sitenin sınırlarını aşmanın yolu değildir. 429 Too Many Requests ya da 403 Forbidden cevabı yavaşlamanızı ister ve yeni bir IP bu cevabı değiştirmez.
Puppeteer SOCKS5 proxy ile çalışır mı?
Çalışır, ama kullanıcı adı ve parola olmadan. Chromium'un proxy belgesi, SOCKSv5 için hiçbir kimlik doğrulama yönteminin desteklenmediğini açıkça yazar. Yerel SOCKS5 sunucumuz aynı şeyi öbür taraftan gördü: Chrome bağlantının açılış mesajında yalnızca 0x00 yöntemini, yani "kimlik doğrulama yok" seçeneğini sundu. Kullanıcı adı ve parola yöntemini (0x02) şart koşan sunucu bu teklifi reddetmek zorunda kaldı ve gezinme net::ERR_SOCKS_CONNECTION_FAILED ile düştü. SOCKS5'te Puppeteer'ın cevaplayacağı 407 benzeri bir talep olmadığından page.authenticate() bir şey değiştirmedi.
Çözüm, kim olduğunuzu parola yerine IP adresinizle kanıtlamaktır. Chrome'u çalıştıran makinenin genel IP adresini paneldeki IP whitelist'e ekleyin (en fazla 10 adres), Endpoint Oluşturucu'nun gösterdiği SOCKS5 portunu alın ve tarayıcıyı kimlik bilgisi olmadan başlatın:
import puppeteer from "puppeteer";
// Kullanıcı adı ve parola yok: bu makinenin genel IP'si IP whitelist'te olmalı.
// SOCKS5_PORT: Endpoint Oluşturucu'nun gösterdiği SOCKS5 portu.
const { SOCKS5_PORT } = process.env;
const browser = await puppeteer.launch({
args: [`--proxy-server=socks5://pr.proxynet.io:${SOCKS5_PORT}`],
});
const page = await browser.newPage();
await page.goto("https://httpbin.org/ip");
console.log(await page.$eval("body", (el) => el.innerText));
await browser.close();Chrome SOCKS5 sunucusuna IP adresi değil, sunucu adı gönderdi; yani DNS çözümlemesi proxy tarafında yapılıyor ve cURL'den bilinen socks5h:// alışkanlığına gerek kalmıyor. Web sayfaları için HTTP proxy çoğu zaman daha sade bir seçimdir, çünkü page.authenticate() ile çalışır.
Bazı adresler proxy'nin dışında nasıl tutulur?
--proxy-bypass-list bayrağı ya da context'te dizi olarak verilen proxyBypassList, Chrome'un doğrudan bağlanacağı sunucuları listeler. Bayrakta kurallar noktalı virgül ya da virgülle ayrılır: --proxy-bypass-list=*.internal.example;192.168.0.0/16. Testimizde listedeki sunucu proxy'ye hiç uğramadı, adı yerel makinede çözümlendi.
Chrome'un örtük kuralları da vardır: localhost, *.localhost, 127.0.0.1/8 ve [::1] liste boş olsa bile proxy'yi kullanmaz. Yerel bir sunucuyla test ederken proxy kaydı sessiz kalıyorsa nedeni budur. Özel <-loopback> kuralı bu örtük kuralları kaldırır; onu eklediğimizde 127.0.0.1 adresine giden isteğimiz proxy'den geçti.
Çıkış IP'si nasıl kontrol edilir?
Aynı tarayıcıda doğrudan bağlanan bir context'i proxy'li bir context'le karşılaştırın. Adresler farklıysa trafik proxy'den geçiyordur:
import puppeteer from "puppeteer";
async function exitIp(context, credentials) {
const page = await context.newPage();
if (credentials) await page.authenticate(credentials);
await page.goto("https://httpbin.org/ip");
const { origin } = JSON.parse(await page.$eval("body", (el) => el.innerText));
await page.close();
return origin;
}
const browser = await puppeteer.launch();
const direct = await browser.createBrowserContext();
const proxied = await browser.createBrowserContext({ proxyServer: "http://pr.proxynet.io:8000" });
const own = await exitIp(direct);
const viaProxy = await exitIp(proxied, { username: "user", password: "pass" });
console.log({ own, viaProxy, proxyWorks: own !== viaProxy });
await browser.close();Belirli bir ülkeyi hedefliyorsanız çıkış IP'sini bir IP konum servisinde de sorgulayın. Kontrol başarısız olursa Chrome'u devreden çıkarın: Proxy Çalışıyor mu? Proxy Nasıl Test Edilir? yazısındaki komut satırı testleri, sorunun ağda mı kodda mı olduğunu ayırır.
Hangi hataları görürsünüz, ne anlama gelirler?
Aşağıdakilerin her birini yerel test düzeneğinde kendimiz ürettik:
| Ne görüyorsunuz | Ne oldu | Ne yapmalı |
|---|---|---|
net::ERR_PROXY_CONNECTION_FAILED | Chrome proxy'ye ulaşamadı: sunucu ya da port yanlış veya giden trafik engelli | Adresi ve portu kontrol edin; yeniden denemek işe yaramaz |
net::ERR_INVALID_AUTH_CREDENTIALS | Proxy giriş istedi, Chrome'da kimlik bilgisi yoktu | İlk goto() çağrısından önce page.authenticate() çağırın |
goto() 407 durum koduyla dönüyor | Parola yanlış; Puppeteer bir kez denedi ve vazgeçti | response.status() değerine bakın, kimlik bilgisini düzeltin |
net::ERR_TUNNEL_CONNECTION_FAILED | Giriş başarılı, ama proxy siteye tünel açamadı | Hedef adresi kontrol edin |
net::ERR_NO_SUPPORTED_PROXIES | Chrome --proxy-server değerini reddetti | user:pass@ kısmını silin, http:// ya da socks5:// kullanın |
net::ERR_SOCKS_CONNECTION_FAILED | SOCKS5 sunucusu parola istiyor ya da IP'niz whitelist'te değil | IP'nizi whitelist'e ekleyin ya da HTTP portunu kullanın |
| Sayfa açılıyor ama IP sizin | Bir bypass kuralı ya da loopback adresi yüzünden proxy atlandı | Bypass listesine ve <-loopback> kuralına bakın |
En uzun süre gözden kaçan, yanlış parola satırıdır: hiçbir yerde hata fırlatılmaz ve betik proxy'nin 407 sayfasıyla devam eder. Masaüstü tarayıcıda tünel hatasının, antivirüsün HTTPS taramasından eskide kalmış bir sistem proxy ayarına kadar başka nedenleri de olabilir; bunlar için err_tunnel_connection_failed Hatası Nedir, Nasıl Çözülür? yazısına bakın. Geliştirme sırasında şu iki dinleyici, zaman aşımının arkasındaki gerçek hatayı gösterir:
page.on("requestfailed", (req) => console.log("BAŞARISIZ", req.url(), req.failure()?.errorText));
page.on("response", (res) => res.status() >= 400 && console.log(res.status(), res.url()));Tam örnek: paralel context'ler, sticky oturumlar ve yeniden deneme
Aşağıdaki betik, JavaScript ile oluşturulan altı sayfayı aynı anda en fazla üç context'le açar. Her deneme yeni bir context ve yeni bir sticky oturum alır; böylece çerezler ve çıkış IP'si birlikte değişir. Trafikten tasarruf için görsel, medya ve font istekleri engellenir; page.setRequestInterception() ile yapılan bu engelleme page.authenticate() çağrısını bozmaz. Zaman aşımları ve tünel hataları üstel bekleme (exponential backoff) ile yeniden denenir; yapılandırma hataları ve siteden gelen 403 ya da 429 ise işi durdurur.
import puppeteer from "puppeteer";
const PROXY = "http://pr.proxynet.io:8000";
const USER = "user";
const PASS = "pass";
const URLS = Array.from({ length: 6 }, (_, i) => `https://quotes.toscrape.com/js/page/${i + 1}/`);
const CONCURRENCY = 3; // aynı anda açık context sayısı
const ATTEMPTS = 3;
const BLOCKED = new Set(["image", "media", "font"]);
// Yapılandırma hataları: beklemek ve yeniden denemek bunları düzeltmez
const FATAL = ["ERR_PROXY_CONNECTION_FAILED", "ERR_NO_SUPPORTED_PROXIES", "ERR_INVALID_AUTH_CREDENTIALS"];
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
async function scrape(browser, url) {
for (let attempt = 1; attempt <= ATTEMPTS; attempt++) {
// Her denemeye bir context: kendi çerezleri ve kendi sticky oturumu (tek çıkış IP'si)
const context = await browser.createBrowserContext({ proxyServer: PROXY });
try {
const page = await context.newPage();
const session = crypto.randomUUID().slice(0, 8);
await page.authenticate({ username: `${USER}-session-${session}-ttl-300`, password: PASS });
await page.setRequestInterception(true);
page.on("request", (req) => (BLOCKED.has(req.resourceType()) ? req.abort() : req.continue()));
const res = await page.goto(url, { waitUntil: "domcontentloaded", timeout: 30_000 });
const status = res ? res.status() : 0;
if (status === 403 || status === 429) {
// Site reddediyor ya da yavaşlamanızı istiyor: çözüm yeni bir IP değil
throw Object.assign(new Error(`HTTP ${status}: durun ve istek hızını düşürün`), { fatal: true });
}
if (status >= 400) throw new Error(`HTTP ${status}`);
await page.waitForSelector("div.quote span.text", { timeout: 10_000 }); // JavaScript ile oluşuyor
return await page.$$eval("div.quote span.text", (els) => els.map((el) => el.textContent));
} catch (err) {
err.fatal ||= FATAL.some((code) => err.message.includes(code));
if (err.fatal || attempt === ATTEMPTS) throw err;
await sleep(2 ** attempt * 1000 + Math.random() * 1000); // sonraki denemeden önce bekle
} finally {
await context.close();
}
}
}
const browser = await puppeteer.launch();
const queue = [...URLS];
const results = new Map();
await Promise.all(
Array.from({ length: CONCURRENCY }, async () => {
while (queue.length) {
const url = queue.shift();
try {
results.set(url, `${(await scrape(browser, url)).length} alıntı`);
} catch (err) {
results.set(url, `HATA ${err.message.split("\n")[0]}`);
if (err.fatal) queue.length = 0; // yalnız bu sayfayı değil, bütün işi durdur
}
}
}),
);
await browser.close();
for (const url of URLS) console.log(url, results.get(url) ?? "atlandı");Yerel test proxy'si üzerinden altı sayfanın hepsi onar alıntıyla döndü; iş beş saniyeden kısa sürdü. Proxy portunu bilerek yanlış yazdığımızda o anda işlenen üç sayfa yeniden denenmeden, hemen net::ERR_PROXY_CONNECTION_FAILED ile durdu, kalan üçü atlandı; 429 dönen yerel bir test sayfası da işi aynı şekilde bitirdi. CONCURRENCY değerine düşük başlayın: her context bellek tutar, hedef sitenin de kaldırabileceği bir yük sınırı vardır.
Kullanım alanları
- Düz bir HTTP istemcisinin boş gördüğü, JavaScript ile yüklenen katalog ve fiyat sayfaları.
- Kendi sitenizin, fiyatlarınızın ya da çerez bildiriminizin başka bir ülkeden nasıl göründüğünü kontrol etmek; her ülkeye bir context.
- Herkese açık sayfaların, belirli bir ülkedeki ziyaretçinin gördüğü hâliyle ekran görüntüsü ve PDF'i.
- Kendi sayfalarınızı ve ödeme akışlarınızı ağınızın dışından düzenli olarak izlemek.
Hepsinde aynı çerçeve geçerlidir: sitenin robots.txt kurallarına ve kullanım şartlarına uyun, resmî bir API varsa onu kullanın ve istek hızını sitenin kaldırabileceği düzeyde tutun.
Sık yapılan hatalar
--proxy-serverdeğerineuser:pass@yazmak. Chrome değerinet::ERR_NO_SUPPORTED_PROXIESile reddeder.- Her sayfada yeni bir kullanıcı adının geçerli olacağını sanmak. Chrome ilk kimlik bilgisini bütün context boyunca tutar; her oturuma bir context açın.
- SOCKS5'te parola denemek. Chrome yalnızca "kimlik doğrulama yok" seçeneğini sunar; IP whitelist ya da HTTP portu kullanın.
localhostüzerinde test edip sonuca güvenmek. Loopback adresleri,<-loopback>eklenmedikçe proxy'yi atlar.407cevabını sayfa sanmak. Yanlış parola hata fırlatmaz;response.status()değerine bakın.429ya da403sonrasında IP değiştirmek. Bunun yerine yavaşlayın; sınır adresinizle değil, davranışınızla ilgilidir.- Context'leri açık bırakmak. Her biri bellek tutar;
finallybloğunda kapatın.
Karar rehberi
| İhtiyaç | Öneri |
|---|---|
| Tek betik, tek çıkış | --proxy-server bayrağı ve page.authenticate() |
| Tek tarayıcıda çok sayıda bağımsız oturum | createBrowserContext({ proxyServer }), her context'e bir oturum kimliği |
| Birbirine bağlı olmayan toplu sayfalar | Rotating kullanıcı adı, kısa ömürlü context'ler |
| Giriş, sepet ya da çok adımlı form | Akıştan uzun süren sticky oturum, tek context |
| SOCKS5 zorunlu | IP whitelist, kimlik bilgisi yok |
| Yalnızca başlatma bayrağını kabul eden bir araç | IP whitelist ya da proxy-chain gibi yerel bir aktarıcı |
| İç sunucular doğrudan bağlanmalı | --proxy-bypass-list ya da proxyBypassList |
Sıkça sorulan sorular
puppeteer.launch() çağrısının proxy seçeneği var mı?
Hayır. Proxy, Chrome'un --proxy-server bayrağı olarak args dizisine; giriş bilgisi ise page.authenticate() çağrısına yazılır. Puppeteer'ın kendi API'sinde proxy alanları yalnızca browser.createBrowserContext() çağrısında bulunur: proxyServer ve proxyBypassList.
Her sayfaya ayrı proxy verilebilir mi?
Aynı context içinde verilemez. Proxy ve önbellekteki kimlik bilgisi context'e aittir; testimizde farklı kimlik bilgisi verilen ikinci sayfa yine ilkini kullandı. Kendi çıkışı olması gereken her sayfayı kendi context'inde açın; context açmak yeni bir tarayıcı başlatmaktan çok daha ucuzdur.
proxy-chain nedir, gerekli mi?
proxy-chain, açık kaynaklı bir Node.js paketidir. anonymizeProxy() fonksiyonu parolasız yerel bir proxy başlatır ve trafiği kimlik bilgileriyle birlikte asıl proxy'ye aktarır; Chrome'a da yalnızca sade bir http://127.0.0.1:<port> adresi verilir. Testimizde parola isteyen hem HTTP hem SOCKS5 proxy'yle çalıştı. page.authenticate() ya da IP whitelist kullanıyorsanız buna ihtiyacınız yoktur.
Tarayıcıyı yeniden başlatmadan proxy değiştirilebilir mi?
Evet, context'lerle. Context'i kapatın, başka bir proxyServer ya da oturum kimliğiyle yenisini açın ve page.authenticate() çağrısını tekrarlayın. Tarayıcının ömrü boyunca sabit kalan, yalnızca --proxy-server bayrağıyla verilen proxy'dir.
Proxy kaydında neden sizin göndermediğiniz istekler görünüyor?
Güncelleme denetimleri ve Google servis istekleri gibi Chrome'un kendi arka plan trafiği de aynı proxy'ye gider. Kaydımızda bunların çoğu kimlik bilgisi olmadan geldi ve 407 aldı, çünkü page.authenticate() yalnızca sayfa trafiğinden gelen talepleri cevaplar. Sayfalarınızı etkilemezler.
Proxy, Puppeteer'da CAPTCHA çıkmasını önler mi?
Hayır. Proxy trafiğin nereden geldiğini değiştirir; CAPTCHA ise istek hızına, tarayıcı sinyallerine ve tutarsız oturumlara da tepki verir. Nedenleri ve CAPTCHA'yı azaltmanın meşru yolları Puppeteer ve CAPTCHA: Neden Çıkar, Nasıl Azalır? yazısında anlatılıyor.
Özet
Puppeteer'da proxy bir Chrome ayarıdır: bütün tarayıcı için --proxy-server bayrağı, tek context için proxyServer; giriş bilgisi ise ilk gezinmeden önce page.authenticate() ile verilir. Kimlik bilgisi context başına önbelleğe alındığı için her oturumu bir context olarak kurun, sticky ya da rotating seçimini kullanıcı adıyla yapın ve SOCKS5 için IP whitelist kullanın. response.status() değerini kontrol edin ve istek hızını makul tutun. Sayfaların sıradan ev bağlantılarından açılması gerekiyorsa çıkış IP'lerini Residential Proxy havuzundan alabilirsiniz.




