Bloga geri dön

Puppeteer ve Playwright ile Proxy Entegrasyonu: Kod Örnekleri ile Kapsamlı Rehber

Puppeteer ve Playwright'ta HTTP, HTTPS ve SOCKS5 proxy ayarları için JavaScript ve TypeScript ile kod örnekleriyle detaylı bir rehber.

📅13 Şubat 2026
```html

Puppeteer ve Playwright, tarayıcı otomasyonu ve web kazıma için popüler araçlardır. Büyük miktarda istekle çalışırken veya korumalı siteleri kazırken, proxy kullanımı IP engellemelerinden kaçınmak için kritik öneme sahiptir. Bu kılavuzda, her iki aracın proxy entegrasyonunu temel ayarlardan hata işleme ve döngü senaryolarına kadar tüm yollarını inceleyeceğiz.

Headless tarayıcılarda proxy'nin temelleri

Puppeteer ve Playwright, DevTools Protokolü aracılığıyla gerçek tarayıcıları (Chromium, Firefox, WebKit) yönetir. Bu, proxy'nin tarayıcı başlatma aşamasında ayarlandığı anlamına gelir, ayrı istekler üzerinde değil. Her iki araç da HTTP, HTTPS ve SOCKS5 proxy'lerini destekler, ancak bunları ayarlamak için farklı API'lere sahiptir.

Normal HTTP kütüphanelerinden (axios, fetch) temel farklar:

  • Proxy, tarayıcı başlatıldığında ayarlanır — bir tarayıcı oturumu içinde proxy'yi değiştiremezsiniz
  • JavaScript desteği ve render alma — proxy, sayfanın tüm kaynaklarına (görseller, scriptler, XHR) uygulanır
  • Otomatik yönlendirme ve çerez işleme — tarayıcı gerçek bir kullanıcı gibi davranır
  • Parmak izi alma — proxy ile bile, siteler tarayıcı özelliklerine göre otomasyonu belirleyebilir

Önemli: Sık IP değişikliği gerektiren görevler için (binlerce sayfa kazıma, toplu kayıt) döngüsel rezidans proxy'leri kullanmak daha etkilidir — her istekte IP'yi değiştirmeye izin verir, tarayıcıyı yeniden başlatmadan.

Puppeteer'da proxy ayarlama

Puppeteer, Chrome/Chromium'u yönetmek için Google'dan bir kütüphanedir. Proxy, tarayıcıyı başlatma argümanları aracılığıyla --proxy-server bayrağı ile ayarlanır.

HTTP/HTTPS proxy için temel ayar

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch({
    headless: true,
    args: [
      '--proxy-server=http://proxy.example.com:8080'
    ]
  });

  const page = await browser.newPage();
  
  // IP adresini kontrol etme
  await page.goto('https://api.ipify.org?format=json');
  const content = await page.content();
  console.log('Geçerli IP:', content);

  await browser.close();
})();

Bu kod, tarayıcıyı bir proxy sunucusu aracılığıyla başlatır. Tüm HTTP ve HTTPS istekleri belirtilen proxy üzerinden geçecektir. Çalışabilirliği kontrol etmek için, dış IP adresini döndüren ipify hizmeti kullanılır.

SOCKS5 proxy ayarlama

const browser = await puppeteer.launch({
  headless: true,
  args: [
    '--proxy-server=socks5://proxy.example.com:1080'
  ]
});

// Diğer kod benzer

SOCKS5 proxy'leri daha düşük bir seviyede çalışır ve UDP trafiğini destekler, bu bazı web uygulamaları için faydalı olabilir. Söz dizimi, yalnızca URL'deki protokol değişir.

Belirli alanlar için proxy kullanımı

const browser = await puppeteer.launch({
  args: [
    '--proxy-server=http://proxy1.example.com:8080',
    '--proxy-bypass-list=localhost;127.0.0.1;*.internal.com'
  ]
});

// Yerel istekler ve *.internal.com istekleri doğrudan gidecek
// Diğer tüm istekler proxy üzerinden

--proxy-bypass-list bayrağı, belirli alanların proxy'den muaf tutulmasına izin verir. Bu, doğrudan ve proxy üzerinden istekleri birleştirmeniz gerektiğinde faydalıdır.

Playwright'ta proxy ayarlama

Playwright, Microsoft'tan daha modern bir kütüphanedir ve Chromium, Firefox ve WebKit'i destekler. Proxy, yapılandırma nesnesi aracılığıyla ayarlanır, bu da API'yi daha anlaşılır ve tipli hale getirir.

Proxy için temel ayar

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

(async () => {
  const browser = await chromium.launch({
    proxy: {
      server: 'http://proxy.example.com:8080'
    }
  });

  const context = await browser.newContext();
  const page = await context.newPage();
  
  await page.goto('https://api.ipify.org?format=json');
  const ip = await page.textContent('body');
  console.log('Proxy üzerinden IP:', ip);

  await browser.close();
})();

Playwright, proxy nesnesini komut satırı argümanları yerine kullanır. Bu, TypeScript'te daha iyi tipleme sağlar ve daha temiz bir kod sunar.

Bağlam düzeyinde proxy ayarlama

const browser = await chromium.launch();

// Bağlam 1 - proxy ile
const context1 = await browser.newContext({
  proxy: {
    server: 'http://proxy1.example.com:8080'
  }
});

// Bağlam 2 - başka bir proxy ile
const context2 = await browser.newContext({
  proxy: {
    server: 'http://proxy2.example.com:8080'
  }
});

const page1 = await context1.newPage();
const page2 = await context2.newPage();

// Her sayfa kendi proxy'sini kullanır!

Playwright'ın en önemli avantajlarından biri, tek bir süreç içinde farklı proxy'lerle birden fazla tarayıcı bağlamı oluşturma yeteneğidir. Bu, birçok IP adresi ile çalışırken kaynakları tasarruf etmenizi sağlar.

Proxy'den muaf alanlar

const browser = await chromium.launch({
  proxy: {
    server: 'http://proxy.example.com:8080',
    bypass: 'localhost,127.0.0.1,*.internal.com'
  }
});

// localhost ve *.internal.com istekleri doğrudan gidecek

Kullanıcı adı ve şifre ile kimlik doğrulama

Çoğu ticari proxy, kimlik doğrulama gerektirir. Her iki araç da yetkilendirmeyi destekler, ancak bunu farklı şekillerde uygular.

Puppeteer'da kimlik doğrulama

const browser = await puppeteer.launch({
  args: ['--proxy-server=http://proxy.example.com:8080']
});

const page = await browser.newPage();

// Proxy için kimlik bilgilerini ayarlama
await page.authenticate({
  username: 'kullanici_adiniz',
  password: 'sifreniz'
});

await page.goto('https://httpbin.org/ip');
const content = await page.content();
console.log(content);

page.authenticate() metodu, bu sayfadaki tüm sonraki istekler için kimlik bilgilerini ayarlar. İlk page.goto()'dan önce çağrılması önemlidir.

Playwright'ta kimlik doğrulama

const browser = await chromium.launch({
  proxy: {
    server: 'http://proxy.example.com:8080',
    username: 'kullanici_adiniz',
    password: 'sifreniz'
  }
});

const page = await browser.newPage();
await page.goto('https://httpbin.org/ip');

Playwright, kimlik bilgilerini doğrudan proxy yapılandırma nesnesinde belirtmenize olanak tanır — bu daha kullanışlı ve güvenlidir, çünkü ek metod çağrıları gerektirmez.

Alternatif yöntem: URL'de kimlik bilgileri

// Her iki çerçevede de çalışır
const proxyUrl = 'http://kullanici_adiniz:sifreniz@proxy.example.com:8080';

// Puppeteer
const browser = await puppeteer.launch({
  args: [`--proxy-server=${proxyUrl}`]
});

// Playwright
const browser = await chromium.launch({
  proxy: { server: proxyUrl }
});

Bu yöntem çalışır, ancak üretim için önerilmez — kimlik bilgileri günlüklerde görünebilir. Hassas verileri saklamak için ortam değişkenleri kullanın.

İpucu: Ticari siteleri kazırken rezidans proxy'leri kullanmanızı öneririz — bunlar gerçek ev kullanıcılarının IP'lerine sahiptir ve bot engelleme sistemleri tarafından daha az engellenir.

Proxy döngüsü ve IP havuzunu yönetme

Ölçeklenebilir kazıma için IP adreslerini düzenli olarak değiştirmek gerekir. Proxy, tarayıcıyı başlatırken ayarlandığı için, döngü, tarayıcı oturumunu yeniden başlatmayı gerektirir.

Proxy listesi ile basit döngü (Puppeteer)

const puppeteer = require('puppeteer');

const proxyList = [
  'http://user1:pass1@proxy1.example.com:8080',
  'http://user2:pass2@proxy2.example.com:8080',
  'http://user3:pass3@proxy3.example.com:8080'
];

async function scrapeWithRotation(urls) {
  for (let i = 0; i < urls.length; i++) {
    const proxyUrl = proxyList[i % proxyList.length];
    
    const browser = await puppeteer.launch({
      args: [`--proxy-server=${proxyUrl}`]
    });

    try {
      const page = await browser.newPage();
      await page.goto(urls[i], { waitUntil: 'networkidle0' });
      
      const data = await page.evaluate(() => {
        return {
          title: document.title,
          url: window.location.href
        };
      });
      
      console.log(`URL ${i + 1}:`, data);
    } catch (error) {
      console.error(`Hata ${urls[i]} üzerinde:`, error.message);
    } finally {
      await browser.close();
    }
  }
}

const urlsToScrape = [
  'https://example.com/page1',
  'https://example.com/page2',
  'https://example.com/page3',
  'https://example.com/page4'
];

scrapeWithRotation(urlsToScrape);

Bu kod, listedeki proxy'leri döngüsel olarak geçirir ve her URL için yeni bir tarayıcı başlatır. i % proxyList.length metodu döngüsel döngüyü sağlar.

Bağlam havuzu ile döngü (Playwright)

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

const proxyList = [
  { server: 'http://proxy1.example.com:8080', username: 'user1', password: 'pass1' },
  { server: 'http://proxy2.example.com:8080', username: 'user2', password: 'pass2' },
  { server: 'http://proxy3.example.com:8080', username: 'user3', password: 'pass3' }
];

async function scrapeWithContextPool(urls) {
  const browser = await chromium.launch();
  
  // Farklı proxy'lerle bağlam havuzu oluşturma
  const contexts = await Promise.all(
    proxyList.map(proxy => browser.newContext({ proxy }))
  );

  for (let i = 0; i < urls.length; i++) {
    const context = contexts[i % contexts.length];
    const page = await context.newPage();
    
    try {
      await page.goto(urls[i], { waitUntil: 'networkidle' });
      const title = await page.title();
      console.log(`URL ${i + 1} (proxy ${i % contexts.length}):`, title);
    } catch (error) {
      console.error(`Hata ${urls[i]} üzerinde:`, error.message);
    } finally {
      await page.close();
    }
  }

  await browser.close();
}

const urls = [
  'https://example.com/page1',
  'https://example.com/page2',
  'https://example.com/page3'
];

scrapeWithContextPool(urls);

Playwright, tek bir tarayıcıda her biri kendi proxy'sine sahip birden fazla bağlam oluşturmanıza olanak tanır. Bu, tarayıcıyı tamamen yeniden başlatmaktan daha az bellek ve başlatma süresi tasarrufu sağlar.

Hataları izleyerek akıllı döngü

class ProxyRotator {
  constructor(proxyList) {
    this.proxyList = proxyList;
    this.currentIndex = 0;
    this.failedProxies = new Set();
  }

  getNext() {
    const availableProxies = this.proxyList.filter(
      (_, index) => !this.failedProxies.has(index)
    );

    if (availableProxies.length === 0) {
      throw new Error('Tüm proxy'ler kullanılamıyor');
    }

    const proxy = this.proxyList[this.currentIndex];
    this.currentIndex = (this.currentIndex + 1) % this.proxyList.length;
    
    return { proxy, index: this.currentIndex - 1 };
  }

  markFailed(index) {
    this.failedProxies.add(index);
    console.log(`Proxy ${index} kullanılamaz olarak işaretlendi`);
  }

  resetFailed() {
    this.failedProxies.clear();
  }
}

// Kullanım
const rotator = new ProxyRotator(proxyList);

async function scrapeWithSmartRotation(url, maxRetries = 3) {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    const { proxy, index } = rotator.getNext();
    
    const browser = await chromium.launch({ proxy });
    const page = await browser.newPage();

    try {
      await page.goto(url, { timeout: 30000 });
      const data = await page.content();
      await browser.close();
      return data;
    } catch (error) {
      console.error(`Proxy ${index} ile hata:`, error.message);
      rotator.markFailed(index);
      await browser.close();
      
      if (attempt === maxRetries - 1) {
        throw new Error(`${url} yüklenemedi, ${maxRetries} denemeden sonra`);
      }
    }
  }
}

Bu sınıf, çalışmayan proxy'leri izler ve döngüden çıkarır. Hata durumunda, otomatik olarak listedeki bir sonraki proxy'ye geçer.

Hata işleme ve çalışabilirlik kontrolü

Proxy ile çalışırken belirli hatalar ortaya çıkar: bağlantı zaman aşımı, yetkilendirme reddi, hedef site tarafından IP engelleme. Hataların doğru bir şekilde işlenmesi, kazıyıcının kararlı çalışması için kritik öneme sahiptir.

Tipik hatalar ve işleme yöntemleri

async function safePageLoad(page, url, options = {}) {
  const defaultOptions = {
    timeout: 30000,
    waitUntil: 'networkidle0',
    maxRetries: 3,
    retryDelay: 2000
  };

  const config = { ...defaultOptions, ...options };

  for (let attempt = 1; attempt <= config.maxRetries; attempt++) {
    try {
      await page.goto(url, {
        timeout: config.timeout,
        waitUntil: config.waitUntil
      });
      
      return { success: true, attempt };
    } catch (error) {
      console.error(`Deneme ${attempt} başarısız oldu:`, error.message);

      // Hata türünü analiz etme
      if (error.message.includes('ERR_PROXY_CONNECTION_FAILED')) {
        throw new Error('Proxy kullanılamıyor');
      }
      
      if (error.message.includes('ERR_TUNNEL_CONNECTION_FAILED')) {
        throw new Error('Proxy tünelleme hatası');
      }

      if (error.message.includes('407')) {
        throw new Error('Proxy yetkilendirme hatası (407)');
      }

      if (error.message.includes('Navigation timeout')) {
        console.log(`Yükleme zaman aşımı, ${config.retryDelay}ms sonra tekrar denenecek`);
        await new Promise(resolve => setTimeout(resolve, config.retryDelay));
        continue;
      }

      // Eğer bu son deneme ise hatayı fırlat
      if (attempt === config.maxRetries) {
        throw error;
      }
    }
  }
}

Proxy'nin çalışabilirliğini kontrol etme

async function testProxy(proxyConfig) {
  const browser = await chromium.launch({ proxy: proxyConfig });
  const page = await browser.newPage();

  const result = {
    working: false,
    ip: null,
    responseTime: null,
    error: null
  };

  const startTime = Date.now();

  try {
    await page.goto('https://api.ipify.org?format=json', { timeout: 10000 });
    const content = await page.textContent('body');
    const data = JSON.parse(content);
    
    result.working = true;
    result.ip = data.ip;
    result.responseTime = Date.now() - startTime;
  } catch (error) {
    result.error = error.message;
  } finally {
    await browser.close();
  }

  return result;
}

// Proxy listesini test etme
async function validateProxyList(proxyList) {
  console.log('Proxy kontrol ediliyor...');
  
  const results = await Promise.all(
    proxyList.map(async (proxy, index) => {
      const result = await testProxy(proxy);
      console.log(`Proxy ${index + 1}:`, result.working ? `✓ ${result.ip} (${result.responseTime}ms)` : `✗ ${result.error}`);
      return { proxy, ...result };
    })
  );

  const workingProxies = results.filter(r => r.working);
  console.log(`\nÇalışan proxy'ler: ${workingProxies.length}/${proxyList.length}`);
  
  return workingProxies.map(r => r.proxy);
}

