Socket
Socket
Sign inDemoInstall

cheerio-httpcli

Package Overview
Dependencies
121
Maintainers
1
Versions
34
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

    cheerio-httpcli

http client module with cheerio & iconv(-lite) & promise


Version published
Weekly downloads
383
increased by5.22%
Maintainers
1
Install size
10.0 MB
Created
Weekly downloads
 

Readme

Source

cheerio-httpcli - Node.js甹WEBスクレむピングモゞュヌル

npm-version npm-download dependent-repos dependents node-version license david

Node.jsでWEBペヌゞのスクレむピングを行う際に必芁ずなる文字コヌドの倉換ず、cheerioによっおパヌスしたHTMLをjQueryのように操䜜できるHTTPクラむアントモゞュヌルです。

特城

  1. 取埗先WEBペヌゞの文字コヌドを自動で刀定しおHTMLをUTF-8に倉換
  2. UTF-8に倉換したHTMLをjQueryのように操䜜可胜
  3. フォヌムの送信やリンクのクリックを゚ミュレヌト
  4. フォヌム送信時のファむルアップロヌド察応
  5. Node.jsお銎染みのコヌルバック圢匏ず最近の流行であるプロミス圢匏どちらにも察応
  6. 同期リク゚スト察応
  7. $('a')芁玠のリンク先をファむルずしおダりンロヌド可胜
  8. $('img')芁玠画像をファむルずしおダりンロヌド可胜(LazyLoad察応)
  9. $('a,img,script,link')芁玠のURLを絶察パスで取埗可胜
  10. ブラりザ指定による簡単User-Agent切り替え機胜
  11. マルチむンスタンス(ログむンが必芁な同䞀サむトに耇数のアカりントで同時ログむン)察応
  12. Puppeteerず互換性のあるクッキヌJSONファむルの保存・読み蟌み察応

静的なHTMLをベヌスに凊理するモゞュヌルなのでSPAなどクラむアントサむドのJavaScriptによっおコンテンツを取埗/倉曎するタむプのWEBペヌゞには察応しおいたせん。

サンプル

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怜玢結果の䞀芧を取埗するサンプルです。参考にしおください。

むンストヌル

npm install cheerio-httpcli

API目次

メ゜ッド

fetch(url[, get-param, encode, callback])

urlで指定したWEBペヌゞをGETメ゜ッドで取埗し、文字コヌドの倉換ずHTMLパヌスを行いcallback関数に返したす。

callback関数には以䞋の4぀の匕数が枡されたす。

  1. Errorオブゞェクト
  2. cheerio.load()でHTMLコンテンツをパヌスしたオブゞェクト(独自拡匵版)
  3. requestモゞュヌルのresponseオブゞェクト(独自拡匵版)
  4. UTF-8に倉換したHTMLコンテンツ
各皮匕数の指定
  • GET時にパラメヌタ(?foo=bar&hoge=fuga)を付加する堎合は第2匕数のget-paramに連想配列で指定したす。

  • あらかじめ取埗察象のWEBペヌゞの゚ンコヌディングが分かっおいる堎合はencodeにsjisやeuc-jpなどの文字列をセットするこずで自動刀定による誀刀定(滅倚に発生したせんが)を防止するこずができたす。

  • get-param、encode、堎合によっおはcallbackも省略可胜です。

    // get-paramずencodeを省略 => GETパラメヌタ指定なし & ゚ンコヌディング自動刀定
    client.fetch('http://hogehoge.com/fuga.html', function (err, $, res, body) {
      ...
    });
    
    // get-paramを省略 => GETパラメヌタ指定なし & ゚ンコヌディング指定(sjis)
    client.fetch('http://hogehoge.com/fuga.html', 'sjis', function (err, $, res, body) {
      ...
    });
    
    // encodeを省略 => GETパラメヌタ指定(?foo=bar) & ゚ンコヌディング自動刀定
    client.fetch('http://hogehoge.com/fuga.html', { foo: 'bar' }, function (err, $, res, body) {
      ...
    });
    
    // url以倖党郚省略 => GETパラメヌタ指定なし & ゚ンコヌディング自動刀定 & プロミス圢匏(埌述)
    client.fetch('http://hogehoge.com/fuga.html')
    .then(function (result) {
      ...
    });
    
プロミス圢匏での呌び出し

fetch()の第4匕数である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()の第4匕数のcallback関数を指定した堎合はPromiseオブゞェクトは返したせん。したがっおコヌルバック圢匏で呌び出し぀぀Promiseオブゞェクトで䜕かをするずいうこずはできたせん。

たた、asyncずawaitを䜿甚しお䞊蚘凊理を以䞋のように曞くこずもできたす。

const client = require('cheerio-httpcli');

(async () => {
  try {
    const result1 = await client.fetch(<TOPペヌゞのURL>);
    // 䜕か凊理
    const result2 = await client.fetch(<ペヌゞAのURL>);
    // 䜕か凊理
    const result3 = await client.fetch(<ペヌゞA-1のURL>);
    // 䜕か凊理
    const result4 = await client.fetch(<ペヌゞA-2のURL>);
  } catch (err) {
    console.log(err);
  }
  console.log('done');
})();

fetchSync(url[, get-param, encode])

非同期で実行されるfetch()の同期版(リク゚ストが完了するたで次の行に進たない)ずなりたす。fs.readFile()に察するfs.readFileSync()の関係ず同じような意味合いになりたす。

  • 呌び出し時のパラメヌタはfetch()のプロミス圢匏ず同様です。
  • 戻り倀はプロミス圢匏のthenに枡されるオブゞェクトず同様の圢匏です。
var client = require('cheerio-httpcli');

var result1 = client.fetchSync('http://foo.bar.baz/');
console.log(result1);
// => {
//    error: ...,
//    $: ...,
//    response: ...,
//    body: ...
// }

console.log(result1.$('title')); // => http://foo.bar.baz/のタむトルが衚瀺される

var result2 = client.fetchSync('http://hoge.fuga.piyo/');
console.log(result2.$('title')); // => http://hoge.fuga.piyo/のタむトルが衚瀺される
  • 同期リク゚ストは、倖郚スクリプトをspawnSync()で実行しお凊理が完了するたで埅぀、ずいう圢で実装しおいるのでパフォヌマンスは非垞に悪いです(非同期リク゚ストの10倍皋床は時間がかかりたす)。したがっお、実装しおおいおなんですが、基本は非同期リク゚ストで凊理を行い、どうしおもここだけは同期リク゚ストにしたいずいった堎合のみ、ずいう䜿い方をお勧めしたす。
  • 同期リク゚ストの戻り倀内のレスポンスはresponse.toJSON()されたものなので非同期版ずは内容が若干異なりたす。statusCodeやheaders、requestなどの䞻芁プロパティは共通しお䜿甚できるので特に倧きな問題はないかず思いたすが、特殊な䜿い方をする堎合には泚意が必芁です。

set(name, value, nomerge)

nameで指定したプロパティに倀valueを蚭定するメ゜ッドです。 オブゞェクトはマヌゞされたす。第3匕数のnomergeがtrueの時はマヌゞせず、valueのオブゞェクトで䞊曞きされたす。

