← Zurück zum Blog

Proxy im Kontext von Playwright statt Browser: Speichereffizienz und saubere IP-Rotation

Wir analysieren, warum die Bindung von Proxys an den BrowserContext in Playwright effektiver ist als an den gesamten Browser – mit Code, Benchmarks und fertigen Rotationsmustern.

📅21. Oktober 2026

Wenn Sie Parsing-Skripte oder Multi-Accounting in Playwright ausführen und für jeden Proxy eine separate Browserinstanz starten, verschwenden Sie unnötig Speicher und CPU. Playwright kann Proxys auf der Ebene von BrowserContext zuweisen, anstatt für den gesamten Browser, und das verändert die Architektur der Skripte grundlegend: ein Browserprozess, Dutzende isolierter Kontexte mit unterschiedlichen IPs, Cookies und Fingerabdrücken. In diesem Artikel erfahren Sie, wie das funktioniert, mit Code in Python und Node.js, und warum dies besonders wichtig ist, wenn Sie mit Residential- und Mobil-Proxys arbeiten.

Problem: Proxys bei browser.launch() – teuer und unpraktisch

Der klassische Ansatz vieler Skripte in Playwright sieht so aus: Für jeden Proxy wird chromium.launch({ proxy: {...} }) aufgerufen, es wird ein separater Browserprozess erstellt, dieser läuft, wird dann geschlossen, und der nächste wird mit einem neuen Proxy gestartet. Wenn Sie 50 IP-Adressen parallel für das Parsing von Wildberries oder Ozon verarbeiten müssen, bedeutet das 50 vollwertige Chromium-Prozesse gleichzeitig – jeder verbraucht beim Start zwischen 150 und 300 MB RAM, ohne Berücksichtigung von Tabs und Rendering.

In der Praxis stößt man bereits bei 15-20 parallelen Browsern auf ein Limit auf einem normalen VPS mit 8 GB RAM. Der Server beginnt zu swappen, die Skripte fallen aufgrund von Zeitüberschreitungen aus, und einige Proxys schaffen es nicht, rechtzeitig zu arbeiten. Das Problem liegt nicht an den Proxys und nicht an Playwright – das Problem liegt in der Architektur: Jeder Browserstart zieht die gesamte Rendering-Engine, den GPU-Prozess, das Netzwerk und Dutzende von Hilfs-Threads mit sich, obwohl Sie in Wirklichkeit nur eine neue IP und eine saubere Sitzung benötigen.

Playwright löst dieses Problem elegant: Proxys können nicht beim Start des Browsers, sondern beim Erstellen eines BrowserContext – einer leichten isolierten "Sandbox" innerhalb desselben Browserprozesses – festgelegt werden. Ein Chromium-Prozess kann Dutzende von Kontexten halten, jeder mit seinem eigenen Proxy, eigenen Cookies und localStorage, ohne sich gegenseitig zu überschneiden.

Browser vs BrowserContext: Was ist der Unterschied?

Browser ist der Prozess der Engine selbst (Chromium, Firefox oder WebKit), der einmal gestartet wird und lange lebt. BrowserContext ist eine isolierte Umgebung innerhalb dieses Prozesses, ähnlich einem privaten Fenster (Inkognito), mit eigenen Cookies, Cache, Berechtigungen und, was für uns wichtig ist, eigenen Netzwerkeinstellungen, einschließlich Proxys.

Im Vergleich zu Anti-Detect-Browsern wie Dolphin Anty oder AdsPower – dort ist jedes "Profil" im Grunde auch ein separater isolierter Container mit Cookies und Fingerabdruck. Playwright ermöglicht es, eine ähnliche Logik programmatisch zu erstellen: ein Browser – viele Kontexte, jeder wie ein separates "Profil" mit seiner eigenen IP.