Bu fonksiyon, her proxy'yi kullanmadan önce kontrol eder, yanıt süresini ölçer ve yalnızca çalışan proxy'leri döndürür. Uygulama başlatıldığında doğrulama yapmanız önerilir.

İzleme ve günlüğe kaydetme

class ProxyMonitor {
  constructor() {
    this.stats = {
      totalRequests: 0,
      successfulRequests: 0,
      failedRequests: 0,
      proxyErrors: 0,
      averageResponseTime: 0,
      requestsByProxy: new Map()
    };
  }

  recordRequest(proxyIndex, success, responseTime, error = null) {
    this.stats.totalRequests++;
    
    if (success) {
      this.stats.successfulRequests++;
      this.stats.averageResponseTime = 
        (this.stats.averageResponseTime * (this.stats.successfulRequests - 1) + responseTime) / 
        this.stats.successfulRequests;
    } else {
      this.stats.failedRequests++;
      if (error && error.includes('proxy')) {
        this.stats.proxyErrors++;
      }
    }

    // Her proxy için istatistik
    if (!this.stats.requestsByProxy.has(proxyIndex)) {
      this.stats.requestsByProxy.set(proxyIndex, { success: 0, failed: 0 });
    }
    
    const proxyStats = this.stats.requestsByProxy.get(proxyIndex);
    success ? proxyStats.success++ : proxyStats.failed++;
  }

