,

Automatisere nettleseren med Playwright på Wayland

Automatisere nettleseren med Playwright på Wayland

Utgangspunktet er enkelt nok: du vil styre en ekte, innlogget nettlesersesjon fra et skript. Playwright kobler seg gjerne til en kjørende Chrome via CDP (remote debugging), men på en Wayland/GNOME-maskin ryker dette stille på flere punkter samtidig, og feilmeldingene er sjelden til hjelp. Her er fellene, og oppsettet som faktisk står.

Chrome nekter debug-port på standardprofilen

Moderne Chrome åpner rett og slett ikke debug-porten mot din vanlige brukerprofil. Løsningen er å peke den mot en egen profilmappe og be den droppe den avanserte nøkkellagringen.

google-chrome \
  --remote-debugging-port=9222 \
  --user-data-dir=/tmp/chrome-debug \
  --password-store=basic

Egen --user-data-dir gir en ren profil som porten får lov til å binde seg til. --password-store=basic hindrer at Chrome blir hengende på et keyring-oppslag mens den venter på en dialog som aldri dukker opp.

Prosessen når ikke skjermen uten riktig miljø

Skjematisk diagram over miljøvariablene DISPLAY, XAUTHORITY, XDG_RUNTIME_DIR og DBUS som kobler Chrome-prosessen til Xwayland-skjermserveren på Wayland

Starter du Chrome fra et skall uten grafisk kontekst, finner den verken skjerm eller sesjonsbuss, og gir opp. Under Xwayland må fire miljøvariabler være på plass: skjerm, X-autentisering, runtime-katalog og DBUS-adresse.

export DISPLAY=:0
export XDG_RUNTIME_DIR=/run/user/1000
export DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus
export XAUTHORITY=/run/user/1000/.mutter-Xwaylandauth.XXXXXX

Den lumske av dem er XAUTHORITY. Xwayland lager et nytt auth-filnavn ved hver innlogging, så en hardkodet sti fungerer i dag og feiler i morgen. Løsningen er å hente verdien fra miljøet til en GUI-prosess som allerede kjører, i stedet for å gjette.

PID=$(pgrep -u "$USER" -f gnome-shell | head -n1)
XAUTHORITY=$(tr '\0' '\n' < /proc/$PID/environ | grep '^XAUTHORITY=' | cut -d= -f2)
export XAUTHORITY

Ikke drep din egen prosess

Fristelsen når noe henger, er å rydde opp med et raskt drep på portmønsteret. Problemet er at det mønsteret som regel matcher startskriptet ditt også, så du ender med å skyte verktøyet og la nettleseren leve videre. Litt bakvendt.

# Farlig: matcher lett ditt eget skript
pkill -f "remote-debugging-port=9222"

# Tryggere: match bare Chrome-binæren
pkill -x chrome

Start detached så den overlever skallet

Startes Chrome som et barn av skallet, dør den i det øyeblikket skallet lukkes eller SSH-sesjonen faller. Med setsid løsriver du prosessen så den lever sitt eget liv.

setsid google-chrome \
  --remote-debugging-port=9222 \
  --user-data-dir=/tmp/chrome-debug \
  --password-store=basic \
  >/tmp/chrome.log 2>&1 < /dev/null &

Koble Playwright på den kjørende sesjonen

Topologidiagram som viser hvordan et Python-Playwright-skript kobler seg til en kjørende Chrome-nettleser over CDP på port 9222 og overtar den innloggede sesjonen

Når porten først står, er resten udramatisk. Playwright kobler seg til over CDP og overtar den innloggede sesjonen direkte. Ingen ny nettleser, ingen ny innlogging.

from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.connect_over_cdp("http://localhost:9222")
    context = browser.contexts[0]
    page = context.pages[0]
    print(page.title())

Sjekkliste

  • Egen --user-data-dir og --password-store=basic
  • DISPLAY, XDG_RUNTIME_DIR og DBUS_SESSION_BUS_ADDRESS satt
  • XAUTHORITY hentet dynamisk fra en GUI-prosess, ikke hardkodet
  • Start med setsid, og drep aldri på portmønsteret

Med dette på plass er nettleserautomatisering på Wayland stabil nok til å kjøres fra cron eller en agent uten at du trenger å sitte og passe på den.


Trenger du hjelp med dette?

Ta kontakt for en uforpliktende prat om hvordan jeg kan hjelpe deg.

Navn