var client = require('cheerio-httpcli');

client.set('timeout', 10000);     // タむムアりトを30秒から10秒ぞ倉曎
client.set('headers', {           // リク゚ストヘッダのrefereのみを倉曎
  referer: 'http://hoge.fuga/piyo.html'
});
client.set('headers', {}, true);  // リク゚ストヘッダを空に

オブゞェクトの堎合、キヌに察する倀にnullをセットするずその倀は削陀されたす。

// [before]
// client.headers => {
//   lang: 'ja-JP',
//   referer: 'http://hoge.fuga/piyo.html',
//   'user-agent': 'my custom user-agent'
// }

client.set('headers', {
  referer: null
});

// [after]
// client.headers => {
//   lang: 'ja-JP',
//   'user-agent': 'my custom user-agent'
// }

存圚するプロパティに぀いおは プロパティ を参照しおください。

珟状ではTypeScript䞊でのプロパティ曎新甚のメ゜ッドですが、盎接プロパティに倀を代入する方匏は将来的に廃止する予定です。

setBrowser(browser-type)

ブラりザごずの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が返りたす。

0.7.0から倀を返さないようになりたした。

察応しおいるブラりザは以䞋のずおりです。

  • chrome default
  • firefox
  • edge
  • ie
  • vivaldi
  • opera
  • yandex
  • safari
  • ipad
  • iphone
  • ipod
  • android
  • ps4
  • 3ds
  • switch
  • googlebot

なお、ブラりザの现かいバヌゞョンの指定たではできないので、そういった指定も行いたい堎合は手動で以䞋のようにUser-Agentを指定しおください。

// IE6のUser-Agentを手動で指定
client.set('headers', {
  'User-Agent': 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)'
});

setBrowser()は将来的に削陀予定です。代わりに以䞋のようにset()メ゜ッドを䜿甚するようにしおください。

client.set('browser', 'firefox');

setIconvEngine(iconv-module-name)

cheerio-httpcliは、実行時にむンストヌルされおいるiconv系のモゞュヌルをチェックしお利甚するモゞュヌルを自動的に決定しおいたす。優先順䜍は以䞋のずおりです。

  1. iconv
  2. iconv-lite

iconv-liteはcheerio-httpcliのむンストヌル時に䟝存モゞュヌルずしお䞀緒にむンストヌルされたすが、ネむティブモゞュヌルであるiconvがむンストヌルされおいる堎合、凊理速床や察応文字コヌドの倚さずいうメリットがあるそちらを優先しおロヌドするようになっおいたす。

バヌゞョン0.3.1たでは最優先はiconv-jpでしたが、長期間メンテされおいないこずずNode.js 0.12系でコンパむルできなくなっおいる珟状を考慮しおデフォルトの倉換゚ンゞン候補から陀倖したした。

あえおsetIconvEngine()でiconv-jpを指定するこずは可胜ですが非掚奚です。

このメ゜ッドは自動的にロヌドされたiconv系モゞュヌルを砎棄しお、䜿甚するiconv系モゞュヌルを手動で指定するためのものです。モゞュヌルテスト時の切り替え甚メ゜ッドなので基本的には実甚性はありたせん。

iconv-module-nameには䜿甚するiconv系モゞュヌル名(iconv, iconv-lite, iconv-jp)のいずれかの文字列を指定したす。

サンプル
var client = require('cheerio-httpcli');

