前言
Google Chrome早就支持了headless
模式,但一般都是在Linux上运行,而我则习惯于在WSL
上开发,折腾了好久终于找到了可以在WSL上跑headless
模式的方法。
以下以WSL
中安装的是Ubuntu 18.04
系统为例。
常见安装方法
安装依赖库
$ sudo apt install gconf-service libasound2 libatk1.0-0 libc6 libcairo2 libcups2 libdbus-1-3 libexpat1 libfontconfig1 libgcc1 libgconf-2-4 libgdk-pixbuf2.0-0 libglib2.0-0 libgtk-3-0 libnspr4 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 ca-certificates fonts-liberation libappindicator3-1 libnss3 lsb-release xdg-utils
安装Chrome
$ wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
$ sudo dpkg -i google-chrome-stable_current_amd64.deb
$ which google-chrome
/usr/bin/google-chrome
使用Chrome Headless访问网页
使用 官方文档的方法打开Chrome:
$ google-chrome --headless --disable-gpu --screenshot https://www.baidu.com/
出现如下报错信息:
Failed to move to new namespace: PID namespaces supported, Network namespace supported, but failed: errno = Permission denied
Failed to generate minidump.Illegal instruction (core dumped)
使用如下命令行也不行:
$ google-chrome --no-sandbox --headless --no-gpu --disable-setuid-sandbox --screenshot http://www.baidu.com/
[0829/140949.035033:WARNING:gpu_process_host.cc(1188)] The GPU process has crashed 1 time(s)
[0829/140950.200613:WARNING:gpu_process_host.cc(1188)] The GPU process has crashed 2 time(s)
[0829/140951.306996:WARNING:gpu_process_host.cc(1188)] The GPU process has crashed 3 time(s)
增加--single-process
参数后打印如下信息:
[0829/141145.431580:ERROR:browser_main_loop.cc(584)] Failed to put Xlib into threaded mode.
[0829/141146.090239:INFO:headless_shell.cc(572)] Written to file screenshot.png.
虽然看起来有报错,但是的确生成网页截图了。
screenshot.png
显示如下:
看起来有两个问题:
- 中文没有正确显示
- 窗口大小偏小
中文显示的问题可以通过以下命令解决:
$ sudo apt install fonts-noto-cjk
修改窗口大小可以通过增加--window-size=1920,1080
参数进行修改。
开启远程调试
Headless
模式下一般需要通过Chrome远程调试协议进行访问。
命令行增加--remote-debugging-port=9200
参数启动Chrome后,打印出以下信息:
[0829/194236.072838:ERROR:browser_main_loop.cc(584)] Failed to put Xlib into threaded mode.
DevTools listening on ws://127.0.0.1:9200/devtools/browser/18442c9f-b0ee-4149-a16b-f49622047621
[0829/194236.299565:ERROR:command_buffer_proxy_impl.cc(107)] ContextResult::kTransientFailure: Shared memory region is not valid
看起来调试端口是启动成功了。
但是在访问调试页面后,Chrome进程Crash
了。
Segmentation fault (core dumped)
试了多个页面后发现,远程调试都会导致Crash,看来这条路不太好走。
使用puppeteer提供的Chrome
无意中发现,puppeteer
中提供的Chrome竟然可以在WSL中开启调试端口并正常访问。
puppeteer默认下载地址的格式为:https://storage.googleapis.com/chromium-browser-snapshots/${platform}/${revision}/chrome-${revision}.zip
。例如目前Linux上最新版本的URL为:https://storage.googleapis.com/chromium-browser-snapshots/Linux_x64/674921/chrome-linux.zip
也可以使用镜像网站下载,例如:https://npm.taobao.org/mirrors/chromium-browser-snapshots/
。
解压出来就可以直接用了。
总结
- 安装依赖库,包括中文字体库
- 使用puppeteer提供的Chrome版本
- 完整的启动命令行:
chrome --no-sandbox --headless --no-gpu --disable-setuid-sandbox --single-process --window-size=1920,1080 --screenshot --remote-debugging-port=9200 http://www.baidu.com/
顺便提供一下puppeteer
使用的完整命令行:
chrome --disable-background-networking --enable-features=NetworkService,NetworkServiceInProcess --disable-background-timer-throttling --disable-backgrounding-occluded-windows --disable-breakpad --disable-client-side-phishing-detection --disable-component-extensions-with-background-pages --disable-default-apps --disable-dev-shm-usage --disable-extensions --disable-features=site-per-process,TranslateUI,BlinkGenPropertyTrees --disable-hang-monitor --disable-ipc-flooding-protection --disable-popup-blocking --disable-prompt-on-repost --disable-renderer-backgrounding --disable-sync --force-color-profile=srgb --metrics-recording-only --no-first-run --enable-automation --password-store=basic --use-mock-keychain --headless --hide-scrollbars --mute-audio about:blank --no-sandbox --disable-setuid-sandbox --remote-debugging-port=0 --user-data-dir=/tmp/puppeteer_dev_profile-NkEdQ6