JavaScript
ClojureScript
nodejs
puppeteer
headless-chrome

puppeteerをlumo+calvinで使ってみる

puppeteerが話題になっていて気になってみたので触ってみた。

使用したもの

  • calvin 0.2.0
  • lumo 1.7.0

新しいnodeをインストールする

puppeteerは古いnodeバージョンだと動かない。

筆者はUbuntuを使っているが、apt-getで入るやつのバージョンが古いので、
こちらの記事を参考に新しいバージョンをゲットした

後からnodenvなる物の存在を教えてもらった。こちらの方が好ましいらしい。

strictモードを無効にする

  • puppeteerはOctalのリテラルを使用しており、strict modeに違反している
  • Lumoはデフォルトでstrictのチェックが有効になっている

なのでこの情報を参照してstrictチェックを無効にした。

(def v8 (js/require "v8"))
(.setFlagsFromString v8 "--no-use_strict")

動かす

calvinのproject.clj

(defproject plc "0.0.1"
  :dependencies [[org.clojure/clojurescript "1.9.293"]]
  :cljsbuild {:builds [{:id "dev"
                        :source-paths ["src"]
                        :compiler {:main plc.core
                                   :target :nodejs
                                   :npm-deps {"puppeteer" "0.10.2"}}}]})

puppeteerのReadmeの例

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.goto('https://example.com');
  await page.screenshot({path: 'example.png'});

  browser.close();
})();

無理矢理ClojureScriptに訳す

asyncとかawaitのシンタックスをどうマッピングすれば良いのか検討もつかないので返ってくるPromiseに対して.thenメソッドを呼ぶようにしてみた。

(require '[puppeteer :as p])
(do
  (def b (p/launch #js {:headless false}))
  (def p (.then b (fn [browser] (.newPage browser))))
  (.then p (fn [p]
             (.then (.goto p "https://example.com")
                    (fn [_] (.screenshot p #js {:path "example.png"}))))))

上記でスクショが取れることは確認できた。
楽しそうなことに使えるので色々応用していこうと思う。