  getReport() {
    const successRate = (this.stats.successfulRequests / this.stats.totalRequests * 100).toFixed(2);
    
    return {
      ...this.stats,
      successRate: `${successRate}%`,
      averageResponseTime: `${this.stats.averageResponseTime.toFixed(0)}ms`
    };
  }
}

// Kullanım
const monitor = new ProxyMonitor();

async function monitoredScrape(url, proxyIndex) {
  const startTime = Date.now();
  try {
    // ... kazıma kodu ...
    const responseTime = Date.now() - startTime;
    monitor.recordRequest(proxyIndex, true, responseTime);
  } catch (error) {
    monitor.recordRequest(proxyIndex, false, 0, error.message);
    throw error;
  }
}

Gelişmiş senaryolar: coğrafi konum ve parmak izi alma

Modern bot engelleme sistemleri yalnızca IP adresini değil, aynı zamanda coğrafi konum, saat dilimi, tarayıcı dili ve diğer parametreleri de kontrol eder. Başka bir ülkeden proxy kullanırken, tüm bu parametrelerin doğru bir şekilde ayarlanması önemlidir.

Proxy için coğrafi konum ve dil ayarlama

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

async function createContextWithGeo(proxy, geoData) {
  const browser = await chromium.launch({ proxy });
  
  const context = await browser.newContext({
    locale: geoData.locale,           // 'en-US', 'de-DE', 'fr-FR'
    timezoneId: geoData.timezone,     // 'America/New_York', 'Europe/Berlin'
    geolocation: {
      latitude: geoData.latitude,
      longitude: geoData.longitude
    },
    permissions: ['geolocation']
  });

  return { browser, context };
}