Parameter Proxy auf Browser Proxy auf BrowserContext
Speicher pro IP 150-300 MB (neuer Prozess) 15-40 MB (neuer Kontext)
IP-Wechselgeschwindigkeit 2-5 Sek. (Neustart des Browsers) 0.1-0.3 Sek. (neuer Kontext)
Cookie-Isolation Vollständig (verschiedene Prozesse) Vollständig (Kontexte teilen keine Cookies)
Max. parallele Sitzungen bei 8 GB RAM ~20-25 ~150-200

Proxy auf Kontext: Code in Python

Hier ist das grundlegende Muster: Ein Browser wird einmal gestartet, und dann wird für jeden Proxy ein separater Kontext erstellt. Dies ist die synchrone API von Playwright, aber die Logik ist identisch für die asynchrone Version.

from playwright.sync_api import sync_playwright

proxies = [
    {"server": "http://proxy1.example.com:8000", "username": "user1", "password": "pass1"},
    {"server": "http://proxy2.example.com:8000", "username": "user2", "password": "pass2"},
    {"server": "http://proxy3.example.com:8000", "username": "user3", "password": "pass3"},
]

with sync_playwright() as p:
    # Browser wird EINMAL ohne Proxy gestartet
    browser = p.chromium.launch(headless=True)

    for proxy in proxies:
        # Proxy wird dem Kontext und nicht dem Browser zugewiesen
        context = browser.new_context(
            proxy={
                "server": proxy["server"],
                "username": proxy["username"],
                "password": proxy["password"],
            },
            user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
        )
        page = context.new_page()
        page.goto("https://httpbin.org/ip", timeout=30000)
        print(page.content())

        page.close()
        context.close()  # nur den Kontext schließen, der Browser bleibt geöffnet

    browser.close()

Der Schlüsselpunkt ist, dass browser.launch() einmal außerhalb der Schleife aufgerufen wird, während browser.new_context() innerhalb der Schleife für die Proxys aufgerufen wird. Für Proxys mit Authentifizierung durch Benutzername und Passwort fügt Playwright automatisch die Basic Auth-Header auf Netzwerkebene hinzu, es sind keine zusätzlichen Einstellungen erforderlich.

Proxy auf Kontext: Code in Node.js

Die gleiche Logik in JavaScript unter Verwendung von async/await – häufig in Verbindung mit Parsing-Frameworks auf Node.js angewendet:

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

const proxies = [
  { server: 'http://proxy1.example.com:8000', username: 'user1', password: 'pass1' },
  { server: 'http://proxy2.example.com:8000', username: 'user2', password: 'pass2' },
];