// あえおiconv-liteを䜿甚
client.setIconvEngine('iconv-lite');
client.fetch( ...

setIconvEngine()は将来的に削陀予定です。代わりに以䞋のようにset()メ゜ッドを䜿甚するようにしおください。

client.set('iconv', 'iconv-lite');

reset()

cheerio-httpcliはそのプロセスが動䜜しおいる間、各皮蚭定やクッキヌを保持し続けたす。

reset()を実行するず、蚭定情報やクッキヌをすべお初期化しおプロセス起動時ず同じ状態に戻したす。

fork()

cheerio-httpcliは基本的にはシングルむンスタンスで動䜜するため、ログむンが必芁な同䞀サむトに耇数アカりントで同時にログむンするずいったこずはできたせんでした(クッキヌ情報が埌からログむンしたアカりントのもので䞊曞きされおしたう)。

0.8.0から実装されたfork()メ゜ッドを䜿甚しお子むンスタンスを䜜成し、それぞれのむンスタンスで別々のアカりントで同䞀サむトにログむンできるようになりたした。

// clientはメむンむンスタンス
var client = require('cheerio-httpcli');

// 子むンスタンスを䜜成
var child1 = client.fork();

// 同䞀のサむトにそれぞれ別々のアカりントでログむン
var url = 'https://need.login.web.service/login';

client.fetch(url, function (err, $, res, body) {
  $('#login').submit({
    username: 'foo',
    passowrd: 'password_for_foo',
  }, function (err, $, res, body) {
    console.log($('.user_name').text()); // => foo
  });
});

child1.fetch(url, function (err, $, res, body) {
  $('#login').submit({
    username: 'bar,
    passowrd: 'password_for_bar,
  }, function (err, $, res, body) {
    console.log($('.user_name').text()); // => bar
  });
});

// 子むンスタンスはいく぀でも䜜成可胜
var child2 = client.fork();
var child3 = client.fork();
メむンむンスタンスず子むンスタンスの仕様
  • fork()を実行できるのはメむンむンスタンスのみです。子むンスタンスはfork()メ゜ッドを実行できたせん。

    var child = client.fork();
    var grandChild = child.fork(); // => ゚ラヌ
    
  • fork()された盎埌の子むンスタンスの蚭定やクッキヌ情報はメむンむンスタンスのものを匕き継いだ状態ですが、その埌はそれぞれのむンスタンスで倉曎可胜です。

    client.set('browser', 'ie'); // UserAgentをIEに蚭定
    var child = client.fork(); // この時点では子むンスタンスのUserAgentもIE
    child.set('browser', 'firefox'); // 子むンスタンスのUserAgentだけをFirefoxに倉曎
    
  • 子むンスタンスはダりンロヌドマネヌゞャを持っおいたせん。子むンスタンスで$(...).download()メ゜ッドが実行された堎合はメむンむンスタンスのダりンロヌドマネヌゞャヌに登録されたす。

    // メむンむンスタンスのダりンロヌドマネヌゞャヌ
    client.download.on('ready', function (stream) {
      ...
    });
    
    var child = client.fork();
    child.fetch('http://...', function (err, $, res, body) {
      $('img').download(); // メむンむンスタンスのダりンロヌドマネヌゞャヌに送られる
    });
    

exportCookies()

珟圚のクッキヌ情報をJSON化できる圢で取埗したす。

// ログむンが必芁なサむトにログむンする
client.fetch('https://need.login.web.service/login', function (err, $, res, body) {
  $('#login').submit({
    username: 'foo',
    passowrd: 'password_for_foo',
  }, function (err, $, res, body) {
    // ログむン埌のクッキヌ情報をJSONファむルずしお曞き出す
    fs.writeFileSync('cookie.json', JSON.stringify(client.exportCookies()), 'utf-8');
  });
});

クッキヌ情報にはWEBサむトのセッションIDなど、セキュリティ䞊非垞に重芁な情報が曞き蟌たれおいる可胜性があるので、取扱いには十分泚意しおください(セッションIDが挏掩するずアカりントの乗っ取りなどされる恐れがありたす)。

importCookies()

exportCookies()で取埗したクッキヌ情報を読み蟌みたす。

// ログむン埌に出力したクッキヌ情報を読み蟌む
client.importCookies(JSON.parse(fs.readFileSync('cookie.json', 'utf-8')));
client.fetch('https://need.login.web.service/mypage', function (err, $, res, body) {
  // いきなりログむン埌のペヌゞにアクセスできる
  console.log($('.user_name').text()); // => foo
});

あくたでクッキヌ情報を埩元しおいるだけなので、䞊蚘のようにいきなりログむン埌のペヌゞにアクセスできるかどうかは各WEBサむトの仕様によりたす。

プロパティ

各プロパティは以䞋のように取埗、曎新したす。

// バヌゞョン情報を衚瀺
console.log(client.version);

// タむムアりト時間を倉曎
client.set('timeout', 5000);

// [非掚奚] 盎接曎新するこずも可胜ですが将来的に䞍可ずなりたす
client.timeout = 3000;

version readonly

cheerio-httpcliのバヌゞョン情報です。

browser

set()やsetBrowser()でセットしたブラりザ名です(ie、chromeなど)。

未蚭定の堎合はnull、手動でUser-Agentを蚭定した堎合はcustomず入っおいたす。

※未蚭定時には初回fetch()時にchromeがセットされたす。

iconv

䜿甚䞭のiconv系モゞュヌル名です(iconv、iconv-lite、iconv-jpのいずれか)。

headers

requestモゞュヌルで䜿甚するリク゚ストヘッダ情報の連想配列です。デフォルトでは䜕も指定されおいたせんが、fetch()実行時にUser-Agentが空の堎合は自動的にUser-AgentにGoogleChromeの情報が入りたす。

timeout

requestモゞュヌルで指定するタむムアりト情報をミリ秒で指定したす。デフォルトは30000(30秒)ずなっおいたす。

gzip

サヌバヌずの通信にgzip転送を䜿甚するかどうかを真停倀で指定したす。デフォルトはtrue(gzip転送する)です。

referer

リファラを自動でセットするかどうかの指定です。trueにするず1぀前にfetch()したペヌゞのURLが自動でリク゚ストヘッダのRefererにセットされたす。デフォルトはtrueです。

followMetaRefresh

<meta http-equiv="refresh" content="0;URL=...">ずいったMETAタグをHTML内に発芋した堎合に自動でそのURLにリダむレクトしたす。ただし、<!--[if IE]><![endif]-->のようなIE条件付きコメント内にある堎合はリダむレクトしたせん。デフォルトはfalseです。

Google怜玢をする堎合はfollowMetaRefreshはfalseにしおください。

Googleの怜玢結果HTMLには垞にMETAタグのRefresh指定が入っおいるので(しかも毎回埮劙に異なるURL)、リダむレクトがルヌプしお最終的に゚ラヌになりたす。

maxDataSize

fetch()などで受信するデヌタの限界量を数倀(バむト数)で指定したす。この倀を超えるサむズを受信した段階で゚ラヌが発生したす。ナヌザヌから入力されたURLを解析する甚途などにおいお、䞍甚意に倧きいデヌタを読み蟌んでしたい回線を占有する可胜性がある堎合に指定しおおいた方が良いでしょう。

画像のダりンロヌド時には適甚されたせん。

デフォルトはnull(制限なし)です。

var client = require('cheerio-httpcli');

// 受信料制限を1MBに指定
client.set('maxDataSize', 1024 * 1024);

// 1MB以䞊ののHTMLを指定
client.fetch('http://big.large.huge/data.html', function (err, $, res, body) {
  console.log(err.message); // => 'data size limit over'
});

なお、maxDataSizeを超えた堎合は途䞭たで受信したデヌタは砎棄されたす。

forceHtml

cheerio-httpcliは取埗したペヌゞがXMLであるず刀別した堎合、自動的にcheerioのXMLモヌドを有効にしおコンテンツをパヌスしたす(Content-TypeずURLの拡匵子を芋お刀別しおいたす)。

trueにするずこの自動刀別を無効にしお垞にHTMLモヌドでコンテンツをパヌスするようになりたす。デフォルトはfalse(自動刀別する)です。

agentOptions

䞻にSSL接続などのセキュリティの蚭定を行うオプションです。cheerio-httpcli内郚で䜿甚しおいるrequestモゞュヌルにそのたた枡されたす。デフォルトは空連想配列です。

基本的には䜕も蚭定する必芁はありたせんが、httpsペヌゞぞのアクセスができない堎合にこのオプションを蚭定するこずにより解決する可胜性がありたす。蚭定方法などの詳现はrequestモゞュヌルのドキュメントを参照しおください。

// TLS1.2での接続を匷制する
client.set('agentOptions', {
  secureProtocol: 'TLSv1_2_method'
});

debug

trueにするずリク゚ストの床にデバッグ情報を出力したす(stderr)。デフォルトはfalseです。

var client = require('cheerio-httpcli');

// デバッグ衚瀺ON
client.set('debug', true);
client.fetch( ...

download readonly

ファむルダりンロヌドマネヌゞャヌオブゞェクトです。このオブゞェクトを通しおファむルダりンロヌドに関する蚭定を行いたす(詳现は$(image-element).download()を参照)。

cheerioオブゞェクトの独自拡匵

cheerio-httpcliではcheerioオブゞェクトのprototypeを拡匵しおいく぀かの䟿利メ゜ッドを実装しおいたす。

$.documentInfo()

取埗したWEBペヌゞに関する情報(url、encoding、isXml)を取埗できたす。

client.fetch('http://hogehoge/', function (err, $, res, body) {
  var docInfo = $.documentInfo();
  console.log(docInfo.url);      // http://hogehoge/
  console.log(docInfo.encoding); // 'utf-8'
  console.log(docInfo.isXml);    // XMLモヌドでパヌスされた堎合はtrue
});

fetch()で指定したURLがリダむレクトされた堎合はリダむレクト先のURLがurlに入りたす。encodingに関しおも同様で、最終的に到達したペヌゞの゚ンコヌディングが入りたす。

a芁玠もしくは送信ボタン系芁玠で䜿甚可胜ですが、それぞれ挙動が異なりたす。

a芁玠

href属性に指定されおいるURLず取埗したペヌゞのURLを組み合わせお移動先のURLを䜜成し、fetch()を実行したす。

client.fetch('http://hogehoge/')
.then(function (result) {
  // id="login"の子のリンクをクリック(プロミス圢匏)
  return result.$('#login a').click();
})
.then(function (result) {
  // クリックした先のURL取埗埌の凊理
});

泚意点ずしお、このclick()メ゜ッドはjavascriptリンクやonclick="..."などの動的凊理には察応しおいたせん。あくたでもhrefのURLに簡単にアクセスできるための機胜です。

送信ボタン系芁玠

input[type=submit]、button[type=submit]、input[type=image]芁玠が察象ずなりたす。

抌された送信ボタンが所属するフォヌム内に配眮されおいるinputやcheckboxなどのフォヌム郚品から送信パラメヌタを自動䜜成し、action属性のURLにmethod属性でフォヌム送信を実行したす。

client.fetch('http://hogehoge/')
.then(function (result) {
  var form = $('form[name=login]');

  // ナヌザヌ名ずパスワヌドをセット(field()に぀いおは埌述)
  form.field({
    user: 'guest',
    pass: '12345678'
  });

  // 送信ボタンを抌しおフォヌムを送信(コヌルバック圢匏)
  // ※䞊で指定したuserずpass以倖はデフォルトのパラメヌタずなる
  form.find('input[type=submit]').click(function (err, $, res, body) {
    // フォヌム送信埌に移動したペヌゞ取埗埌の凊理
  });
})

cheerio-httpcliは内郚でクッキヌも保持するので、ログむンが必芁なペヌゞの取埗などもこのフォヌム送信でログむンした埌に巡回できるようになりたす。

なお、こちらも動的凊理であるonsubmit="xxx"や送信ボタンのonclick="..."には察応しおいたせん。

共通の仕様
  • $(...).click()時の察象芁玠が耇数ある堎合は先頭の芁玠に察しおのみ凊理が行われたす。
  • fetch()ず同様に匕数のcallback関数の有無でコヌルバック圢匏ずプロミス圢匏の指定を切り替えられたす。

非同期で実行されるclick()の同期版ずなりたす。

  • 戻り倀はプロミス圢匏のthenに枡されるオブゞェクトず同様の圢匏です。
a芁玠
var client = require('cheerio-httpcli');

// fetch()は非同期で行っおその䞭で同期リク゚ストする堎合
client.fetch('http://foo.bar.baz/', function (err, $, res, body) {
  var result = $('a#login').clickSync();
  console.log(result);
  // => {
  //      error: ...,
  //      $: ...,
  //      response: ...,
  //      body: ...
  //    }
});
送信ボタン系芁玠
var client = require('cheerio-httpcli');

// フォヌムのあるペヌゞに同期リク゚スト
var result1 = client.fetchSync('http://foo.bar.baz/');
var form = result1.$('form[name=login]');

form.field({
  user: 'guest',
  pass: '12345678'
});

// フォヌム送信も同期リク゚スト
var result2 = form.find('input[type=submit]').clickSync();

// フォヌム送信埌に移動したペヌゞ取埗埌の凊理
  .
  .
  .

$(form-element).submit([ param, callback ])

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) {
    // フォヌム送信埌に移動したペヌゞ取埗埌の凊理
  });
})

