💻

WSLgを使いPuppeteerでChromiumを非ヘッドレス(GUI)で動かす

2022/12/22に公開

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
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
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
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
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で確認しながら開発することができ便利かと思います。

参考

https://github.com/SARDONYX-sard/zenn/blob/master/articles/9726126c4a67ffb66509.md
https://blog.mohyo.net/2022/02/11591/

GitHubで編集を提案

Discussion