はじめに
Node.jsでHTMLを解析したいとき、どうしていますか。正規表現でゴリ押ししようとして、ネストしたタグの構造に心が折れた経験がある方も多いのではないでしょうか。かといってブラウザを丸ごと立ち上げるのは、単純なテキスト抽出には大げさすぎます。
そんな悩みを解決してくれるのがCheerioです。ブラウザを起動せずに、jQueryそのままの感覚でHTMLをパース・操作できる軽量ライブラリで、GitHub上で3万を超えるスターを集める定番ツールとして今も活発に開発が続けられています。
Cheerioとは
Cheerioは「高速で柔軟、かつエレガントなHTML/XML解析・操作ライブラリ」です。DOM APIをそのまま実装しているわけではなく、必要な部分だけを実装した軽量な独自パーサーの上に、おなじみの$()セレクタ構文を再現しています。ブラウザやheadlessブラウザを起動しないため、動作が非常に高速で、サーバーサイドでのスクレイピングやHTML加工に広く使われています。
主な特徴
- jQuery互換の書き味 -
$('selector').find()や.text()、.attr()といったおなじみのAPIでDOM操作ができる - 軽量・高速 - ブラウザエンジンを使わないため、メモリ消費が少なく処理も高速
- CSSセレクタ完全対応 - class・id・属性セレクタや擬似セレクタまで柔軟に指定可能
- TypeScript対応 - 型定義が同梱されており、型安全にDOM操作ができる
インストール
npm、yarn、pnpmなど、お好きなパッケージマネージャーでインストールできます。
# npm
npm install cheerio
# yarn
yarn add cheerio
# pnpm
pnpm add cheerio
基本的な使い方
まずはシンプルなHTML文字列を読み込み、要素を取得してみましょう。
import * as cheerio from 'cheerio';
const html = `
<ul id="fruits">
<li class="item">りんご</li>
<li class="item">みかん</li>
<li class="item">ぶどう</li>
</ul>
`;
const $ = cheerio.load(html);
// class="item" を持つ要素のテキストを配列で取得
const fruits = $('.item')
.map((_, el) => $(el).text())
.get();
console.log(fruits);
// ["りんご", "みかん", "ぶどう"]
cheerio.load()でHTMLを読み込むと、jQueryライクな$関数が使えるようになります。あとはCSSセレクタで要素を絞り込み、.text()や.attr()でデータを取り出すだけです。
要素の追加・属性の書き換えといった操作も直感的に行えます。
import * as cheerio from 'cheerio';
const $ = cheerio.load('<div id="app"></div>');
$('#app')
.append('<p class="message">読み込み完了</p>')
.find('.message')
.attr('data-status', 'ready');
console.log($.html());
// <html><head></head><body>
// <div id="app"><p class="message" data-status="ready">読み込み完了</p></div>
// </body></html>
実践的なユースケース
実際の開発現場では、外部サイトから取得したHTMLをパースして必要な情報を抽出するケースが多く見られます。以下は、取得済みのHTML文字列から記事の一覧情報を抽出する例です。
import * as cheerio from 'cheerio';
// 何らかの方法で取得済みのHTML文字列(取得処理自体はこの例には含みません)
function extractArticles(html) {
const $ = cheerio.load(html);
const articles = [];
$('article.post').each((_, el) => {
const $el = $(el);
articles.push({
title: $el.find('h2.title').text().trim(),
summary: $el.find('p.summary').text().trim(),
link: $el.find('a').attr('href') ?? null,
});
});
return articles;
}
const sampleHtml = `
<article class="post">
<h2 class="title">Cheerio入門</h2>
<p class="summary">サーバーサイドでHTMLを解析する方法</p>
<a href="/posts/cheerio-intro">続きを読む</a>
</article>
`;
console.log(extractArticles(sampleHtml));
// [{ title: 'Cheerio入門', summary: 'サーバーサイドでHTMLを解析する方法', link: '/posts/cheerio-intro' }]
このように、each()でループしながらfind()やtext()を組み合わせることで、複雑な構造を持つHTMLからでも必要なデータだけを綺麗に取り出せます。テストコードのDOM検証や、社内向けのRSS・サイトマップ生成ツールなど、応用範囲は広いです。
まとめ
Cheerioは、ブラウザを起動せずにjQuery感覚でHTMLを解析・操作できる、軽量かつ高速なライブラリです。正規表現による無理なパース処理から解放され、CSSセレクタで直感的に要素を扱えるようになる点が最大の魅力といえるでしょう。
まずは手元にあるHTMLファイルをcheerio.load()で読み込むところから試してみてください。慣れてきたら、実際のプロジェクトでのデータ抽出処理に組み込んでみると、その使いやすさを実感できるはずです。