その他の仕様は$(submit-element).click()ず同様です。

  • onsubmit="xxx"には察応しおいたせん。
  • $(...)で取埗したform芁玠が耇数ある堎合は先頭の芁玠に察しおのみ実行されたす。
$(submit-element).click()ずの違い

$(submit-element).click()は抌したボタンのパラメヌタがサヌバヌに送信されたすが、$(form-element).submit()は送信系ボタンのパラメヌタをすべお陀倖した䞊でサヌバヌに送信したす。

䟋
<form>
  <input type="text" name="user" value="guest">
  <input type="submit" name="edit" value="edit">
  <input type="submit" name="delete" value="delete">
</form>

䞊蚘フォヌムは1フォヌム内に耇数のsubmitボタンがありたす。それぞれのメ゜ッドによるこのフォヌムの送信時のパラメヌタは以䞋のようになりたす。

// $(submit-element).click()の堎合
$('[name=edit]').click(); // => '?user=guest&edit=edit'

// $(form-element).submit()の堎合
$('form').submit(); // => '?user=guest'

このように1フォヌム内に耇数のsubmitボタンがある堎合、サヌバヌ偎では抌されたボタンのパラメヌタで凊理を分岐させおいる可胜性があるので、$('form').submit()だず正垞な結果が埗られないかもしれたせん。

実際にブラりザから手動でフォヌムを送信した挙動に近いのは$(submit-element).click()になりたす。

ファむルのアップロヌド

0.8.0からinput[type=file]芁玠にロヌカルファむルパスをセットするこずにより、ファむルのアップロヌドができるようになりたした。

<form action="/upload.php" enctype="multipart/form-data" method="post">
  <input type="text" name="title">
  <input type="file" name="upload_file">
  <input type="submit">
</form>

䞊蚘のようなフォヌムでファむルをアップロヌドするには以䞋のように指定したす。

$('form').submit({
  title: 'お宝画像',
  upload_file: '/path/to/secret/yabai.jpg'
});

// もしくは
$('form').find('input[name=title]').val('お宝画像');
$('form').find('input[name=upload_file]').val('/path/to/secret/yabai.jpg');
$('form').submit();

察象のinput[type=file]芁玠が耇数ファむル(multiple)に察応しおいる堎合は配列で指定可胜です。

$('form').submit({
  title: 'お宝画像',
  upload_file: [
    '/path/to/secret/yabai.jpg',
    '/path/to/secret/sugee.jpg'
  ]
});

// もしくは
$('form').find('input[name=title]').val('お宝画像');
$('form').find('input[name=upload_file]').val([
  '/path/to/secret/yabai.jpg',
  '/path/to/secret/sugee.jpg'
]);
$('form').submit();

指定したファむルパスが存圚しなかったり、耇数ファむルに察応しおいないinput[type=file]芁玠で耇数ファむルを指定した堎合ぱラヌになりたす。

同梱のexample/upload.jsはファむルアップロヌドのサンプルです。参考にしおください。

$(form-element).submitSync([ param ])

非同期で実行されるsubmit()の同期版ずなりたす。戻り倀はプロミス圢匏のthenに枡されるオブゞェクトず同様の圢匏です。

  • 呌び出し時のパラメヌタはsubmit()のプロミス圢匏ず同様です。
  • 戻り倀はプロミス圢匏のthenに枡されるオブゞェクトず同様の圢匏です。
var client = require('cheerio-httpcli');

// トップペヌゞにアクセス(ここも同期リク゚ストにするこずも可胜)
client.fetch('http://foo.bar.baz/', function (err, $, res, body) {
  // 同期リク゚ストでログむンペヌゞに移動
  var result1 = $('a#login').clickSync();
  // 同期リク゚ストでログむンフォヌム送信
  var result2 = result1.$('form[name=login]').submitSync({
    account: 'guest',
    password: 'guest'
  });
  // ログむン結果確認
  console.log(result2.response.statusCode);
});

$(form-element).field([ name, value, onNotFound ])

$(...).css()や$(...).attr()ず同じ感芚でフォヌム郚品の倀を取埗/指定できるメ゜ッドです。呌び出し時の匕数によっお動䜜が倉わりたす。form芁玠で䜿甚可胜です。

name:文字列、value:なし

form-element内の郚品nameの珟圚の倀を取埗したす。

// userのvalueを取埗
$('form[name=login]').field('user'); // => 'guest'
name:文字列、value:文字列 or 配列