// Örnek: Almanya'dan proxy
const germanyProxy = {
  server: 'http://de-proxy.example.com:8080',
  username: 'user',
  password: 'pass'
};

const germanyGeo = {
  locale: 'de-DE',
  timezone: 'Europe/Berlin',
  latitude: 52.520008,
  longitude: 13.404954
};

const { browser, context } = await createContextWithGeo(germanyProxy, germanyGeo);
const page = await context.newPage();

await page.goto('https://www.google.com');
// Google, Berlin için sonuçlarla Almanca versiyonunu gösterecek

Bu kod, tarayıcıyı gerçek bir Alman kullanıcısı gibi görünmesi için ayarlar: Almanca arayüz dili, Berlin saat dilimi ve Berlin'in merkezi koordinatları.

Tam parmak izi ayarı

async function createStealthContext(proxy, profile) {
  const context = await chromium.launch({ proxy }).then(b => 
    b.newContext({
      locale: profile.locale,
      timezoneId: profile.timezone,
      userAgent: profile.userAgent,
      viewport: profile.viewport,
      deviceScaleFactor: profile.deviceScaleFactor,
      isMobile: profile.isMobile,
      hasTouch: profile.hasTouch,
      colorScheme: profile.colorScheme,
      geolocation: profile.geolocation,
      permissions: ['geolocation']
    })
  );

  return context;
}

