プログラマでありたい

おっさんになっても、プログラマでありつづけたい

Node.jsのWebスクレイピングモジュール 『cheerio-httpcli』の使い方その1 cheerioでhtmlの要素指定

 少し間が空きましたが、cheerio-httpcliの使い方です。cheerio-httpcliは、HTMLパーサーであるcheerioに、文字コード変換のiconvを組み合わせたHTTPクライアントモジュールで取得したコンテンツの文字コードを良しなにUTF-8に変換してくれます。HTMLの解析&取得自体はcheerioのラッパーなので、DOM指定でHTMLの要素を取得するといったことが簡単に出来ます。cheerioを上手い感じに補っているので、cheerio-httpcliはWebスクレイピングに最適なモジュールとなっています。

cheerioのDOMセレクト機能



 cheerio-httpcliを見る前に、生のcheerioの機能を見てみましょう。そこでまず、基本中の基本であるHTML中から任意のタグを指定して取得するDOMセレクトの機能です。この部分については、cheerioのGithubページにマニュアルがあるので、そちらを見ながらです。

cheerioの基本的な構文

 cheerioのDOMセレクターの基本的な構文は、以下のとおりです。

$( selector, [context], [root] )

selectorは、取得対象の指定。contextは、範囲指定。rootは、どのhtmlタグを親とするかです。何も指定しない場合は、通常htmlタグになるでしょう。selectorとcontextの関係が解りにくいので、実例をみてみましょう。

var html = (function() {/*
        <ul id="fruits">
          <li class="apple">Apple</li>
          <li class="orange">Orange</li>
          <li class="pear">Pear</li>
        </ul>
*/}).toString().match(/\/\*([^]*)\*\//)[1];

var cheerio = require('cheerio'),
    $ = cheerio.load(html);

console.log($('.apple', '#fruits').text());
//=> Apple

console.log($('ul .pear').attr('class'));
//=> pear

console.log($('li[class=orange]').html());
//=> Orange

 selectorについては解るのですが、contextについては直感的ではないような気がしますね。上記1番目の#fruitsを指定している例だと、id="fruits"のモノに限定して検索しています。一方で、2番めの例ではselectorでul .pearで指定して、.attrメソッドで、そのclassの属性を出力するようにしています。3つ目の例は、classがorangeのliタグを検索しています。個人的には3番目が一番直感的で使いやすいです。id指定であれば、ul[id=fruits]でいけますね。

 それでは、ulタグの中のliタグといった指定の仕方はどうするのでしょうか?悩んだのですが、下記のような書き方で指定できました。単純にスペースで区切れば良いのですね。

console.log($('ul li[class=orange]').text());
//=> Orange
属性表示&操作用メソッド


 ここで、属性を表示する為のメソッドを確認してみましょう。
いろいろありますが、スクレイピング用途であれば.attr以外は使わなさそうですね。他に挙げるとしたら、.removeClass等で不要なクラスを一括削除して抽出しやすくするくらいだと思います。

メソッド 概要
.attr( name, value ) 属性取得と設定メソッド。nameのみの場合は取得、設定したい場合はvalueを指定
.prop( name, value ) プロパティの取得と設定メソッド。(input checkbox等の)状態を取得したい場合はnameのみ指定。
.data( name, value ) data属性の取得と設定メソッド
.val( [value] ) input, select, and textarea属性用
.removeAttr( name ) 属性削除
.hasClass( className ) クラスを持っているか true/false
.addClass( className ) クラスの追加
.removeClass( [className] ) クラスの削除
.toggleClass( className, [switch] ) 条件に一致したクラスの追加or削除
.is( selector )  
.is( element )  
.is( selection )  
.is( function(index) )  

まとめ



 ざっとですが、cheerio-httpcliの核の1つであるcheerioによるhtmlの要素抽出の仕方が解りました。今回の一連の調査・実験は、AWS Lambda+Node.jsでどこまでクローラー/Webスクレイピングの実行基盤を作れるか試しています。今回のような基本的なスクレイピングに始まり、動的サイトや巡回型のクローラーを作ってみようと考えています。次は、cheerio-httpcliから実際のサイトの取得を試してみます。Lambdaとは何ぞやという人は、下記の本をよろしくお願い致します。数ヶ月遊び倒せるくらいサンプルを載せております。



シリーズ目次:
Node.jsでスクレイピングするならば
AWS Lambdaでcheerio-httpcliを実行する
Node.jsのWebスクレイピングモジュール 『cheerio-httpcli』の使い方その1 cheerioでhtmlの要素指定

See Also:
『Rubyによるクローラー開発技法』を書きました
アプリケーションエンジニア向けのAWS本を書きました
『Amazon Web Services パターン別構築・運用ガイド』を書きました



参照:
GitHub - ktty1220/cheerio-httpcli: iconvによる文字コード変換とcheerioによるHTMLパースを組み込んだNode.js用HTTPクライアントモジュール
GitHub - cheeriojs/cheerio: Fast, flexible, and lean implementation of core jQuery designed specifically for the server.