ペチパーノート

WEB開発系Tipsブログです。

puppeteerでMyProteinの価格を取得するツールを作った

きっかけ

わたくしMyProtein社のプロテインを飲んでいます。
定期的にセールをやっているのですが、 種類毎に価格が違ったりします。
そこでスクレイピングで価格を抽出するツールを作りました。

法律的な話

MyProteinの利用規約に「スクレイピングを禁止する」文面は見当たりませんでした。
サーバーに負荷をかけないように注意すれば問題はなさそうです。

以下の記事を参考にさせて頂きました。
Webスクレイピングに関する10のよくある誤解 - Octoparse | スクレイピングツール

構想

スクレイピングといえばPythonですが、
あまり触った事がないため、JavaScript(Node.js)で作ってみます。
とりあえずテキストで表示できればよいので、CSVで出力することにします。

結果

こんな感じで取得できました。

アイスラテ,1kg,¥3,890
アイスラテ,2.5kg,¥7,390
アイスラテ,5kg,¥14,290
アイスラテ,250g,¥1,590
アイリッシュ コーヒー,1kg,¥3,890
アップルクランブルとカスタード,1kg,¥3,890
アップルクランブルとカスタード,2.5kg,¥7,390
イートン メス,1kg,¥3,290
…省略

開発

使ったライブラリはpuppeteer(パペティア)
コマンドでChromeを制御するためのライブラリです。
(デフォルトはヘッドレスなので画面が表示されることもありません)

GitHub - puppeteer/puppeteer: Headless Chrome Node.js API

ブラウザを起動してホエイプロテインの販売ページにアクセスするソースコード

const puppeteer = require("puppeteer");

(async () => {
  const browser = await puppeteer.launch({
  });
  const page = await browser.newPage();
  await page.goto(
    "https://www.myprotein.jp/sports-nutrition/impact-whey-protein/10530943.html"
  );
/* ここでゴニョゴニョして価格を抽出する */
  await browser.close();
})();

ブラウザ操作する例はこんな感じ

# セレクタを指定してクリック
await page.click("#mainContent");

またサーバーに負荷をかけないように、ボタンクリックやドロップダウンの選択は1秒待つようにしました。

await page.waitForTimeout(1000);

APIはdocsにまとめられています。
https://github.com/puppeteer/puppeteer/blob/main/docs/api.md

要素を取得するには、様々な方法があるようですが違いがよくわかっていません…

  • page.evaluete()
  • page.$()
  • page.$$()
  • page.$$eval()
  • page.$eval()

自分はevaluete()しか使いませんでした。
イメージでは「ブラウザ内で実行する処理」を関数で渡す感じ。
documentオブジェクトが使えたので、ブラウザ内のJavaScriptを書くイメージで使えました。

作ったツールはこちら

github.com

目的は達成しました。puppeteerもおもしろかったです。
ちゃんと理解してないので、もう少しやってみたい気持ちになりました。