// Windows 10 + ABD'den Chrome için profil
const desktopUSProfile = {
  locale: 'en-US',
  timezone: 'America/New_York',
  userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
  viewport: { width: 1920, height: 1080 },
  deviceScaleFactor: 1,
  isMobile: false,
  hasTouch: false,
  colorScheme: 'light',
  geolocation: { latitude: 40.7128, longitude: -74.0060 }
};

// Birleşik Krallık'tan iPhone için profil
const mobileUKProfile = {
  locale: 'en-GB',
  timezone: 'Europe/London',
  userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1',
  viewport: { width: 390, height: 844 },
  deviceScaleFactor: 3,
  isMobile: true,
  hasTouch: true,
  colorScheme: 'light',
  geolocation: { latitude: 51.5074, longitude: -0.1278 }
};

Kapsamlı parmak izi ayarı, otomasyonun tespit edilme olasılığını azaltır. Tüm parametrelerin birbiriyle uyumlu olması önemlidir: örneğin, mobil User-Agent, mobil ekran çözünürlüğü ile birlikte gelmelidir.

Önemli: Reklam platformları (Google Ads, Facebook Ads) veya finansal hizmetlerle çalışırken mobil proxy'ler kullanmanızı öneririz — bunlar gerçek mobil operatörlerin güven puanına sahiptir ve neredeyse hiç engellenmez.

