WSLgを使いPuppeteerでChromiumを非ヘッドレス(GUI)で動かす
WSLgは「Windows Subsystem for Linux GUI」の略で、WSL上でLinux GUIアプリケーションを動かす仕組みです。
WSLgの仕組みが無かったときは、VcXsrvというWindows用のXサーバアプリを使いWSL側のGUIを表示させていたのですが、WSLgが使えるようになり、こちらが不要になりました。
Puppeteer(パペティア)は、Chrome/Chromiumを操作できるNode.jsのライブラリです。
WSLgの仕組みを使い、PuppeteerでChromiumを非ヘッドレス(GUI)で動かしたいと思います。
確認
まず、Linux GUIアプリケーションが動作するか確認します。
Windows TerminalなどからWSLを起動します。
X11アプリケーションをインストール。
sudo apt update
sudo apt install -y x11-apps
電卓を起動。
xcalc
電卓が起動できれば、WSLgが使える状態です。
WSL
WSLでChromiumを動かします。
GUIに必要なライブラリやフォントをインストールします。
sudo apt install -y libgtk2.0-0 libgtk-3-0 libnotify-dev libgconf-2-4 libnss3 libxss1 libasound2 libxtst6 xauth xvfb libgbm-dev fonts-ipafont
適当なディレクトリを作成しその中で動作させます。
mkdir chromium-test
cd chromium-test
Puppeteerをインストールします。
この時、Chromiumもダウンロードされます。
npm install puppeteer
Chromiumを操作するプログラムを作成します。
vi open.js
const puppeteer = require("puppeteer");
(async () => {
try {
const browser = await puppeteer.launch({
headless: false,
slowMo: 30,
args: [
"--no-sandbox",
"--disable-setuid-sandbox",
"--window-size=1024,768",
],
});
const page = (await browser.pages())[0];
await page.goto("https://www.yahoo.co.jp");
await page.waitForTimeout(5000);
await page.screenshot({ path: 'screenshot.png',fullPage: true,});
await browser.close();
} catch (e) {
console.log(e);
}
})();
実行します。
node open
Chromiumを起動し、Yahoo!を表示します。
5秒待った後にスクリーンショットを作成します。
Linuxの画像ビューアをインストールして、スクリーンショットを確認できます。
sudo apt install -y feh
feh screenshot.png
ちなみに、WSLではWindowsのエクスプローラーを呼び出すことも可能なので、エクスプローラーからの確認も可能です。
explorer.exe .
Docker
WSL上で動くDockerからWSLgを動かすことも可能です。
mkdir chromium-docker-test
cd chromium-docker-test
vi Dockerfile
FROM node:18-bullseye
RUN apt update \
&& apt install -y feh \
libgtk2.0-0 libgtk-3-0 libnotify-dev libgconf-2-4 libnss3 libxss1 libasound2 libxtst6 xauth xvfb libgbm-dev fonts-ipafont
vi docker-compose.yml
services:
node:
build:
context: ./
environment:
- DISPLAY=$DISPLAY
- PULSE_SERVER=$PULSE_SERVER
- WAYLAND_DISPLAY=$WAYLAND_DISPLAY
- XDG_RUNTIME_DIR=$XDG_RUNTIME_DIR
volumes:
- ./:/app
- /tmp/.X11-unix:/tmp/.X11-unix
- /mnt/wslg:/mnt/wslg
tty: true
working_dir: /app
user: node
コンテナを起動します。
docker compose up -d
コンテナに入ります。
docker compose exec node bash
Puppeteerをインストールします。
この時、Chromiumもダウンロードされます。
npm install puppeteer
Chromiumを操作するプログラムを作成します。
vi open.js
const puppeteer = require("puppeteer");
(async () => {
try {
const browser = await puppeteer.launch({
headless: false,
slowMo: 30,
args: [
"--no-sandbox",
"--disable-setuid-sandbox",
"--window-size=1024,768",
],
});
const page = (await browser.pages())[0];
await page.goto("https://www.yahoo.co.jp");
await page.waitForTimeout(5000);
await page.screenshot({ path: 'screenshot.png',fullPage: true,});
await browser.close();
} catch (e) {
console.log(e);
}
})();
実行します。
node open
Chromiumを起動し、Yahoo!を表示します。
5秒待った後にスクリーンショットを作成します。
スクリーンショットを確認できます。
feh screenshot.png
コンテナをでます。
exit
コンテナを削除します。
docker compose down
おわりに
このようにWSLgの仕組みを使い、LinuxのGUIを動かすことが可能です。
Puppeteerなどでブラウザの操作を行う際に、GUIで確認しながら開発することができ便利かと思います。
参考
Discussion