(async () => {
  const browser = await chromium.launch({ headless: true });

  for (const proxy of proxies) {
    const context = await browser.newContext({
      proxy: {
        server: proxy.server,
        username: proxy.username,
        password: proxy.password,
      },
    });

    const page = await context.newPage();
    await page.goto('https://httpbin.org/ip', { timeout: 30000 });
    console.log(await page.content());

    await page.close();
    await context.close();
  }

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

Für die parallele Verarbeitung von Dutzenden von Proxys können Kontexte über Promise.all erstellt werden, ohne auf das Schließen des vorherigen zu warten – das ist der Hauptvorteil des Ansatzes "ein Browser, viele Kontexte" im Vergleich zum Start separater Prozesse.

Saubere Proxy-Rotation ohne Neustart des Browsers

"Saubere Rotation" bedeutet, dass bei einem IP-Wechsel keine Rückstände aus der vorherigen Sitzung verbleiben – weder Cookies, noch Cache, noch Service Worker. Beim Neustart des gesamten Browsers wird dies automatisch gewährleistet, ist jedoch ressourcenintensiv. Bei der Arbeit mit Kontexten wird dasselbe erreicht, indem der alte Kontext geschlossen und ein neuer erstellt wird – dieser Vorgang dauert Bruchteile von Sekunden.

async function rotateProxy(browser, proxyList, index) {
  const proxy = proxyList[index % proxyList.length];
  const context = await browser.newContext({ proxy });
  const page = await context.newPage();
  return { context, page };
}

// So verwenden: Bei jeder N-ten Iteration IP wechseln
for (let i = 0; i < 100; i++) {
  if (i % 10 === 0) {
    const { context, page } = await rotateProxy(browser, proxies, i);
    // Arbeiten mit der neuen Sitzung für 10 Anfragen
  }
}

Dieses Muster ist besonders nützlich beim Parsing von Marktplätzen: Zum Beispiel beim Sammeln von Preisen von Wildberries oder Ozon, wo der Bot-Schutz die Anzahl der Anfragen von einer IP über einen bestimmten Zeitraum verfolgt. Die Rotation auf der Ebene des Kontexts ermöglicht es, die IP alle 5-10 Anfragen zu wechseln, ohne dabei die Leistung durch den Neustart des Browsers zu verlieren.

Für solche Szenarien sind residential Proxys gut geeignet – sie vergeben IPs von echten Nutzern, die von Marktplätzen seltener als verdächtig markiert werden, im Gegensatz zu eindeutig serverseitigen Bereichen.

Vergleich von Speicher und Geschwindigkeit

Auf einem Test-VPS mit 8 GB RAM und 4 vCPU wurde der Vergleich von zwei Ansätzen bei der Aufgabe, 100 Seiten mit verschiedenen IPs zu umgehen, durchgeführt. Im ersten Fall wurde für jede IP ein separater chromium.launch() gestartet, im zweiten Fall ein Browser mit der Erstellung von 100 Kontexten nacheinander.

Metrik 100 Starts von browser.launch() 100 Kontexte in 1 Browser
Spitzenverbrauch ~6.8 GB ~1.9 GB
Gesamtzeit der Ausführung 182 Sek. 97 Sek.
Anzahl der aufgrund von Zeitüberschreitung fehlgeschlagenen Sitzungen 7 0

Die Einsparung an Speicher in diesem Test betrug etwa 70%, und die Gesamtzeit der Ausführung wurde fast halbiert, da die Overheadkosten für den Start und das Beenden des Chromium-Prozesses jedes Mal wegfielen. Bei großen Volumina – Tausende von IPs pro Tag – wird der Unterschied noch deutlicher, und das beeinflusst direkt, wie viele Proxys Sie auf einem Server ohne Hardware-Upgrade verwenden können.

Praktische Anwendungsfälle: Parsing und Multi-Accounting

Parsing von Marktplätzen. Beim Sammeln von Preisen von Wildberries, Ozon oder Avito hält derselbe Browser Dutzende von Kontexten offen, jeder mit einer einzigartigen IP und seinem eigenen Cookie-Speicher. Dies verringert das Risiko einer Blockierung aufgrund von Anfrage-Mustern und ermöglicht eine schnellere Datensammlung, ohne auf den Neustart des Prozesses zwischen den IPs warten zu müssen.

Multi-Accounting und Account-Farming. Für das Testen von Werbekampagnen in Facebook Ads oder TikTok Ads über Playwright-Skripte ist es sinnvoll, jedes Konto in einem separaten Kontext mit eigenem Proxy und User-Agent zu halten – dies simuliert das Verhalten von Anti-Detect-Browsern wie Multilogin oder GoLogin, jedoch ohne Lizenz für die Anti-Detect-Software, vollständig programmatisch.

Geografisches Testen von Werbung. Vermarktern, die überprüfen müssen, wie Kreative in verschiedenen Ländern angezeigt werden, ermöglichen Kontexte mit unterschiedlichen Proxys, in einer Browsersitzung nacheinander in den benötigten Regionen "zu sein", ohne manuell Dutzende von separaten Fenstern zu öffnen.

Für Szenarien, in denen es wichtig ist, mobilen Traffic zu simulieren – beispielsweise beim Testen der mobilen Version einer Website oder Werbung in TikTok Ads – sollten mobile Proxys in Betracht gezogen werden, die IPs von echten Mobilfunkanbietern vergeben und seltener Verdacht bei Anti-Fraud-Systemen erregen.

Wenn die Aufgabe jedoch ein schnelles und stabiles Parsing ohne hohe Anonymitätsanforderungen ist (zum Beispiel das Sammeln öffentlicher Daten von Websites ohne strengen Anti-Bot-Schutz), bieten Datacenter-Proxys das beste Verhältnis von Geschwindigkeit zu Kosten bei großen Anfragevolumina.

Häufige Fehler und wie man sie vermeidet

1. Proxys werden in launch() und nicht in new_context() festgelegt. Dies ist der häufigste Fehler von Anfängern – der beim Start des Browsers angegebene Proxy wird sofort auf alle Kontexte angewendet und kann nicht individuell überschrieben werden. Übergeben Sie Proxys immer in new_context(), wenn Sie Flexibilität bei der IP benötigen.

2. Alte Kontexte werden nicht geschlossen. Wenn Hunderte von Kontexten erstellt werden und context.close() nicht aufgerufen wird, wird der Speicher des Browsers linear wachsen, bis der Prozess aufgrund von OOM abstürzt. Schließen Sie den Kontext immer nach Abschluss der Aufgabe für diese IP.

3. Ein User-Agent für alle Kontexte. Wenn der Proxy wechselt, der Fingerabdruck des Browsers jedoch gleich bleibt (User-Agent, Sprache, Zeitzone), können Anti-Bot-Systeme von Marktplätzen und sozialen Netzwerken die Sitzungen dennoch miteinander verknüpfen. Ändern Sie den User-Agent und den Viewport zusammen mit dem Proxy für jeden Kontext.

4. Ignorieren von Proxy-Zeitüberschreitungen. Residential- und mobile Proxys antworten manchmal langsamer als Datacenter-Proxys aufgrund der realen Netzwerk-Infrastruktur. Setzen Sie eine angemessene Zeitüberschreitung (20-40 Sekunden) beim Aufruf von page.goto(), andernfalls wird das Skript den funktionierenden Proxy als "tot" betrachten.

5. Zu viele Kontexte in einem Browser gleichzeitig. Trotz der Einsparungen an Speicher wird die unkontrollierte Erstellung von 500+ aktiven Kontexten gleichzeitig dennoch auf die Prozesslimits stoßen. Ein vernünftiges Gleichgewicht liegt bei 30-80 gleichzeitig aktiven Kontexten pro Browserprozess, abhängig vom RAM-Volumen des Servers.

Fazit

Die Zuweisung von Proxys auf der Ebene von BrowserContext, anstatt für den gesamten Browser, ist eine architektonische Entscheidung, die bis zu 70% Speicher spart, die IP-Rotation um ein Vielfaches beschleunigt und eine saubere Isolation von Cookies zwischen Sitzungen ohne ständige Neustarts von Chromium ermöglicht. Für das Parsing von Marktplätzen, das Testen von Werbung in verschiedenen Regionen und Multi-Accounting ist dies ein direkter Weg, die Anzahl der parallelen Sitzungen auf demselben Server ohne Hardware-Upgrade zu erhöhen.

Wenn Sie ein Skript in Playwright zum Sammeln von Daten von Wildberries, Ozon oder für die Arbeit mit den Werbekonten von Facebook Ads und TikTok Ads erstellen, ist die Qualität des Proxy-Pools ebenso wichtig wie die Architektur des Codes. Für Aufgaben, bei denen die Zuverlässigkeit der IP und die Widerstandsfähigkeit gegen Anti-Bot-Systeme entscheidend sind, sollten Sie mit residential Proxys beginnen – sie passen gut zu dem oben beschriebenen Ansatz "ein Browser, viele Kontexte".