WebRTC sızıntısını aşma

// Puppeteer: WebRTC'yi engelleme
const browser = await puppeteer.launch({
  args: [
    '--proxy-server=http://proxy.example.com:8080',
    '--disable-webrtc',
    '--disable-webrtc-hw-encoding',
    '--disable-webrtc-hw-decoding'
  ]
});

// Playwright: WebRTC API'sini yeniden tanımlama
const context = await browser.newContext({ proxy: proxyConfig });

await context.addInitScript(() => {
  // RTCPeerConnection'ı engelle
  window.RTCPeerConnection = undefined;
  window.RTCDataChannel = undefined;
  window.RTCSessionDescription = undefined;
  
  // getUserMedia'yı yeniden tanımla
  navigator.mediaDevices.getUserMedia = undefined;
  navigator.getUserMedia = undefined;
});

WebRTC, proxy kullanırken bile gerçek IP adresinizi ifşa edebilir. Bu kod, tarayıcıda WebRTC API'sini tamamen devre dışı bırakır.

Proxy ile çalışmak için Puppeteer ve Playwright karşılaştırması

Kriter Puppeteer Playwright
Proxy ayarlama Komut satırı argümanları ile Yapılandırma nesnesi ile
Kimlik doğrulama Başlatma sonrası page.authenticate() Oluşturma sırasında proxy nesnesinde
Tek bir tarayıcıda birden fazla proxy Hayır, ayrı bir tarayıcı gerekir Evet, farklı bağlamlar aracılığıyla
Tarayıcı desteği Sadece Chromium/Chrome Chromium, Firefox, WebKit
Performans Tek bir tarayıcının hızlı başlatılması Birçok bağlamda daha etkili
TypeScript @types/puppeteer ile tipler Yerleşik TypeScript desteği
Dokümantasyon İyi, birçok örnek var Harika, daha yapılandırılmış
Ekosistem Daha fazla eklenti ve uzantı Daha hızlı gelişiyor, yeni özellikler