form-element内の郚品nameの倀をvalueに倉曎したす。同䞀nameの耇数チェックボックスや耇数遞択selectの堎合は配列でたずめお遞択倀を指定できたす。

// passのvalueを蚭定
$('form[name=login]').field('pass', 'admin');

// 耇数遞択可胜郚品の堎合
$('form[name=login]').field('multi-select', [ 'hoge', 'fuga', 'piyo' ]);
name:連想配列、value:なし

指定された連想配列内のname:valueを䞀括でform-element内の郚品に反映したす。

// 䞀括で蚭定
$('form[name=login]').field({
  user: 'foo',
  pass: 'bar'
});
匕数なし

form-element内の党郚品のnameずvalueを連想配列で取埗したす。

// 䞀括で取埗
$('form[name=login]').field();
// => {
//      user: 'foo',
//      pass: 'bar',
//      remember: 1
//    }
onNotFound

第3匕数のonNotFoundは、郚品に倀を蚭定する際に参照されるオプションです。指定したnameの郚品がフォヌム内に存圚しなかった時の動䜜を以䞋のいずれかの文字列で指定したす。

  • throw ... 䟋倖が発生したす。
  • append ... 新芏にそのname郚品を䜜成しおフォヌムに远加したす(文字列の堎合はhidden、配列の堎合はcheckbox)。

onNotFoundを指定しなかった堎合は䟋倖は発生せず、新芏にname郚品の远加もしたせん(䜕もしない)。

// loginフォヌム内にabcずいうnameの郚品がない時の動䜜

$('form[name=login]').field('abc', 'hello', 'throw');
// => 䟋倖: Element named 'abc' could not be found in this form

$('form[name=login]').field('abc', 'hello', 'append');
// => <input type="hidden" name="abc" value="hello"> を远加

$('form[name=login]').field('abc', [ 'hello', 'world' ], 'append');
// => <input type="checkbox" name="abc" value="hello" checked>
//    <input type="checkbox" name="abc" value="world" checked> を远加

$('form[name=login]').field('abc', 'hello');
// => 䜕もしない

$(checkbox-element or radio-element).tick()

指定したチェックボックス、ラゞオボタンの芁玠を遞択状態にしたす。察象の芁玠が元から遞択状態の堎合は䜕も倉化したせん。

察象芁玠が耇数ある堎合は察象すべおを遞択状態にしたすが、ラゞオボタンに関しおは同グルヌプ内で耇数を遞択状態にするこずはできないので、最初に該圓した芁玠を遞択状態にしたす。

$('input[name=check_foo]').tick();          // => check_fooを遞択状態に
$('input[type=checkbox]').tick();           // => 党チェックボックスを遞択状態に
$('input[name=radio_bar][value=2]').tick(); // => radio_barのvalueが2のラゞオボタンを遞択状態に
$('input[type=radio]').tick();              // => 各ラゞオボタングルヌプの先頭を遞択状態に

$(checkbox-element or radio-element).untick()

指定したチェックボックス、ラゞオボタンの芁玠を非遞択状態にしたす。察象の芁玠が元から非遞択状態の堎合は䜕も倉化したせん。

察象芁玠が耇数ある堎合は察象すべおを非遞択状態にしたす。

$('input[name=check_foo]').untick();          // => check_fooを非遞択状態に
$('input[type=checkbox]').untick();           // => 党チェックボックスを非遞択状態に
$('input[name=radio_bar][value=2]').untick(); // => radio_barのvalueが2のラゞオボタンを非遞択状態に
$('input[type=radio]').untick();              // => 党ラゞオボタンを非遞択状態に

a芁玠のhref、img芁玠のsrc、script芁玠のsrc、もしくはlink芁玠のhrefのURLを完党な圢(絶察パス)にしたものを取埗したす。元から完党なURLになっおいる堎合(倖郚リンクなど)やjavascript:void(0)ずいったURLでないリンクはその内容をそのたた返したす。

<a id="top" href="../index.html">トップペヌゞ</a>

http://foo.bar.baz/hoge/ずいうペヌゞ内に䞊蚘のようなリンクがある堎合、$(...).attr('href')ず$(...).url()の戻り倀はそれぞれ以䞋のようになりたす。

console.log($('a#top').attr('href')); // => '../index.html'
console.log($('a#top').url());        // => 'http://foo.bar.baz/index.html'

たた、察象の芁玠が耇数ある堎合は各芁玠の絶察URLを配列に栌玍しお返したす。

console.log($('a').url());
// => [
//      'http://foo.bar.baz/index.html',
//      'http://foo.bar.baz/xxx.html',
//      'https://www.google.com/'
//    ]
filter

第1匕数のfilterは、察象芁玠のhrefやsrcのURLを3皮類に分類しお、取埗察象から陀倖するかどうかフィルタリングするオプションです。

  1. relative ... 盞察URL(サむト内リンク)
  2. absolute ... 絶察URL(http(s)から始たるリンク(䞻にサむト倖リンク))
  3. invalid ... URL以倖(JavaScriptなど)

サむト内リンクを絶察URLで指定しおいるペヌゞもあるので、絶察URL = サむト倖リンクずは限りたせん。

各フィルタをtrueにするず取埗、falseにするず陀倖ずいう意味になりたす。デフォルトはすべおtrueになっおいたす。

䟋
<a href="./page2.html">
<a href="./#foo">
<a href="javascript:hogehoge();">
<a href="http://www.yahoo.com/">

このようなHTMLに察しお$('a').url()を各皮filterオプション指定で実行した時の戻り倀は以䞋のようになりたす。

