Cheerio で Web ページをスクレイピングする

Node.js スクリプトから Web ページのスクレイピングができないか調べてみたところ、Cheerio という npm パッケージを使うのが簡単そうだったのでやってみた。

目次

モジュールのインストール

Cheerio 自体は、受け取った HTML 文字列をパースして jQuery ライクに扱えるようにしてくれるだけなので、Web ページを取得する部分は別の npm パッケージを使わないといけない。今回は request-promise というライブラリが扱いやすかったので、コレを使うことにした。

$ npm install --save cheerio request-promise

Web ページを取得する

scrape.js などという適当なファイルを作り、以下のように実装してみる。

const requestPromise = require('request-promise');
const cheerio = require('cheerio');

// URL を指定して HTML を取得する
requestPromise.get('https://google.com/', {
  headers: {
    // ページによっては UA 偽装しておかないと正常に取得できない場合があったりするので、適当に Windows Chrome の UA 文字列を差し込んだりしておく
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36'
  },
  transform: (rawHtml) => {
    // Cheerio を使い jQuery ライクなオブジェクトに変換する
    return cheerio.load(rawHtml);
  }
})
  .then(($) => {
    // ページ取得成功
    
    // 例えば以下のように CSS クラス別に操作したりできる
    $('.contents-item').each((index, element) => {
      // 指定の要素内のテキストを取得したり
      const itemTitle = $(element).find('.contents-item-title').text();
      // 要素の属性値を取得したり
      const itemUrl = $(element).find('a.contents-item-details-link').attr('href');
    });
  });

requestPromise.get() の第1引数で URL を指定する。すると Promise の then() でその内容が受け取れるのだが、第2引数のオプションで transform オプション関数を設定している。ココで Cheerio を差し込み、ただの HTML 文字列が返されるところ、jQuery ライクなオブジェクトに変換している。そのため、then() の仮引数を $ と表現していて、以降は jQuery よろしく each() とか find() とかなんとかいう操作ができるのである。

UA 偽装については、Web スクレイピング対策として UA が見られていることが多いので、Windows の Chrome ブラウザから拾ってきた UA 文字列を入れている。簡易的なスクレイピング対策であればコレで回避できる。

ものすごく簡単だが、このようにして Web ページをスクレイピングすることができた。