Seçim önerileri

Puppeteer'i seçin, eğer:

  • Yalnızca Chrome/Chromium ile çalışıyorsanız
  • Tek bir proxy kullanıyorsanız
  • Mevcut araçlarla maksimum uyumluluk gerekiyorsa
  • Puppeteer üzerinde büyük bir kod tabanınız varsa

Playwright'i seçin, eğer:

  • Firefox veya Safari (WebKit) ile çalışmanız gerekiyorsa
  • Birden fazla proxy'yi aynı anda kullanmanız gerekiyorsa
  • Ölçeklenebilirlikte performans önemliyse
  • TypeScript ile yazıyorsanız
  • Yeni bir projeye sıfırdan başlıyorsanız

Proxy döngüsünde performans

Test: 10 proxy ile 100 sayfa kazıma, MacBook Pro M1 üzerinde:

Yöntem Çalışma süresi RAM tüketimi
Puppeteer (tarayıcıyı yeniden başlatma) 8 dakika 23 saniye ~1.2 GB pik
Playwright (tarayıcıyı yeniden başlatma) 7 dakika 54 saniye ~1.1 GB pik
Playwright (bağlam havuzu) 4 dakika 12 saniye ~800 MB sabit

Playwright, bağlam havuzuyla neredeyse 2 kat daha hızlıdır, çünkü tarayıcıyı başlatma masrafları yoktur. Bu, binlerce sayfa kazırken kritik öneme sahiptir.

Sonuç

Puppeteer ve Playwright ile proxy entegrasyonu, web kazıma, test etme ve otomasyon için standart bir uygulamadır. Puppeteer, basitlik ve geniş bir ekosistem sunarken, Playwright modern bir API ve birçok proxy ile çalışırken daha iyi performans sunar.

İncelediğimiz ana noktalar:

  • Her iki çerçevede de HTTP, HTTPS ve SOCKS5 proxy için temel ayarlar
  • Kullanıcı adı ve şifre ile kimlik doğrulama
  • Ölçeklenebilir kazıma için proxy döngüsü
  • Hata işleme ve kullanımdan önce proxy doğrulama
  • Coğrafi konum ve parmak izi ayarlama, bot engelleme sistemlerini aşmak için
  • Farklı yaklaşımların performans karşılaştırması

Üretim çözümleri için, kaliteli proxy'leri doğru parmak izi ayarı, hata işleme ve izleme ile birleştirmenizi öneririz. Bu, korumalı sitelerde bile kazıyıcının kararlı çalışmasını sağlar.

Ticari siteleri, pazar yerlerini veya reklam platformları ile çalışmayı planlıyorsanız, rezidans proxy'leri kullanmanızı öneririz — bunlar maksimum anonimlik sağlar ve gerçek ev kullanıcılarının IP adresleri sayesinde engellenme riski minimumdur.

```