هدلس کروم در ویندوز راه اندازی نمی شود
برخی از خطمشیهای Chrome ممکن است اجرای Chrome یا Chromium را با برنامههای افزودنی خاص اعمال کنند.
Puppeteer به طور پیشفرض پرچم --disable-extensions
را پاس میکند و بنابراین وقتی چنین خطمشیهایی فعال هستند راهاندازی نمیشود.
برای حل این مشکل، بدون پرچم اجرا کنید:
const browser = await puppeteer.launch({
ignoreDefaultArgs: ['--disable-extensions'],
});
متن: شماره 3681 .
هدلس کروم در یونیکس راه اندازی نمی شود
مطمئن شوید که تمام وابستگی های لازم نصب شده اند. می توانید ldd chrome | grep not
تا بررسی کند کدام وابستگی وجود ندارد.
وابستگی های دبیان (اوبونتو).
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
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
پس از نصب وابستگی ها، باید کتابخانه nss را با استفاده از این دستور به روز کنید
yum update nss -y
بررسی بحث ها:
Headless Chrome ترکیب GPU را غیرفعال می کند
Chrome و Chromium برای فعال کردن شتاب GPU در حالت بدون سر به --use-gl=egl
نیاز دارند.
const browser = await puppeteer.launch({
headless: true,
args: ['--use-gl=egl'],
});
Chrome دانلود شده است اما در Node.js راه اندازی نمی شود
اگر هنگام تلاش برای راهاندازی Chromium با خطایی به این شکل مواجه شدید:
(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
این بدان معنی است که مرورگر دانلود شده است اما به درستی استخراج نشده است. شایعترین علت یک اشکال در Node.js نسخه 14.0.0 است که extract-zip
شکست، ماژول Puppeteer از آن برای استخراج دانلودهای مرورگر در مکان مناسب استفاده میکند. این اشکال در Node.js v14.1.0 برطرف شد، بنابراین مطمئن شوید که آن نسخه یا بالاتر را اجرا می کنید.
یک جعبه ایمنی Chrome Linux راه اندازی کنید
برای محافظت از محیط میزبان در برابر محتوای وب غیرقابل اعتماد، Chrome از چندین لایه sandboxing استفاده میکند. برای اینکه این کار به درستی کار کند، ابتدا میزبان باید پیکربندی شود. اگر سندباکس خوبی برای استفاده کروم وجود نداشته باشد، با خطای No usable sandbox!
.
اگر به محتوایی که در Chrome باز می کنید کاملاً اعتماد دارید، می توانید Chrome را با آرگومان --no-sandbox
راه اندازی کنید:
const browser = await puppeteer.launch({
args: ['--no-sandbox', '--disable-setuid-sandbox'],
});
2 راه برای پیکربندی جعبه ایمنی در Chromium وجود دارد.
[توصیه می شود] شبیه سازی فضای نام کاربری را فعال کنید
شبیه سازی فضای نام Sser فقط توسط هسته های مدرن پشتیبانی می شود. فضاهای نام کاربری غیرمجاز عموماً برای فعال کردن مناسب هستند، اما میتوانند سطح حمله هسته بیشتری را برای فرآیندهای غیر ریشه (جعبه نشده) باز کنند تا به امتیازات هسته ارتقا پیدا کنند.
sudo sysctl -w kernel.unprivileged_userns_clone=1
[جایگزین] راه اندازی جعبه شنی setuid
جعبه شنی setuid به عنوان یک فایل اجرایی مستقل ارائه می شود و در کنار Chromium که Puppeteer دانلود می کند قرار دارد. استفاده مجدد از همان جعبه اجرائی یکسان برای نسخه های مختلف Chromium خوب است، بنابراین موارد زیر را می توان تنها یک بار در هر محیط میزبان انجام داد:
# 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
ممکن است بخواهید متغیر CHROME_DEVEL_SANDBOX
env را به طور پیش فرض صادر کنید. در این مورد، موارد زیر را به ~/.bashrc
یا .zshenv
اضافه کنید:
export CHROME_DEVEL_SANDBOX=/usr/local/sbin/chrome-devel-sandbox
Puppeteer را روی Travis CI اجرا کنید
ما آزمایشات خود را برای Puppeteer در Travis CI تا نسخه 6.0.0 اجرا کردیم و پس از آن به GitHub Actions مهاجرت کردیم. برای مرجع می توانید .travis.yml
(v5.5.0) را ببینید.
در اینجا برخی از بهترین شیوه ها وجود دارد:
- سرویس xvfb باید برای اجرای Chromium در حالت غیر هدلس راه اندازی شود
- به طور پیش فرض روی لینوکس Xenial در تراویس اجرا می شود
-
npm install
به صورت پیش فرض اجرا می کند -
node_modules
به طور پیش فرض ذخیره می شود
.travis.yml
ممکن است به شکل زیر باشد:
language: node_js
node_js: node
services: xvfb
script:
- npm run test
Puppeteer را در CircleCI اجرا کنید
- با یک تصویر NodeJS در پیکربندی خود شروع کنید.
yaml docker: - image: circleci/node:14 # Use your desired version environment: NODE_ENV: development # Only needed if puppeteer is in `devDependencies`
- وابستگی هایی مانند
libXtst6
احتمالاً باید باapt-get
نصب شوند، بنابراین از گوی threetreeslight/puppeteer ( دستورالعمل ها ) استفاده کنید یا بخش هایی از منبع آن را در پیکربندی خود بچسبانید. - در نهایت، اگر از Puppeteer از طریق Jest استفاده میکنید، ممکن است با خطای ایجاد فرآیندهای فرزند مواجه شوید:
shell [00:00.0] jest args: --e2e --spec --max-workers=36 Error: spawn ENOMEM at ChildProcess.spawn (internal/child_process.js:394:11)
این احتمالاً به دلیل شناسایی خودکار تعداد پردازشها در کل دستگاه (36
) توسط Jest به جای تعداد مجاز به ظرف شما (2
) است. برای رفع این مشکل،jest --maxWorkers=2
در دستور تست خود تنظیم کنید.
Puppeteer را در Docker اجرا کنید
راهاندازی و اجرای هدلس Chrome در Docker میتواند مشکل باشد. Chromium همراهی که Puppeteer نصب میکند، وابستگیهای لازم کتابخانه مشترک را ندارد.
برای رفع این مشکل، باید وابستگیهای گمشده و آخرین بسته Chromium را در Dockerfile خود نصب کنید:
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"]
ظرف را بسازید:
docker build -t puppeteer-chrome-linux .
کانتینر را با ارسال node -e "<yourscript.js content as a string>"
به عنوان دستور اجرا کنید:
docker run -i --init --rm --cap-add=SYS_ADMIN \
--name puppeteer-chrome puppeteer-chrome-linux \
node -e "`cat yourscript.js`"
یک مثال کامل در https://github.com/ebidel/try-puppeteer وجود دارد که نشان می دهد چگونه این Dockerfile را از یک وب سرور در حال اجرا بر روی App Engine Flex (Node) اجرا کنید.
در آلپاین بدوید
جدیدترین بسته Chromium پشتیبانی شده در Alpine 100 است که با Puppeteer v13.5.0 مطابقت دارد.
نمونه 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
...
بهترین روش ها با Docker
بهطور پیشفرض، Docker یک کانتینر با فضای حافظه مشترک /dev/shm
64 مگابایتی اجرا میکند. این معمولاً برای Chrome بسیار کوچک است و باعث میشود کروم هنگام رندر کردن صفحات بزرگ از کار بیفتد. برای رفع مشکل، کانتینر را با docker run --shm-size=1gb
اجرا کنید تا اندازه /dev/shm
را افزایش دهید. از Chrome 65، این دیگر ضروری نیست. در عوض، مرورگر را با پرچم --disable-dev-shm-usage
راه اندازی کنید:
const browser = await puppeteer.launch({
args: ['--disable-dev-shm-usage'],
});
این فایل های حافظه مشترک را به جای /dev/shm
در /tmp
می نویسد. بررسی crbug.com/736452 .
آیا هنگام راه اندازی Chrome خطاهای عجیب دیگری می بینید؟ هنگام توسعه محلی، کانتینر خود را با docker run --cap-add=SYS_ADMIN
اجرا کنید. از آنجایی که Dockerfile یک کاربر pptr
را به عنوان یک کاربر غیرمجاز اضافه می کند، ممکن است تمام امتیازات لازم را نداشته باشد.
dumb-init ارزش این را دارد که بررسی کنید اگر زامبی های زیادی را تجربه می کنید که فرآیندهای کروم در اطراف شما باقی مانده است. روش خاصی برای فرآیندهای با PID=1
وجود دارد که در برخی موارد (مانند Docker) بهدرستی پایان دادن به Chrome را دشوار میکند.
Puppeteer را در ابر اجرا کنید
در موتور برنامه گوگل
زمان اجرا Node.js محیط استاندارد App Engine با تمام بسته های سیستمی مورد نیاز برای اجرای Headless Chrome ارائه می شود.
برای استفاده از puppeteer
، ماژول را به عنوان یک وابستگی در package.json
خود فهرست کنید و در Google App Engine قرار دهید. با دنبال کردن آموزش رسمی، درباره استفاده از puppeteer
در App Engine بیشتر بخوانید.
در Google Cloud Functions
زمان اجرا Node.js 10 Google Cloud Functions با تمام بسته های سیستمی مورد نیاز برای اجرای Headless Chrome ارائه می شود.
برای استفاده از puppeteer
، ماژول را به عنوان یک وابستگی در package.json
خود فهرست کنید و تابع خود را با استفاده از زمان اجرا nodejs10
در Google Cloud Functions پیاده کنید.
Puppeteer را در Google Cloud Run اجرا کنید
زمان اجرای پیشفرض Node.js Google Cloud Run با بستههای سیستمی مورد نیاز برای اجرای Headless Chrome ارائه نمیشود. Dockerfile
خود را راه اندازی کنید و وابستگی های از دست رفته را اضافه کنید .
روی هیروکو
اجرای Puppeteer در Heroku به برخی وابستگیهای اضافی نیاز دارد که در جعبه لینوکس که Heroku برای شما میچرخاند وجود ندارد. برای افزودن وابستگیها به هنگام استقرار، بسته ساخت Puppeteer Heroku را به لیست بستههای ساخت برنامه خود در تنظیمات > Buildpacks اضافه کنید.
نشانی اینترنتی buildpack https://github.com/jontewks/puppeteer-heroku-buildpack
است.
هنگام راهاندازی Puppeteer، مطمئن شوید که از حالت '--no-sandbox'
استفاده میکنید. این کار را می توان با ارسال آن به عنوان آرگومان به .launch()
فراخوانی انجام داد: puppeteer.launch({ args: ['--no-sandbox'] });
.
وقتی روی افزودن buildpack کلیک میکنید، آن URL را در ورودی قرار دهید و روی ذخیره کلیک کنید. در استقرار بعدی، برنامه شما وابستگی هایی را که Puppeteer برای اجرا نیاز دارد نیز نصب می کند.
اگر نیاز به رندر کردن نویسههای چینی، ژاپنی یا کرهای دارید، ممکن است لازم باشد از یک buildpack با فایلهای فونت اضافی مانند https://github.com/CoffeeAndCode/puppeteer-heroku-buildpack استفاده کنید.
همچنین راهنمای دیگری از @timleland وجود دارد که شامل یک پروژه نمونه است.
در AWS Lambda
AWS Lambda اندازه بسته استقرار را به 50 مگابایت محدود می کند . این چالشهایی را برای اجرای کروم بدون هد (و در نتیجه Puppeteer) در Lambda ایجاد میکند. جامعه چند منبع را گردآوری کرده است که در مورد مسائل کار می کنند:
- Chromium Binary برای AWS Lambda و Google Cloud Functions (با آخرین نسخه پایدار Puppeteer به روز می شود)
- Chrome/Chromium در AWS Lambda از Marco Lüthy یک افزونه بدون سرور است و قدیمی است.
نمونه AWS EC2 که آمازون-لینوکس را اجرا می کند
اگر یک نمونه EC2 دارید که amazon-linux را در خط لوله CI/CD خود اجرا می کند و می خواهید تست های Puppeteer را در amazon-linux اجرا کنید، این مراحل را دنبال کنید.
برای نصب Chromium، ابتدا باید
amazon-linux-extras
که بخشی از EPEL (بستههای اضافی برای لینوکس سازمانی) است، فعال کنید:sudo amazon-linux-extras install epel -y
سپس، Chromium را نصب کنید:
sudo yum install -y chromium
اکنون Puppeteer میتواند Chromium را برای اجرای آزمایشهای شما راهاندازی کند. اگر EPEL را فعال نکنید و به نصب Chromium به عنوان بخشی از npm install
ادامه دهید، Puppeteer نمیتواند Chromium را راهاندازی کند به دلیل در دسترس نبودن libatk-1.0.so.0
و بسیاری از بستههای دیگر.
مشکلات ترجمه کد
اگر از ترانسپایلر جاوا اسکریپت مانند babel یا TypeScript استفاده می کنید، evaluate()
value با یک تابع async ممکن است کار نکند. این به این دلیل است که در حالی که puppeteer
از Function.prototype.toString()
برای سریال کردن توابع استفاده می کند در حالی که transpiler ها می توانند کد خروجی را به گونه ای تغییر دهند که با puppeteer
ناسازگار باشد.
برخی از راهحلهای حل این مشکل این است که به ترانسپایلر دستور دهید تا کد را به هم نریزد، برای مثال، TypeScript را برای استفاده از آخرین نسخه ecma پیکربندی کنید ( "target": "es2018"
). راه حل دیگر می تواند استفاده از قالب های رشته ای به جای توابع باشد:
await page.evaluate(`(async() => {
console.log('1');
})()`);