Security News
Maven Central Adds Sigstore Signature Validation
Maven Central now validates Sigstore signatures, making it easier for developers to verify the provenance of Java packages.
cheerio-httpcli
Advanced tools
Node.jsでWEBページのスクレイピングを行う際に必要となる文字コードの変換とHTMLのパースを行った後のオブジェクトを取得できるHTTPクライアントモジュールです。
実装にあたり、以下のモジュールを利用しています。
cheerioはHTMLをjQueryライクにパースしてくれるモジュールです。パース後のオブジェクトを格納する変数名を「$」にすると、
$('title').text()
のようなjQueryそのままの形で要素の情報を取得できます。
上記npmモジュールの他にURLエンコード用にecl_new.jsも利用しています。
cheerio.load()
でパースしたオブジェクトも取得できる。npm install cheerio-httpcli
url
で指定したWEBページをGETメソッドで取得し、文字コードの変換とHTMLパースを行いcallback
関数に返します。
callback
関数には以下の4つの引数が渡されます。
cheerio.load()
でHTMLコンテンツをパースしたオブジェクト(独自拡張版)response
オブジェクト(独自拡張版)GET時にパラメータを付加する場合は第2引数のget-param
に連想配列で指定します。
var client = require('cheerio-httpcli');
// Googleで「node.js」について検索する。
var word = 'node.js';
client.fetch('http://www.google.com/search', { q: word }, function (err, $, res, body) {
// レスポンスヘッダを参照
console.log(res.headers);
// HTMLタイトルを表示
console.log($('title').text());
// リンク一覧を表示
$('a').each(function (idx) {
console.log($(this).attr('href'));
});
});
同梱の「example/google.js」はGoogle検索結果の一覧を取得するサンプルです。参考にしてください。
fetch()
の第3引数であるcallback
関数を省略すると、戻り値としてPromiseオブジェクトが返ります。先ほどのサンプルをプロミス形式で呼び出すと以下のようになります。
var client = require('cheerio-httpcli');
// Googleで「node.js」について検索する。
var word = 'node.js';
// callbackを指定しなかったのでPromiseオブジェクトが返る
var p = client.fetch('http://www.google.com/search', { q: word })
p.then(function (result) {
// レスポンスヘッダを参照
console.log(result.response.headers);
// HTMLタイトルを表示
console.log(result.$('title').text());
// リンク一覧を表示
result.$('a').each(function (idx) {
console.log(result.$(this).attr('href'));
});
})
p.catch(function (err) {
console.log(err);
});
p.finally(function () {
console.log('done');
});
callback
関数を指定しないfetch()
の戻り値をp
変数が受け取り、そのp
変数を通してthen
(正常終了時)およびcatch
(エラー発生時)の処理を行っています。また、正常終了でもエラーでも必ず最後に通る処理であるfinally
も使用できます。
then
に渡されるパラメータはコールバック形式で呼び出した際にcallback
関数に渡されるものと同じですが、第1引数のオブジェクトにまとめて入っているという点で異なるのでご注意ください。
error
... Errorオブジェクト$
... cheerio.load()
でHTMLコンテンツをパースしたオブジェクト(独自拡張版)response
... requestモジュールのresponse
オブジェクト(独自拡張版)body
... UTF-8に変換したHTMLコンテンツ.then(function (result) {
console.log(result); => {
error: ...,
$: ...,
response: ...,
body: ...
};
});
とあるサイトのトップページにアクセスして、その中のとあるページに移動して...というように順を追ってWEBページに潜っていきたい場合などもメソッドチェーンでこんな感じに書くことができます。
var client = require('cheerio-httpcli');
client.fetch(<TOPページのURL>)
.then(function (result) {
// 何か処理
return client.fetch(<ページAのURL>); // Promiseオブジェクトを返す
})
.then(function (result) {
// 何か処理
return client.fetch(<ページA-1のURL>); // Promiseオブジェクトを返す
})
.then(function (result) {
// 何か処理
return client.fetch(<ページA-2のURL>); // Promiseオブジェクトを返す
})
.catch(function (err) {
// どこかでエラーが発生
console.log(err);
})
.finally(function () {
// TOPページ => ページA => ページA-1 => ページA-2の順にアクセスした後に実行される
// エラーが発生した場合もcatchの処理後に実行される
console.log('done');
});
実体はrsvpのPromiseオブジェクトなので、詳細はそちらのドキュメントをご覧ください。
fetch()
の第3引数のcallback
関数を指定した場合はPromiseオブジェクトは返しません。したがってコールバック形式で呼び出しつつPromiseオブジェクトで何かをするということはできません。
ブラウザごとのUser-Agentをワンタッチで設定するメソッドです。
var client = require('cheerio-httpcli');
client.setBrowser('chrome'); // GoogleChromeのUser-Agentに変更
client.setBrowser('android'); // AndroidのUser-Agentに変更
client.setBrowser('googlebot'); // GooglebotのUser-Agentに変更
User-Agentを指定したブラウザのものに変更した場合はtrue
、対応していないブラウザを指定するとUser-Agentは変更されずにfalse
が返ります。
対応しているブラウザは以下のとおりです。
default
なお、細かいバージョンの指定まではできないので、そういった指定も行いたい場合は手動で以下のようにUser-Agentを指定してください。
// IE6のUser-Agentを手動で指定
client.headers['User-Agent'] = 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)';
cheerio-httpcliは、実行時にインストールされているiconv系のモジュールをチェックして利用するモジュールを自動的に決定しています。優先順位は以下のとおりです。
iconv-liteはcheerio-httpcliのインストール時に依存モジュールとして一緒にインストールされますが、ネイティブモジュールであるiconv-jpやiconvがインストールされている場合、処理速度や対応文字コードの多さというメリットがあるそちらを優先してロードするようになっています。
このメソッドは自動的にロードされたiconv系モジュールを破棄して、使用するiconv系モジュールを手動で指定するためのものです。モジュールテスト時の切り替え用メソッドなので基本的には実用性はありません。
iconv-module-name
には使用するiconv系モジュール名('iconv-jp'
, 'iconv'
, 'iconv-lite'
)のいずれかの文字列を指定します。
var client = require('cheerio-httpcli');
// あえてiconv-liteを使用
client.setIconvEngine('iconv-lite');
client.fetch( ...
cheerio-httpcliのバージョン情報です。
requestモジュールで使用するリクエストヘッダ情報の連想配列です。デフォルトでは何も指定されていませんが、fetch()
実行時にUser-Agentが空の場合は自動的にUser-AgentにIE11の情報が入ります。
requestモジュールで指定するタイムアウト情報です。デフォルトでは30秒となっています(効いているかどうか不明)。
サーバーとの通信にgzip転送を使用するかどうかを真偽値で指定します。デフォルトはtrue
(gzip転送する)です。
リファラーを自動でセットするかどうかの指定です。true
にすると1つ前にfetch()
したページのURLが自動でリクエストヘッダのRefererにセットされます。デフォルトはtrue
です。
cheerio-httpcliではcheerioオブジェクトのprototypeを拡張していくつかの便利メソッドを実装しています。
取得したWEBページに関する情報(URLとエンコーディング)を取得できます。
client.fetch('http://hogehoge/', function (err, $, res, body) {
var docInfo = $.documentInfo();
console.log(docInfo.url); // http://hogehoge/
console.log(docInfo.encoding); // 'utf-8'
});
fetch()
で指定したURLがリダイレクトされた場合はリダイレクト先のURLがurl
に入ります。encoding
に関しても同様で、最終的に到達したページのエンコーディングが入ります。
a
タグでのみ使用できます。
href
属性に指定されているURLと取得したページのURLを組み合わせて移動先のURLを作成し、fetch()
を実行します。fetch()
と同様に引数のcallback
関数の有無でコールバック形式とプロミス形式の指定を切り替えられます。
client.fetch('http://hogehoge/')
.then(function (result) {
// id="login"の子のリンクをクリック(プロミス形式)
return result.$('#login a').click();
})
.then(function (result) {
// クリックした先のURL取得後の処理
});
注意点として、このclick()
メソッドはjavascriptリンクやonclick="..."
などの動的処理には対応していません。あくまでもhref
のURLに簡単にアクセスできるための機能です。
なお、$(...)
で取得したa
タグオブジェクトが複数ある場合は先頭のオブジェクトに対してのみ実行されます。
form
タグでのみ使用できます。
指定したフォーム内に配置されているinput
やcheckbox
などのフォーム部品から送信パラメータを自動作成し、action
属性のURLにmethod
属性でフォームを送信します。fetch()
と同様に引数のcallback
関数の有無でコールバック形式とプロミス形式の指定を切り替えられます。
また、フォーム送信パラメータはparam
引数で指定した連想配列の内容で上書きできるので、利用する側ではパラメータを変更したい項目だけ指定するだけで済みます。
client.fetch('http://hogehoge/')
.then(function (result) {
// ユーザー名とパスワードだけ入力して、あとはフォームのデフォルト値で送信する
var loginInfo = {
user: 'guest',
pass: '12345678'
};
// name="login"フォームを送信(コールバック形式)
result.$('form[name=login]').submit(loginInfo, function (err, $, res, body) {
// フォーム送信後に移動したページ取得後の処理
});
})
cheerio-httpcliは内部でクッキーも保持するので、ログインが必要なページの取得などもsubmit()
でログイン後に巡回できるようになります。
その他の仕様はclick()
と同様です。
onsubmit="xxx"
や送信ボタンのonclick="..."
で実行される動的処理には対応していません。$(...)
で取得したform
タグオブジェクトが複数ある場合は先頭のオブジェクトに対してのみ実行されます。fetch()
、cheerio.click()
、cheerio.submit()
などで取得できるresponse
オブジェクトはrequestモジュールで取得したものですが、独自拡張としてcookies
プロパティを付け足しています。
client.fetch('http://hogehoge/')
.then(function (result) {
// プロミス形式でログインフォーム送信
return result.$('form[name=login]').submit({ user: 'hoge', pass: 'fuga' })
})
.then(function (result) {
// ログイン後のクッキー内容確認
console.log(result.response.cookies);
});
このcookies
プロパティには現在取得したページのサーバーから送られてきたクッキーのキーと値が連想配列で入っています。セッションIDやログイン状態の確認などに使えるかもしれません。
なお、このcookies
の値を変更してもリクエスト処理には反映されません。クッキー確認専用のプロパティです。
<head>
タグのcharset情報を参照します。後者での判別時においてcharsetで指定された文字コードとWEBページの実際の文字コードが異なる場合は変換エラーや文字化けが発生します。MIT licenseで配布します。
© 2013 ktty1220
0.3.1 (2015-02-15)
.html()
で取得する文字列がHTMLエンティティに変換されないようにしたFAQs
http client module with cheerio & iconv(-lite) & promise
The npm package cheerio-httpcli receives a total of 270 weekly downloads. As such, cheerio-httpcli popularity was classified as not popular.
We found that cheerio-httpcli demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Maven Central now validates Sigstore signatures, making it easier for developers to verify the provenance of Java packages.
Security News
CISOs are racing to adopt AI for cybersecurity, but hurdles in budgets and governance may leave some falling behind in the fight against cyber threats.
Research
Security News
Socket researchers uncovered a backdoored typosquat of BoltDB in the Go ecosystem, exploiting Go Module Proxy caching to persist undetected for years.