Monitorloses Chrome wird unter Windows nicht gestartet
Einige Chrome-Richtlinien erzwingen möglicherweise die Ausführung von Chrome oder Chromium mit bestimmten Erweiterungen.
Puppeteer übergibt standardmäßig das Flag --disable-extensions
und startet daher nicht, wenn solche Richtlinien aktiv sind.
Um dieses Problem zu umgehen, führen Sie ohne das Flag aus:
const browser = await puppeteer.launch({
ignoreDefaultArgs: ['--disable-extensions'],
});
Kontext: Problem 3681.
Monitorloses Chrome wird unter UNIX nicht gestartet
Prüfen Sie, ob alle erforderlichen Abhängigkeiten installiert sind. Sie können ldd chrome | grep not
auf einem Linux-Computer ausführen, um zu prüfen, welche Abhängigkeiten fehlen.
Debian (Ubuntu)-Abhängigkeiten
ca-certificates
fonts-liberation
libappindicator3-1
libasound2
libatk-bridge2.0-0
libatk1.0-0
libc6
libcairo2
libcups2
libdbus-1-3
libexpat1
libfontconfig1
libgbm1
libgcc1
libglib2.0-0
libgtk-3-0
libnspr4
libnss3
libpango-1.0-0
libpangocairo-1.0-0
libstdc++6
libx11-6
libx11-xcb1
libxcb1
libxcomposite1
libxcursor1
libxdamage1
libxext6
libxfixes3
libxi6
libxrandr2
libxrender1
libxss1
libxtst6
lsb-release
wget
xdg-utils
CentOS-Abhängigkeiten
alsa-lib.x86_64
atk.x86_64
cups-libs.x86_64
gtk3.x86_64
ipa-gothic-fonts
libXcomposite.x86_64
libXcursor.x86_64
libXdamage.x86_64
libXext.x86_64
libXi.x86_64
libXrandr.x86_64
libXScrnSaver.x86_64
libXtst.x86_64
pango.x86_64
xorg-x11-fonts-100dpi
xorg-x11-fonts-75dpi
xorg-x11-fonts-cyrillic
xorg-x11-fonts-misc
xorg-x11-fonts-Type1
xorg-x11-utils
Nach der Installation der Abhängigkeiten müssen Sie die NSS-Bibliothek mit diesem Befehl aktualisieren
yum update nss -y
Diskussionen ansehen:
Monitorloses Chrome deaktiviert GPU-Compositing
Für Chrome und Chromium ist --use-gl=egl
erforderlich, um die GPU-Beschleunigung im monitorlosen Modus zu aktivieren.
const browser = await puppeteer.launch({
headless: true,
args: ['--use-gl=egl'],
});
Chrome wurde heruntergeladen, startet aber nicht auf Node.js
Wenn Sie beim Starten von Chromium eine Fehlermeldung wie diese erhalten, gehen Sie so vor:
(node:15505) UnhandledPromiseRejectionWarning: Error: Failed to launch the browser process!
spawn /Users/.../node_modules/puppeteer/.local-chromium/mac-756035/chrome-mac/Chromium.app/Contents/MacOS/Chromium ENOENT
Dies bedeutet, dass der Browser heruntergeladen wurde, aber nicht richtig extrahiert werden konnte.
Die häufigste Ursache ist ein Programmfehler in Node.js v14.0.0, durch den extract-zip
beschädigt wurde. Das Modul, mit dem Puppeteer Browserdownloads an die richtige Stelle extrahiert, ist das. Der Fehler wurde in Node.js v14.1.0 behoben. Achten Sie daher darauf, dass Sie diese oder eine höhere Version ausführen.
Chrome Linux-Sandbox einrichten
Um die Hostumgebung vor nicht vertrauenswürdigen Webinhalten zu schützen, nutzt Chrome mehrere Sandbox-Ebenen.
Damit dies richtig funktioniert, muss der Host zuerst konfiguriert werden. Wenn keine geeignete Sandbox für Chrome verfügbar ist, stürzt der Browser mit dem Fehler No usable sandbox!
ab.
Wenn Sie dem Inhalt, den Sie in Chrome öffnen, absolut vertrauen, können Sie Chrome mit dem Argument --no-sandbox
starten:
const browser = await puppeteer.launch({
args: ['--no-sandbox', '--disable-setuid-sandbox'],
});
Es gibt zwei Möglichkeiten, eine Sandbox in Chromium zu konfigurieren.
[empfohlen] Klonen von Nutzer-Namespaces aktivieren
Das Klonen von Server-Namespaces wird nur von modernen Kerneln unterstützt. Nicht privilegierte Nutzer-Namespaces können in der Regel problemlos aktiviert werden, können aber eine größere Kernel-Angriffsfläche für Nicht-Root-Prozesse (ohne Sandbox) öffnen, um Kernel-Berechtigungen zu erhalten.
sudo sysctl -w kernel.unprivileged_userns_clone=1
[alternative] Setuid-Sandbox einrichten
Die setuid-Sandbox ist eine eigenständige ausführbare Datei und befindet sich neben dem Chromium, den Puppeteer herunterlädt. Sie können dieselbe ausführbare Sandbox-Datei für verschiedene Chromium-Versionen wiederverwenden. Daher ist Folgendes nur einmal pro Hostumgebung möglich:
# cd to the downloaded instance
cd <project-dir-path>/node_modules/puppeteer/.local-chromium/linux-<revision>/chrome-linux/
sudo chown root:root chrome_sandbox
sudo chmod 4755 chrome_sandbox
# copy sandbox executable to a shared location
sudo cp -p chrome_sandbox /usr/local/sbin/chrome-devel-sandbox
# export CHROME_DEVEL_SANDBOX env variable
export CHROME_DEVEL_SANDBOX=/usr/local/sbin/chrome-devel-sandbox
Sie können die Umgebungsvariable CHROME_DEVEL_SANDBOX
standardmäßig exportieren. Fügen Sie in diesem Fall ~/.bashrc
oder .zshenv
Folgendes hinzu:
export CHROME_DEVEL_SANDBOX=/usr/local/sbin/chrome-devel-sandbox
Puppeteer auf Travis CI ausführen
Wir haben unsere Tests für Puppeteer auf Travis CI bis Version 6.0.0 durchgeführt. Danach erfolgten wir zu GitHub Actions. Weitere Informationen finden Sie in der Referenz zu .travis.yml
(Version 5.5.0).
Hier sind einige Best Practices:
- Der Dienst xvfb sollte gestartet werden, um Chromium im nicht monitorlosen Modus auszuführen
- Wird standardmäßig unter Xenial Linux unter Travis ausgeführt
- Wird standardmäßig
npm install
ausgeführt node_modules
wird standardmäßig im Cache gespeichert
.travis.yml
könnte so aussehen:
language: node_js
node_js: node
services: xvfb
script:
- npm run test
Puppeteer auf CircleCI ausführen
- Beginnen Sie mit einem NodeJS-Image in der Konfiguration.
yaml docker: - image: circleci/node:14 # Use your desired version environment: NODE_ENV: development # Only needed if puppeteer is in `devDependencies`
- Abhängigkeiten wie
libXtst6
müssen wahrscheinlich mitapt-get
installiert werden. Verwenden Sie daher den Orb threetreeslight/puppeteer (instructions) oder fügen Sie Teile der Quelle in Ihre eigene Konfiguration ein. - Wenn Sie Puppeteer über Jest verwenden, kann ein Fehler auftreten, der untergeordnete Prozesse erzeugt:
shell [00:00.0] jest args: --e2e --spec --max-workers=36 Error: spawn ENOMEM at ChildProcess.spawn (internal/child_process.js:394:11)
Dies liegt wahrscheinlich daran, dass Jest die Anzahl der Prozesse auf dem gesamten Computer (36
) und nicht die Anzahl der Prozesse, die Ihrem Container (2
) erlaubt ist, automatisch erkennt. Um das Problem zu beheben, legen Siejest --maxWorkers=2
in Ihrem Testbefehl fest.
Puppeteer in Docker ausführen
Es kann sich als schwierig erweisen, die monitorlose Chrome-Version in Docker einzurichten und auszuführen. Beim gebündelten Chromium, das Puppeteer installiert, fehlen die erforderlichen Abhängigkeiten der gemeinsam genutzten Bibliothek.
Zur Behebung dieses Problems müssen Sie die fehlenden Abhängigkeiten und das neueste Chromium-Paket in Ihrem Dockerfile installieren:
FROM node:14-slim
# Install latest chrome dev package and fonts to support major charsets (Chinese, Japanese, Arabic, Hebrew, Thai and a few others)
# Note: this installs the necessary libs to make the bundled version of Chromium that Puppeteer
# installs, work.
RUN apt-get update \
&& apt-get install -y wget gnupg \
&& wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - \
&& sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list' \
&& apt-get update \
&& apt-get install -y google-chrome-stable fonts-ipafont-gothic fonts-wqy-zenhei fonts-thai-tlwg fonts-kacst fonts-freefont-ttf libxss1 \
--no-install-recommends \
&& rm -rf /var/lib/apt/lists/*
# If running Docker >= 1.13.0 use docker run's --init arg to reap zombie processes, otherwise
# uncomment the following lines to have `dumb-init` as PID 1
# ADD https://github.com/Yelp/dumb-init/releases/download/v1.2.2/dumb-init_1.2.2_x86_64 /usr/local/bin/dumb-init
# RUN chmod +x /usr/local/bin/dumb-init
# ENTRYPOINT ["dumb-init", "--"]
# Uncomment to skip the chromium download when installing puppeteer. If you do,
# you'll need to launch puppeteer with:
# browser.launch({executablePath: 'google-chrome-stable'})
# ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD true
# Install puppeteer so it's available in the container.
RUN npm init -y && \
npm i puppeteer \
# Add user so we don't need --no-sandbox.
# same layer as npm install to keep re-chowned files from using up several hundred MBs more space
&& groupadd -r pptruser && useradd -r -g pptruser -G audio,video pptruser \
&& mkdir -p /home/pptruser/Downloads \
&& chown -R pptruser:pptruser /home/pptruser \
&& chown -R pptruser:pptruser /node_modules \
&& chown -R pptruser:pptruser /package.json \
&& chown -R pptruser:pptruser /package-lock.json
# Run everything after as non-privileged user.
USER pptruser
CMD ["google-chrome-stable"]
Erstellen Sie den Container:
docker build -t puppeteer-chrome-linux .
Führen Sie den Container aus, indem Sie node -e "<yourscript.js content as a string>"
als Befehl übergeben:
docker run -i --init --rm --cap-add=SYS_ADMIN \
--name puppeteer-chrome puppeteer-chrome-linux \
node -e "`cat yourscript.js`"
Unter https://github.com/ebidel/try-puppeteer finden Sie ein vollständiges Beispiel, das zeigt, wie dieses Dockerfile von einem Webserver ausgeführt wird, der auf App Engine Flex (Knoten) ausgeführt wird.
Alpines Laufen
Das neueste Chromium-Paket, das auf Alpine unterstützt wird, ist 100, was der Puppeteer-Version 13.5.0 entspricht.
Beispiel für ein Dockerfile:
FROM alpine
# Installs latest Chromium (100) package.
RUN apk add --no-cache \
chromium \
nss \
freetype \
harfbuzz \
ca-certificates \
ttf-freefont \
nodejs \
yarn
...
# Tell Puppeteer to skip installing Chrome. We'll be using the installed package.
ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true \
PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium-browser
# Puppeteer v13.5.0 works with Chromium 100.
RUN yarn add puppeteer@13.5.0
# Add user so we don't need --no-sandbox.
RUN addgroup -S pptruser && adduser -S -G pptruser pptruser \
&& mkdir -p /home/pptruser/Downloads /app \
&& chown -R pptruser:pptruser /home/pptruser \
&& chown -R pptruser:pptruser /app
# Run everything after as non-privileged user.
USER pptruser
...
Best Practices für Docker
Standardmäßig führt Docker einen Container mit einem gemeinsamen /dev/shm
-Arbeitsspeicher von 64 MB aus.
Dieser Wert ist in der Regel zu klein für Chrome und führt beim Rendern großer Seiten zum Absturz von Chrome. Zur Behebung dieses Fehlers führen Sie den Container mit docker run --shm-size=1gb
aus, um die Größe von /dev/shm
zu erhöhen. Seit Chrome 65 ist dies nicht mehr erforderlich. Starten Sie den Browser stattdessen mit dem Flag --disable-dev-shm-usage
:
const browser = await puppeteer.launch({
args: ['--disable-dev-shm-usage'],
});
Dadurch werden Dateien mit gemeinsam genutztem Arbeitsspeicher in /tmp
anstatt in /dev/shm
geschrieben. Prüfen Sie crbug.com/736452.
Werden beim Starten von Chrome weitere seltsame Fehler angezeigt? Versuchen Sie, den Container mit docker run --cap-add=SYS_ADMIN
bei der lokalen Entwicklung auszuführen. Da das Dockerfile einen pptr
-Nutzer als nicht privilegierten Nutzer hinzufügt, verfügt es möglicherweise nicht über alle erforderlichen Berechtigungen.
dumb-init sollte überprüft werden, wenn Chrome-Prozesse viele Zombies haben. Prozesse mit PID=1
werden speziell behandelt, was es in einigen Fällen erschwert, Chrome ordnungsgemäß zu beenden (z. B. mit Docker).
Puppeteer in der Cloud ausführen
In der Google App Engine
Die Node.js-Laufzeit der App Engine-Standardumgebung enthält alle Systempakete, die zum Ausführen von Headless Chrome erforderlich sind.
Wenn Sie puppeteer
verwenden möchten, listen Sie das Modul als Abhängigkeit in Ihrer package.json
auf und stellen Sie es in Google App Engine bereit. Weitere Informationen zur Verwendung von puppeteer
in App Engine finden Sie in der offiziellen Anleitung.
In Google Cloud Functions
Die Node.js 10-Laufzeit von Google Cloud Functions enthält alle Systempakete, die zum Ausführen von Headless Chrome erforderlich sind.
Wenn Sie puppeteer
verwenden möchten, listen Sie das Modul als Abhängigkeit in Ihrer package.json
auf und stellen Sie die Funktion mithilfe der nodejs10
-Laufzeit in Google Cloud Functions bereit.
Puppeteer in Google Cloud Run ausführen
Die Node.js-Standardlaufzeit von Google Cloud Run enthält nicht die Systempakete, die zum Ausführen von Headless Chrome erforderlich sind. Richten Sie Ihre eigene Dockerfile
ein und fügen Sie die fehlenden Abhängigkeiten hinzu.
Auf Heroku
Für die Ausführung von Puppeteer unter Heroku sind einige zusätzliche Abhängigkeiten erforderlich, die nicht im Linux-Rechner enthalten sind, den Heroku für Sie hochfährt. Um die Abhängigkeiten bei der Bereitstellung hinzuzufügen, fügen Sie das Puppeteer Heroku-Buildpack der Liste der Buildpacks für Ihre App unter Einstellungen > Buildpacks hinzu.
Die URL für das Buildpack lautet https://github.com/jontewks/puppeteer-heroku-buildpack
.
Achten Sie darauf, dass Sie den '--no-sandbox'
-Modus verwenden, wenn Sie Puppeteer starten. Übergeben Sie es dazu als Argument an den .launch()
-Aufruf: puppeteer.launch({ args: ['--no-sandbox'] });
.
Wenn Sie auf „Buildpack hinzufügen“ klicken, fügen Sie diese URL in das Eingabefeld ein und klicken Sie auf Speichern. Bei der nächsten Bereitstellung installiert Ihre App auch die Abhängigkeiten, die Puppeteer ausführen muss.
Wenn Sie chinesische, japanische oder koreanische Zeichen rendern müssen, müssen Sie möglicherweise ein Buildpack mit zusätzlichen Schriftartdateien wie https://github.com/CoffeeAndCode/puppeteer-heroku-buildpack verwenden.
Es gibt auch einen weiteren Leitfaden von @timleland, der ein Beispielprojekt enthält.
Auf AWS Lambda
AWS Lambda begrenzt die Größe von Bereitstellungspaketen auf ca. 50 MB. Dies stellt eine Herausforderung für die Ausführung von Chrome (und damit Puppeteer) auf Lambda dar. Die Community hat einige Ressourcen zusammengestellt, die die Probleme umgehen:
- Chromium Binary für AWS Lambda und Google Cloud Functions (wird mit der neuesten stabilen Version von Puppeteer aktualisiert)
- Chrome/Chromium auf AWS Lambda von Marco Lüthy ist ein serverloses Plug-in und veraltet.
AWS EC2-Instanz, auf der Amazon-Linux ausgeführt wird
Wenn eine EC2-Instanz in Ihrer CI/CD-Pipeline amazon-linux ausführt und Sie Puppeteer-Tests in amazon-linux ausführen möchten, führen Sie die folgenden Schritte aus.
Damit Sie Chromium installieren können, müssen Sie zuerst
amazon-linux-extras
aktivieren. Das Tool ist Teil von EPEL (Extra Packages for Enterprise Linux):sudo amazon-linux-extras install epel -y
Installieren Sie als Nächstes Chromium:
sudo yum install -y chromium
Jetzt kann Puppeteer Chromium zum Ausführen Ihrer Tests starten. Wenn Sie EPEL nicht aktivieren und Chromium als Teil von npm install
installieren, kann Puppeteer Chromium nicht starten, da libatk-1.0.so.0
und viele weitere Pakete nicht verfügbar sind.
Probleme bei der Codetranspilierung
Wenn Sie einen JavaScript-Transpiler wie Babel oder TypeScript verwenden, funktioniert der Aufruf von evaluate()
mit einer asynchronen Funktion möglicherweise nicht. Das liegt daran, dass puppeteer
zwar Function.prototype.toString()
zum Serialisieren von Funktionen verwendet, während Transpiler den Ausgabecode so ändern könnten, dass er nicht mit puppeteer
kompatibel ist.
Um dieses Problem zu umgehen, können Sie den Transpiler anweisen, den Code nicht zu verfälschen. Beispielsweise können Sie TypeScript so konfigurieren, dass die neueste ECM-Version ("target": "es2018"
) verwendet wird. Eine weitere Problemumgehung besteht darin, Stringvorlagen anstelle von Funktionen zu verwenden:
await page.evaluate(`(async() => {
console.log('1');
})()`);