🧑🏼‍💻

browserlessで最速スクレイピングをする with Deno Deploy

2024/01/14に公開

スクレイピングはまだまだめんどくさい

以前にこんな記事を書きましたが、
https://zenn.dev/ispec_inc/articles/lambda-puppeteer

これでも手順が多すぎてしんどいです、、

サーバレスにブラウザを操作したいだけなのに!!

そこで browserless というSaasを使ってchromiumの設定不要でスクレイピングをする方法をご紹介します

browserless

なんぞ?

Image from Gyazo

browserlessはヘッドレスchromiumのAPIを提供してくれるサービスです

つまりchromiumをインストールしなくてもpuppeteerを起動できちゃうんです!

LPのPlayGroundで好きに実行できるので試してみてください

↓ みたいな感じでブラウザ起動時のbrowserWSEndpoint オプションでウェブソケットのURLを指定するだけで利用できます(コードを動かすサーバーは自分で用意する必要があります)

const browser = await puppeteer.connect({
  browserWSEndpoint: `wss://chrome.browserless.io?token=${Deno.env.get("BROWSERLESS_TOKEN")}`,
});

料金

Introducing Unit-based Pricing

Unitベースの課金でpuppeteerなら28秒が1unitとなり、1000unitまでは無料なので、個人の利用なら無料で十分に活用できると思います

実用編

外形監視

Deno Deployでやってみます

弊社のホームページのスクショを定期的にslackに投稿する例です

Deno DeployにCronが乗ったのでまじで以下のファイルをpushするだけで動きます(もちろんbrowserlessとslack webhookの設定は必要です)

Deno Deployはファイル書き込みができないのですが、@slack/web-apiの画像アップロードAPIがBufferも受け付けてくれるのでありがたく使います

参考

// 環境変数に BROWSERLESS_TOKEN, SLACK_TOKENをセットしています
import puppeteer from "https://deno.land/x/puppeteer@16.2.0/mod.ts";
import { WebClient } from "npm:@slack/web-api";
import { Buffer } from 'node:buffer';

const main = async () => {
    const browserlessToken = Deno.env.get("BROWSERLESS_TOKEN");
    const slackToken = Deno.env.get("SLACK_TOKEN");
    if (!browserlessToken || !slackToken) {
        throw "[ERROR] `BROWSERLESS_TOKEN` and `SLACK_TOKEN` is required"
    }
    const browser = await puppeteer.connect({
      browserWSEndpoint: `wss://chrome.browserless.io?token=${browserlessToken}`,
    });

    const page = await browser.newPage();

    await page.goto('https://ispec.tech');
    const arr = await page.screenshot();

    // https://slack.dev/node-slack-sdk/web-api
    // slack/web-apiのfiles.uploadV2ではfile意外にfileBufferとReadStreamを渡せる
    const buf = Buffer.from(arr);

    await browser.close();

    const client = new WebClient(slackToken);
    await client.files.uploadV2({
        channel_id: "your-channel-id",
        file: buf,
        filename: "ispec.png",
    });
}

// 毎日朝9時(JST)に起動
Deno.cron("Daily Cron morning", "0 0 * * *", async () => {
    await main();
});

結果はこんな感じできちんと投稿されました!✌️ (アニメーションのせいかなんか白いですが、まぁよし)
Image from Gyazo

終わりに

Deno + browserlessの破壊力が伝わったら嬉しいです

人間がやるべきではない仕事はゴンゴン自動化していきましょう!

GitHubで編集を提案
ispec

Discussion