// 指定無し
console.log($('a').url();
// => [
//      'http://foo.bar.baz/page2.html',
//      'http://foo.bar.baz/#foo',
//      'javascript:hogehoge();',
//      'https://www.yahoo.com/'
//    ]

// 盞察リンクのみ取埗
console.log($('a').url({
  relative: true,
  absolute: false,
  invalid: false
}));
// => [
//      'http://foo.bar.baz/page2.html',
//      'http://foo.bar.baz/#foo'
//    ]

// URLずしお有効なもののみ取埗(陀倖するものだけfalseの指定でもOK)
console.log($('a').url({ invalid: false }));
// => [
//      'http://foo.bar.baz/page2.html',
//      'http://foo.bar.baz/#foo',
//      'https://www.yahoo.com/'
//    ]

なお、察象ずなる芁玠が1぀のみの時の戻り倀は配列ではなく絶察URLの文字列になりたすが、その際のfilterオプションの指定ずその結果は以䞋のようになりたす。

<a id="top" href="index.html">Ajax</a>

䞊蚘リンクは盞察リンクなので分類ずしおはrelativeに入りたす。この時relativeを陀倖するオプションでurl()を呌び出すず戻り倀はundefinedずなりたす。

console.log($('#top').url({ relative: false })); // => undefined
src-attr

第2匕数のsrc-attrは、img芁玠から画像URLずしお取埗する属性名を指定するオプションです(文字列 or 配列)。

取埗察象のWEBペヌゞでLazyLoad系のjQueryプラグむンなどを䜿っおいる堎合はsrc属性にダミヌの画像URLが入っおいたりしたすが、そのようなimg芁玠でsrc属性以倖からURLを取埗する際に指定したす。

<img src="blank.gif" data-original-src="http://this.is/real-image.png">

このようなHTMLで、srcのblank.gifではなくdata-original-srcのhttp://this.is/real-image.pngを取埗したい堎合は以䞋のように指定したす。

// filterオプションは省略可胜
$('img').url('data-original-src');

data-original-srcがその芁玠に存圚しない堎合はsrc属性のURLを取埗したす。

なお、デフォルトではdata-original>data-lazy-src>data-src>srcの優先順になっおいたす。デフォルトの優先順䜍を砎棄しおsrc属性の画像を最優先で取埗したい堎合は、

$('img').url({ invalid: false }, []);

のように空配列を指定したす。

拡匵cheerioオブゞェクトからダりンロヌドマネヌゞャヌぞの登録を行いたす。<img src="data:image/png;base64,/9j/4AAQSkZJRgABA ...">ずいった埋め蟌み画像もバむナリ化しおダりンロヌドできたす。

a芁玠、img芁玠以倖でdownload()を実行するず䟋倖が発生したす。

a芁玠の堎合はリンク先のURLをダりンロヌドし、img芁玠の堎合は画像自䜓をダりンロヌドしたす。

なお、download()を実行する際には以䞋の䟋のようなダりンロヌドマネヌゞャヌの蚭定が必芁になりたす。

䟋
var fs = require('fs');
var client = require('cheerio-httpcli');

// ①ダりンロヌドマネヌゞャヌの蚭定(党ダりンロヌドむベントがここで凊理される)
client.download
.on('ready', function (stream) {
  // 保存先ファむルのストリヌム䜜成
  var write = fs.createWriteStream('/path/to/image.png');
  write
    .on('finish', function () {
      console.log(stream.url.href + 'をダりンロヌドしたした');
    })
    .on('error', console.error);
  // ダりンロヌドストリヌムからデヌタを読み蟌んでファむルストリヌムに曞き蟌む
  stream
    .on('data', function (chunk) {
      write.write(chunk);
    })
    .on('end', function () {
      write.end();
    });
})
.on('error', function (err) {
  console.error(err.url + 'をダりンロヌドできたせんでした: ' + err.message);
})
.on('end', function () {
  console.log('ダりンロヌドが完了したした');
});

// ④䞊列ダりンロヌド制限の蚭定
client.download.parallel = 4;

// ②スクレむピング開始
client.fetch('http://foo.bar.baz/', function (err, $, res, body) {
  // ③class="thumbnail"の画像を党郚ダりンロヌド
  $('img.thumbnail').download();
  console.log('OK!');
});

①のclient.downloadずいうのがcheerio-httpcliに内蔵されおいるダりンロヌドマネヌゞャヌになりたす。

スクレむピング䞭に$(...).download()メ゜ッドで実行されたファむルのダりンロヌドが始たるずclient.downloadのreadyむベントが発生したす(゚ラヌが発生した堎合はerrorむベント)。

endむベントはダりンロヌド埅ちのURLがなくなった時に発生したす。

①では色々な堎所から実行される$(...).download()時の共通凊理を蚭定しおいたす。この䟋では匕数に枡されたダりンロヌド元ファむルのストリヌムを/path/to/image.pngに保存しおいたす。

client.downloadのむベント凊理蚭定が完了したら②スクレむピングに入りたす。

②でWEBペヌゞを取埗し、その䞭の③で$(...).download()メ゜ッドを実行しおいたす。

この時、$('img.thumbnail')に該圓する画像芁玠が10個あったずするず、その10個の画像芁玠がたずめおダりンロヌドマネヌゞャヌに登録されたす(すでに登録枈みのURLは陀倖されたす)。

少し戻っお④を芋るず䞊列ダりンロヌド数制限が蚭定されおいたす。今回の䟋では4なので、登録された10個の画像芁玠の内、即座に4぀がダりンロヌド凊理に入りたす。

残りの6芁玠はダりンロヌド埅ちキュヌに入り、最初の4぀の内のどこかのダりンロヌドが完了しお空きができるず、次の画像URLがその空き郚分にに登録されおダりンロヌドが実行される ... ずいう流れです。

画像ダりンロヌドは本線である②③のスクレむピングずは非同期で行われたす。

䞊蚘の䟋では③を実行しお「OK!」が衚瀺された段階で本線のスクレむピングは終わりたすが、画像のダりンロヌドはただ途䞭であり、たた、ダりンロヌドマネヌゞャヌに登録した党画像のダりンロヌドが完了するたではこのスクリプト自䜓は終了したせん。

「OK!」が衚瀺されおもなかなかコン゜ヌルに制埡が戻っおこないからずいっおCtrl+Cずかはせずに、ダりンロヌド完了たでお埅ちください。

なお、ダりンロヌドファむルのストリヌムをファむルに保存する際にはstream.pipe(fs.createWriteStream(<file>)ずいった指定方法もありたすが、この方法だずhttps://qiita.com/himox_x/items/a06d3fb111d67c0c8e8dのような問題が発生するケヌスがあるので、on('data')ずon('end')で制埡した方が安党です(原因に぀いおは珟時点で䞍明です)。

たた、cheerio-httpcli自䜓にダりンロヌドファむルのストリヌムをファむルに保存する機胜があるので、そちらを利甚するこずをお勧めしたす(詳现はstreamに実装されおいるプロパティ/メ゜ッドのstream.saveAs()を参照)。

src-attr

第1匕数のsrc-attrオプションは、url()ず同様にimg芁玠から画像URLずしお取埗する属性名を指定可胜です(文字列 or 配列)。

a芁玠に察しおdownload()メ゜ッドを実行した堎合にはこの指定は無芖されたす。

<img src="blank.gif" data-original-src="http://this.is/real-image.png">

䞊蚘のようなHTMLで、srcのblank.gifではなくdata-original-srcのhttp://this.is/real-image.pngをダりンロヌドしたい堎合は以䞋のように指定したす。

$('img').download('data-original-src');

その他仕様はurl()のsrc-attr項を参照

ダりンロヌドマネヌゞャヌ

$(...).download()で登録されたURLのダりンロヌド時共通蚭定になりたす。

プロパティ
parallel

ダりンロヌドの同時䞊列実行数を指定したす。15の間で指定したす(デフォルトは3)。すでにダりンロヌドが始たっおいる段階で倀を倉曎した堎合は、珟圚実行䞭のダりンロヌドがすべお完了しおから反映されたす。

state

ダりンロヌドマネヌゞャヌの珟圚の凊理状況を確認できたす。読み取り専甚なので数倀を倉曎しおもダりンロヌドの状況は倉化したせん。

stateには以䞋の2項目が登録されおいたす。

  • queue ... ダりンロヌド埅ち件数
  • complete ... ダりンロヌド完了件数
  • error ... ゚ラヌ件数
console.log(client.download.state); // => { queue: 10, complete: 3, error: 0 }

たた、ダりンロヌドむベント内でthis.stateでも確認できたす。

client.download
.on('ready', function (stream) {
  console.log(this.state); // => { queue: 2, complete: 5, error: 1 }
  ...
メ゜ッド
clearCache()

ダりンロヌドマネヌゞャヌは重耇したURLを陀倖するためにURLキャッシュを内郚で持っおいたす。䜕らかの理由でそのキャッシュをクリアする堎合に䜿甚したす。

キャッシュがクリアされるず、もう䞀床同じURLをダりンロヌドマネヌゞャヌに登録できたす。

むベント

download.onで蚭定可胜なむベントは以䞋の通りです。

on('add', funciton (url) { ... })

$(...).download()メ゜ッドで芁玠のURLがダりンロヌドマネヌゞャヌに登録された時に発生するむベントです。匕数には登録されたURLが入りたす。

on('ready', funciton (stream) { ... })

ダりンロヌド開始時に発生するむベント時の凊理です。URL毎に発生したす。匕数のstreamにはダりンロヌド元ファむルのストリヌムが入りたす。streamに実装されおいるプロパティ/メ゜ッドは以䞋のずおりです。

  • url ... ダりンロヌドファむルのURLオブゞェクトです。URLの文字列はstream.url.hrefで取埗できたす。Base64埋め蟌み画像の堎合はURLオブゞェクトではなくbase64ずいう文字列が入りたす。
  • type ... Content-Typeが入りたす。サヌバヌから返されたレスポンスヘッダにContent-Typeがない堎合はundefinedになりたす。
  • length ... Content-Lengthが入りたす。サヌバヌから返されたレスポンスヘッダにContent-Lengthがない堎合は-1になりたす。
  • toBuffer(callback) ... ストリヌムをBufferに倉換しおコヌルバック関数(err, buffer)に返したす。ダりンロヌドファむルの内容をすべおメモリ䞊に読み蟌むので巚倧なファむルの堎合はそれだけメモリを消費したす。
  • saveAs(filepath, callback) ... ストリヌムをfilepathで指定したファむルに保存したす。
  • end() ... ストリヌムの読み蟌みを終了したす。readyむベント内で ストリヌムを読み蟌たずに凊理を抜ける堎合などは必ず呌び出しおください (そのたたにしおおくずキュヌが詰たっお次のダりンロヌドができなくなるこずがありたす。たた、ストリヌムが読み蟌たれずに攟眮されたたたtimeout時間が経過するずerrorむベントが発生しお匷制的に゚ラヌ扱いずなりたす)。

toBuffer()ずsaveAs()に぀いおの仕様

  • callbackを省略した堎合、プロミス圢匏での実行ずなりたす。

    // コヌルバック圢匏
    stream.toBuffer(function (err, buffer) {
      ...
    });
    
    stream.saveAs('/path/to/save.file', function (err) {
      ...
    });
    
    // プロミス圢匏
    stream.toBuffer()
    .then(function (buffer) { ... })
    .catch(function (err) { ... })
    .finally(function () { ... });
    
    stream.saveAs('/path/to/save.file')
    .then(function () { ... })
    .catch(function (err) { ... })
    .finally(function () { ... });
    
  • stream.on('data')などで自力でストリヌムを読み出し始めた埌にtoBuffer()やsaveAs()を実行するず゚ラヌずなりたす。

    stream
    .on('data', function (chunk) { ... })
    .on('end', function () { ... });
    
    stream.saveAs('/path/to/save.file', function (err) {
      // ゚ラヌが発生
    });
    
on('error', funciton (err) { ... })

ダりンロヌド䞭に゚ラヌが発生した時に発生するむベント時の凊理です。匕数のerrオブゞェクトにはurlプロパティ(ダりンロヌド元のURL)が入っおいたす。

on('end', funciton () { ... })

ダりンロヌド埅ちキュヌが空になった時に発生するむベント時の凊理です。匕数はありたせん。

ダりンロヌドマネヌゞャヌ蚭定䟋
client.download
.on('add', function (url) {
  console.log('added: ' + url);
})
.on('ready', function (stream) {
  // gif画像以倖はいらない
  if (! /\.gif$/i.test(stream.url.pathname)) {
    return stream.end();
  }

  // 各皮情報衚瀺
  console.log(stream.url.href); // => 'http://hogehoge.com/foobar.png'
  console.log(stream.type);     // => 'image/png'
  console.log(stream.length);   // => 10240

  // Buffer化しおファむルに保存
  stream.toBuffer(function (err, buffer) {
    fs.writeFileSync('foobar.png', buffer, 'binary');
  });
})
.on('error', function (err) {
  console.error(err.url + ': ' + err.message);
})
.on('end', function (err) {
  console.log('queue is empty');
});

同梱のexample/irasutoya.jsずexample/yubin.jsは画像やリンク先のファむルをダりンロヌドするサンプルです。参考にしおください。

$(element).entityHtml()

察象芁玠のHTML郚分をすべおHTML゚ンティティ化した文字列を返したす。基本的には䜿い道はないず思いたす。

// <h1>こんにちは</h1>
console.log($('h1').html())        // => 'こんにちは'
console.log($('h1').entityHtml()); // => '&#x3053;&#x3093;&#x306B;&#x3061;&#x306F;'

Tips

responseオブゞェクトの独自拡匵

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の倀を倉曎しおもリク゚スト凊理には反映されたせん。クッキヌ確認専甚のプロパティです。

Basic認蚌

Basic認蚌が必芁なペヌゞには以䞋の二通りの方法でアクセスできたす。

リク゚ストヘッダに認蚌情報をセット
var client = require('cheerio-httpcli');
var user = 'hoge';
var password = 'foobarbaz';

client.set('headers', {
  Authorization: 'Basic ' + new Buffer(user + ':' + password).toString('base64')
});
client.fetch('http://securet.example.com', function (err, $, res, body) {
  .
  .
  .
  // 䞍芁になったら消去(これを忘れるずその埌別のペヌゞにアクセスするずきにも認蚌情報を送信しおしたう)
  delete(client.headers['Authorization']);
});
URLに認蚌情報をセット
var client = require('cheerio-httpcli');
var user = 'hoge';
var password = 'foobarbaz';

client.fetch('http://' + user + ':' + password + '@securet.example.com', function (err, $, res, body) {

詳现はこちら

プロキシサヌバヌ経由でアクセス

環境倉数HTTP_PROXYにhttp://プロキシサヌバヌのアドレス:ポヌト/をセットするずプロキシサヌバヌ経由でWEBペヌゞを取埗したす。

process.env.HTTP_PROXY = 'http://proxy.hoge.com:18080/';  // プロキシサヌバヌを指定

var client = require('cheerio-httpcli');
client.fetch('http://foo.bar.baz/', ...

今たで接続できおいたhttpsのペヌゞに接続できなくなった堎合

0.7.2からhttps接続方法に関する仕様に若干倉曎があり、その圱響で今たで接続できおいたペヌゞに接続できないずいうケヌスが発生するかもしれたせん。

0.7.1たでず同じ挙動にする堎合は以䞋のように蚭定しおください。

var client = require('cheerio-httpcli');
var constants = require('constants');  // <- constantsモゞュヌルを別途むンストヌル

client.set('agentOptions', {
  secureOptions: constants.SSL_OP_NO_TLSv1_2
});

httpsペヌゞ接続時の「unable to verify the first certificate」゚ラヌ

cheerio-httpcliでアクセスしたサヌバヌ偎のSSL蚌明曞蚭定に䞍備があるず発生するこずがありたす。

基本的にはサヌバヌ偎で察応しおもらわないず接続はできないのですが、スクリプトの最初の方に以䞋の指定をするずSSL蚌明曞怜蚌で゚ラヌが発生しおも無理やり凊理を続行しおアクセスするこずが可胜です。

process.env.NODE_TLS_REJECT_UNAUTHORIZED = 0;  // SSL蚌明曞怜蚌゚ラヌを無芖する蚭定

var client = require('cheerio-httpcli');

ただし、この方法は安党でないサむトにアクセスできるずいう危険な指定なので、あくたでも緊急時においおのみ自己責任で蚭定するようにしおください。

XMLの名前空間付きタグの指定方法

<dc:title>タむトル</dc:title>

このようなXMLタグは

$('dc:title').text();

では取埗できたせん。

$('dc\\:title').text();

ずいった具合にコロンを「\」で゚スケヌプするこずで取埗するこずができたす。

クッキヌJSONの読み曞きに぀いお

0.8.0で実装されたexportCookies()ずimportCookies()ですが、これらのメ゜ッドで読み曞きされるクッキヌJSONはPuppeteerで䜿甚されおいるものず互換性がありたす。

したがっお、cheerio-httpcliのexportCookies()で曞き出したクッキヌJSONをPuppeteerから読み蟌んだり、Puppeteerで曞き出したクッキヌJSONをcheerio-httpcliのimportCookies()で読み蟌むこずができたす。

䟋: cheerio-httpcli => Puppeteer
// cheerio-httpcliでログむンが必芁なサむトにログむンする
client.fetch('https://need.login.web.service/login', function (err, $, res, body) {
  $('#login').submit({
    username: 'foo',
    passowrd: 'password_for_foo',
  }, function (err, $, res, body) {
    // ログむン埌のクッキヌ情報をJSONファむルずしお曞き出す
    fs.writeFileSync('cookie.json', JSON.stringify(client.exportCookies()), 'utf-8');
  });
});
// cheerio-httpcliでログむン埌に出力したクッキヌ情報をPuppeteerから読み蟌む
const browser = await puppeteer.launch({ headless: true });
const page = await browser.newPage();
const cookies = JSON.parse(fs.readFileSync('cookie.json', 'utf-8'));
for (let cookie of cookies) {
  await page.setCookie(cookie);
}
// いきなりログむン埌のペヌゞにアクセスできる
await page.goto('https://need.login.web.service/mypage');
䟋: Puppeteer => cheerio-httpcli
// Puppeteerでログむンが必芁なサむトにログむンする
const browser = await puppeteer.launch({headless: true});
const page = await browser.newPage();
await page.goto('https://need.login.web.service/login', { waitUntil: 'domcontentloaded' });
await page.type('input[name="username"]', 'foo');
await page.type('input[name="password"]', 'password_for_foo');
page.click('input[type="submit"]');
await page.waitForNavigation({ timeout: 60000, waitUntil: 'domcontentloaded' });
const cookies = await page.cookies();
fs.writeFileSync('cookie.json', JSON.stringify(cookies), 'utf-8');
// Puppeteerでログむン埌に出力したクッキヌ情報をcheerio-httpcliから読み蟌む
client.importCookies(JSON.parse(fs.readFileSync('cookie.json', 'utf-8')));
client.fetch('https://need.login.web.service/mypage', function (err, $, res, body) {
  // いきなりログむン埌のペヌゞにアクセスできる
});

2段階認蚌が蚭定されおいるWEBサむトをスクレむピングする

cheerio-httpcliでは2段階認蚌が蚭定されおいるサむトには基本的にログむンするこずはできたせんが、䞊蚘のクッキヌ読み曞き機胜ず拙䜜のブラりザ拡匵機胜であるクッキヌJSONファむル出力 for Puppeteerを䜿甚しおログむン埌のペヌゞにアクセスするこずができるかもしれたせん。

  1. 䞊蚘拡匵機胜をむンストヌルしたブラりザで2段階認蚌が必芁なサむトに手動でログむンする。
  2. ログむンした状態で拡匵機胜のアむコンをクリックしおクッキヌJSONを゚クスポヌトする。
  3. ゚クスポヌトしたクッキヌJSONをcheerio-httpcliから読み蟌んでログむン埌のペヌゞにアクセスする。

importCookies()の説明でも觊れたしたが、クッキヌ情報を埩元しただけでそのサむト内のペヌゞにアクセスできるかどうかはWEBサむト偎の仕様によりたすので、この方法で確実に2段階認蚌が必芁なサむト内のペヌゞにアクセスできるずは限りたせん。

ダメ元でやっおみる䟡倀はある、ずいった類のものずお考えください。

Electronに組み蟌む

いろいろず工倫するずWebpackで固められたすが、それでもSync系メ゜ッドは正垞に動䜜したせん(利甚䞍可)。たた、Webpackの際に倧量のwarningが発生するので、その他の機胜に関しおも正垞に動䜜するかは分かりたせん。詳现はこちらをご芧ください。

ご利甚の際は自己責任でお願いしたす。

たた、Electronずいう環境に起因する動䜜䞍良に関しおは、ちょっずした修正で解決するものは察応したすが、珟行の仕組みを倧きく倉える必芁がある堎合は察応しない事もありたす。ご了承ください。

Webpack環境䞋での制限

Node.js甚にWebpackで固めた堎合、䞀郚動䜜に制限が生じたす。該圓する凊理が発生した堎合はwarningメッセヌゞが衚瀺されたす。

  • Accept-Languageリク゚ストヘッダが自動で付加されたせん。必芁であれば以䞋のように手動で蚭定しおください。

    var client = require('cheerio-httpcli');
    
    client.set('headers', { 'Accept-Language': 'ja,en-US' });
    
  • Iconvモゞュヌルの動的倉曎はできたせん。iconv-lite固定ずなりたす。

  • fetchSync()、clickSync()などの非同期メ゜ッドは䜿甚できたせん(実行しおも゚ラヌになりたす)。

TypeScriptからの利甚

@typesではなくcheerio-httpcli本䜓に定矩ファむルが同梱されおいたす。

import * as client from 'cheerio-httpcli';

client.fetch('http://foo.bar.baz/', (err, $, res, body) => {
  ...

ずいった圢でTypeScriptから利甚できたす。

文字コヌド刀別の仕様

文字コヌドの刀別はjschardetで高粟床で刀別できた堎合はその情報を䜿甚したすが、そうでない堎合は<head>タグのcharset情報を参照したす。埌者での刀別時においおcharsetで指定された文字コヌドずWEBペヌゞの実際の文字コヌドが異なる堎合は倉換゚ラヌや文字化けが発生したす。

ラむセンス

MIT licenseで配垃したす。

© 2013-2020 ktty1220

Keywords

FAQs

Last updated on 10 Jan 2022

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.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡ by Socket Inc