<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>さくらたんどっとびーず &#187; jsdom</title>
	<atom:link href="http://sakuratan.biz/archives/tag/jsdom/feed" rel="self" type="application/rss+xml" />
	<link>http://sakuratan.biz</link>
	<description>モロモロ工事中です</description>
	<lastBuildDate>Sun, 25 Jun 2023 12:51:51 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>node.jsとjQueryでスクレイピングするウェブアプリの作り方</title>
		<link>http://sakuratan.biz/archives/3393</link>
		<comments>http://sakuratan.biz/archives/3393#comments</comments>
		<pubDate>Mon, 31 Jan 2011 15:51:06 +0000</pubDate>
		<dc:creator>さくら</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[jsdom]]></category>
		<category><![CDATA[node.js]]></category>

		<guid isPermaLink="false">http://sakuratan.biz/?p=3393</guid>
		<description><![CDATA[やっぱ jQuery 便利ですよ(*´・ω・)(・ω・｀*)ﾈｰ セレクタ使って jQuery でダカダカやってると、DOM とか正規表現でネチネチやるのがバカらしくなっちゃいます。 と日頃から思ってたりしてまして、サーバサイド JavaScript がメインストリームになって、jQuery でウェブアプリをコーディングできれば超ラクできるかもと期待しています。 で、先日サーバサイドJavaScr... <div style="margin-top:1ex"><a href="http://sakuratan.biz/archives/3393">(続きを読む)</a></div>]]></description>
			<content:encoded><![CDATA[<p>やっぱ jQuery 便利ですよ(*´・ω・)(・ω・｀*)ﾈｰ</p>
<p>セレクタ使って jQuery でダカダカやってると、DOM とか正規表現でネチネチやるのがバカらしくなっちゃいます。</p>
<p>と日頃から思ってたりしてまして、サーバサイド JavaScript がメインストリームになって、jQuery でウェブアプリをコーディングできれば超ラクできるかもと期待しています。</p>
<p>で、先日<a href="http://sakuratan.biz/archives/2972">サーバサイドJavaScriptとjQueryでスクレイピング</a>という記事をうpったところ、やっぱ Rhino じゃなくて node.js がえーんよ(´･ω･｀)というコメントを頂きましたので、node.js と jQuery でサーバサイド JavaScript スクレイピングしてみることにしました。</p>
<p>今回は node.js ですので、単にスクレイピングする（コマンドラインから実行する）スクリプトだけじゃなくて、スクレイピングする簡単なウェブアプリを作ってみたいと思います。</p>
<p><a href="http://jquery.com/" target="_blank"><img src="http://sakuratan.biz/blog/wp-content/uploads/2011/01/jquery.png" alt="jQuery" width="215" height="53" class="aligncenter size-full wp-image-3609" /></a> <a href="http://nodejs.org/" target="_blank"><img src="http://sakuratan.biz/blog/wp-content/uploads/2011/01/nodejs.png" alt="node.js" width="215" height="53" class="aligncenter size-full wp-image-3610" /></a></p>
<p>結構長文になっちゃったので、先に今日のブログで扱ってるテーマを書いときます。</p>
<ol>
<li>jsdom パッケージを使って node.js で jQuery する方法</li>
<li>jsdom パッケージの HTML コンテンツ中の script タグの扱いに関する問題の回避方法</li>
<li>文字エンコーディングを考慮した HTML コンテンツのダウンロード方法</li>
<li>スクレイピングウェブアプリの作り方</li>
</ol>
<p>あと完成品のソースを入れた ZIP も先に置いときますので、中身から見たいセッカチさんはこちらからどうぞ。</p>
<blockquote><p>
<a href='http://sakuratan.biz/blog/wp-content/uploads/2011/01/nodejs-linkpicker.zip'>nodejs-linkpicker.zip</a>
</p></blockquote>
<h3>要るもの</h3>
<p>まず node.js が必要です。それと node.js のライブラリをインスコするために npm (Node Package Manager）を使います。一緒にインスコしておいてください。</p>
<p>node.js のインスコ方法については <a href="http://nodejs.org/">node.js の公式サイト</a>を、npm のインスコ方法については配布元 github の <a href="https://github.com/isaacs/npm">isaacs /npm</a> をご覧ください。</p>
<p>英語読むのがメンドくせー方は  <a href="http://sakuratan.biz/archives/3101">node.jsとMySQLで割と普通のデータベースウェブアプリを作ってみるチュートリアル</a>に node.js と npm のインスコ方法を書いてますのでそちらとかどうぞ。</p>
<h4>jsdom</h4>
<p>node.js 本体には DOM ライブラリが付いてませんのでそのままでは jQuery を使えませんが、npm パッケージの <a href="http://jsdom.org/">jsdom</a> という DOM ライブラリをインスコすると jQuery も使えるようになります。</p>
<p>jsdom は npm install でインスコできます。</p>
<div class="codecolorer-container bash dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #666666;">$ </span>npm <span style="color: #c20cb9; font-weight: bold;">install</span> jsdom</div></div>
<p>とりあえず準備はこれで終わりです。</p>
<h3>jQuery を使ってみる</h3>
<p>早速 node.js で jQuery してみます。</p>
<p>HTML コンテンツに div を追加するスクリプトだとこんな感じになります。</p>
<div class="codecolorer-container javascript dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">#<span style="color: #339933;">!/</span>usr<span style="color: #339933;">/</span>bin<span style="color: #339933;">/</span>env node<br />
<span style="color: #006600; font-style: italic;">// exam1.js</span><br />
<br />
<span style="color: #003366; font-weight: bold;">var</span> sys <span style="color: #339933;">=</span> require<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'sys'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; fs <span style="color: #339933;">=</span> require<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'fs'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; jsdom <span style="color: #339933;">=</span> require<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'jsdom'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; domToHtml <span style="color: #339933;">=</span> require<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'jsdom/browser/domtohtml'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #003366; font-weight: bold;">var</span> jquery_js <span style="color: #339933;">=</span> <span style="color: #3366CC;">'https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js'</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #006600; font-style: italic;">// node、スクリプト名、の次に有効なコマンドライン引数が入る</span><br />
<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>process.<span style="color: #660066;">argv</span>.<span style="color: #660066;">length</span> <span style="color: #339933;">&lt;=</span> <span style="color: #CC0000;">2</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; sys.<span style="color: #660066;">puts</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'Usage: node exam1.js [FILE]'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; process.<span style="color: #660066;">exit</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><br />
<br />
<span style="color: #006600; font-style: italic;">// HTMLコンテンツを読み込む</span><br />
<span style="color: #006600; font-style: italic;">// コマンドライン起動前提なので同期I/Oで</span><br />
<span style="color: #003366; font-weight: bold;">var</span> content <span style="color: #339933;">=</span> fs.<span style="color: #660066;">readFileSync</span><span style="color: #009900;">&#40;</span>process.<span style="color: #660066;">argv</span><span style="color: #009900;">&#91;</span><span style="color: #CC0000;">2</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'utf8'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #006600; font-style: italic;">// HTMLコンテンツからwindowオブジェクトを作る</span><br />
<span style="color: #003366; font-weight: bold;">var</span> document <span style="color: #339933;">=</span> jsdom.<span style="color: #660066;">jsdom</span><span style="color: #009900;">&#40;</span>content<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #003366; font-weight: bold;">var</span> window <span style="color: #339933;">=</span> document.<span style="color: #660066;">createWindow</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #006600; font-style: italic;">// jsdom.jQueryifyがwindowにjQueryを追加してくれる</span><br />
jsdom.<span style="color: #660066;">jQueryify</span><span style="color: #009900;">&#40;</span>window<span style="color: #339933;">,</span> jquery_js<span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>window<span style="color: #339933;">,</span> $<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #006600; font-style: italic;">// divを追加する</span><br />
&nbsp; &nbsp; $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'body'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">append</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'&lt;div&gt;More Hello World!!&lt;/div&gt;'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #006600; font-style: italic;">// DOMツリーを出力する</span><br />
&nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>document.<span style="color: #660066;">doctype</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; sys.<span style="color: #660066;">puts</span><span style="color: #009900;">&#40;</span>String<span style="color: #009900;">&#40;</span>document.<span style="color: #660066;">doctype</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; sys.<span style="color: #000066;">print</span><span style="color: #009900;">&#40;</span>domToHtml.<span style="color: #660066;">domToHtml</span><span style="color: #009900;">&#40;</span>document<span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></div>
<p>jQuery 以外の部分が長ったらしいですが、このスクリプトでは大まかに以下の処理を行っています。</p>
<ol>
<li>コマンドライン引数で指定されたファイルを読み込む</li>
<li>jsdom.jsdom() 関数で DOM document オブジェクトを作成</li>
<li>document.createWindow() メソッドを使用し window オブジェクトを作成</li>
<li>window オブジェクトを引数に jsdom.jQueryify 関数を呼び出し jQuery を有効にする</li>
<li>jQuery で処理</li>
</ol>
<p>あと、#!/usr/bin/env node を付けてますので実行パーミッションを与えればそのまま実行可能です。</p>
<p>また、fs.readFileSync() の引数に utf8 を指定してますので、UTF-8 以外のドキュメントだとちゃんと動きません。node.js 本体だけですと ascii／utf-8／base64／binary しか扱えませんので I18N 関係をちゃんと処理しようとすると <a href="https://github.com/bnoordhuis/node-iconv">node-iconv</a> ライブラリなどを使って文字コードを変換する必要があります。後でスクレイピングするスクリプトを書くときにちゃんと対応しますが、とりあえず上のスクリプトは UTF-8 ドキュメントしか処理できません。</p>
<p>他に分からない点があれば <a href="http://nodejs.org/docs/v0.2.6/api.html">node.js のマニュアル</a> をご覧ください。</p>
<p>で、スクリプトを exam1.js に保存します。ついでにテスト用の HTML ファイルを作ります。test1.html として保存してください。</p>
<div class="codecolorer-container html4strict dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="html4strict codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009900;">&lt;!doctype html&gt;</span><br />
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">html</span>&gt;</span><br />
&nbsp; <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">head</span>&gt;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">title</span>&gt;</span>テスト<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">title</span>&gt;</span><br />
&nbsp; <span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">head</span>&gt;</span><br />
&nbsp; <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">body</span>&gt;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">div</span>&gt;</span>Hello, World!<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">div</span>&gt;</span><br />
&nbsp; <span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">body</span>&gt;</span><br />
<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">html</span>&gt;</span></div></div>
<p>実行すると以下のような出力が得られます。（読みにくいので改行とインデントを追加しています。）</p>
<div class="codecolorer-container bash dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ node exam1.js test1.html <br />
<span style="color: #000000; font-weight: bold;">&lt;!</span>doctype html<span style="color: #000000; font-weight: bold;">&gt;</span><br />
<span style="color: #000000; font-weight: bold;">&lt;</span>html<span style="color: #000000; font-weight: bold;">&gt;</span><br />
&nbsp; <span style="color: #000000; font-weight: bold;">&lt;</span><span style="color: #c20cb9; font-weight: bold;">head</span><span style="color: #000000; font-weight: bold;">&gt;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">&lt;</span>title<span style="color: #000000; font-weight: bold;">&gt;</span>テスト<span style="color: #000000; font-weight: bold;">&lt;/</span>title<span style="color: #000000; font-weight: bold;">&gt;</span><br />
&nbsp; <span style="color: #000000; font-weight: bold;">&lt;/</span><span style="color: #c20cb9; font-weight: bold;">head</span><span style="color: #000000; font-weight: bold;">&gt;</span><br />
&nbsp; <span style="color: #000000; font-weight: bold;">&lt;</span>body<span style="color: #000000; font-weight: bold;">&gt;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">&lt;</span>div<span style="color: #000000; font-weight: bold;">&gt;</span>Hello, World<span style="color: #000000; font-weight: bold;">!&lt;/</span>div<span style="color: #000000; font-weight: bold;">&gt;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">&lt;</span>script <span style="color: #007800;">src</span>=<span style="color: #ff0000;">&quot;https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js&quot;</span><span style="color: #000000; font-weight: bold;">&gt;&lt;/</span>script<span style="color: #000000; font-weight: bold;">&gt;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">&lt;</span>div<span style="color: #000000; font-weight: bold;">&gt;</span>More Hello World<span style="color: #000000; font-weight: bold;">!!&lt;/</span>div<span style="color: #000000; font-weight: bold;">&gt;</span><br />
&nbsp; <span style="color: #000000; font-weight: bold;">&lt;/</span>body<span style="color: #000000; font-weight: bold;">&gt;</span><br />
<span style="color: #000000; font-weight: bold;">&lt;/</span>html<span style="color: #000000; font-weight: bold;">&gt;</span></div></div>
<h3>jsdom.jsdom() と jsdom.jQueryify()</h3>
<p>上の例を見ればだいたいお分かり頂けると思いますが node.js で jQuery を使う場合、</p>
<ol>
<li>jsdom.jsdom() で document オブジェクトを作成</li>
<li>document.createWindow() メソッドで window オブジェクトを作成</li>
<li>window オブジェクトに対して jsdom.jQueryify() を呼び出して jQuery オブジェクトを作成</li>
</ol>
<p>という手順が必要になります。</p>
<p>jsdom.jsdom() と jsdom.jQueryify() のパラメータは結構ややこいと思いますので先に説明します。</p>
<h4>jsdom.jsdom() 関数の使い方</h4>
<p>HTML コンテンツを DOM document オブジェクトに変換する関数です。jsdom.jsdom() のプロトタイプは以下のようになります。level 引数と options 引数はオプションです。</p>
<div class="codecolorer-container javascript dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">jsdom.<span style="color: #660066;">jsdom</span><span style="color: #009900;">&#40;</span>body<span style="color: #339933;">,</span> <span style="color: #009900;">&#91;</span>level<span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#91;</span>options<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></div>
<p>body 引数には DOM ツリーを作成する元となる HTML コンテンツ（文字列）を渡します。URL やパスを指定してファイルから直接 document オブジェクトを作成する方法はありません。</p>
<p>level 引数には使用したい DOM レベルに合わせた DOM HTML オブジェクトを渡す必要があります。省略するか、false や null などの偽評価される値を渡すと、DOM Level2 HTML 相当のオブジェクトが使用されます。（実際には DOM Level3 HTML 相当の DOM オブジェクトがデフォルト値なのですが、DOM Level3 は実装中のようで機能的には DOM Level2 になっています。）</p>
<p>level 引数に DOM Level1 を渡す場合は以下のようにコーディングします。ただあまり使い道は無いと思いますので、普段は null を渡しとけば良いと思います。</p>
<div class="codecolorer-container javascript dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #003366; font-weight: bold;">var</span> jsdom <span style="color: #339933;">=</span> require<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'jsdom'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; dom_level1 <span style="color: #339933;">=</span> require<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'jsdom/level1/core'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">dom</span><span style="color: #339933;">;</span><br />
<span style="color: #003366; font-weight: bold;">var</span> document <span style="color: #339933;">=</span> jsdom.<span style="color: #660066;">jsdom</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">''</span><span style="color: #339933;">,</span> dom_level1.<span style="color: #660066;">html</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></div>
<p>options 引数は DOM document を作成する際に使用するオプションを指定するオブジェクトです。</p>
<p>オプションとして有効な値とデフォルト値は以下のとおりです。</p>
<div class="codecolorer-container javascript dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; url<span style="color: #339933;">:</span> undefined<span style="color: #339933;">,</span><br />
&nbsp; &nbsp; features<span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; FetchExternalResources &nbsp;<span style="color: #339933;">:</span> <span style="color: #009900;">&#91;</span><span style="color: #3366CC;">'script'</span><span style="color: #006600; font-style: italic;">/*, 'img', 'css', 'frame', 'link'*/</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; ProcessExternalResources<span style="color: #339933;">:</span> <span style="color: #009900;">&#91;</span><span style="color: #3366CC;">'script'</span><span style="color: #006600; font-style: italic;">/*, 'frame', 'iframe'*/</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; QuerySelector &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">false</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span></div></div>
<p>各オプションの意味は以下のようになっています。</p>
<ul>
<li>url（文字列）<br />
HTML コンテンツの baseURI。<br />
コンテンツに含まれる相対パスの baseURI として使用されます。<br />
省略時は baseURI が存在しないため相対パスはそのまま処理されます。その場合、コンテンツ中の相対パスで指定された外部リソースの取得は失敗します。</li>
<li>features.FetchExternalResources（配列）<br />
外部リソースを取得するタグを列挙します。デフォルトでは script タグで指定されたファイルを取得します。<br />
空文字列または null など偽評価値を渡すと外部リソースをダウンロードしなくなります。</li>
<li>features.ProcessExternalResources（配列）<br />
外部リソースから実行するタグを列挙します。デフォルトでは script タグの JavaScript を実行します。<br />
空文字列または null など偽評価値を渡すと外部リソースを実行しなくなります。</li>
<li>QuerySelector（Boolean）<br />
true の場合、<a href="http://sizzlejs.com/">Sizzle CSS Selector Engine</a> を有効にします。デフォルトは false です。<br />
（jQuery を使う場合は、jQuery 本体に CSS Selector が含まれていますので QuerySelector を有効にする必要はありません。）</li>
</ul>
<p>ちなみに、document オブジェクト自体は不要で window オブジェクトだけが欲しい場合は以下のようにコーディングすることもできます。</p>
<div class="codecolorer-container javascript dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #003366; font-weight: bold;">var</span> window <span style="color: #339933;">=</span> jsdom.<span style="color: #660066;">jsdom</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">''</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">createWindow</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></div>
<h4>jsdom.jQueryify() 関数の使い方</h4>
<p>jsdom.jQueryify() 関数は document.createWindow() メソッドにより作成した window オブジェクトに対し jQueryify（jQuery 化）を行います。</p>
<p>jsdom.jQueryify() のプロトタイプは以下のとおりです。path 引数と callback 引数はオプションです。第三引数を省略した場合、第二引数が文字列なら path 引数として扱われ、第二引数が関数なら callback 引数として扱われます。</p>
<div class="codecolorer-container javascript dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">jsdom.<span style="color: #660066;">jQueryify</span><span style="color: #009900;">&#40;</span>window<span style="color: #339933;">,</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#91;</span>path<span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> callback<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span></div></div>
<p>window 引数には jsdom.jsdom().createWindow() を使って作成した window オブジェクトを渡します。</p>
<p>path 引数には jQuery ソースコードの置かれたパスまたは URL を渡します。この引数を省略すると http://code.jquery.com/jquery-latest.js から jQuery のソースコードを読み込もうとします。（不要かもしれませんが）サーバ負荷を考慮して上の例では <a href="http://code.google.com/intl/ja/apis/libraries/">Google Libraries API</a> の <a href="http://code.google.com/intl/ja/apis/libraries/devguide.html#jquery">jQuery</a> を指定するようにしています。</p>
<p>path 引数にローカルの jQuery ファイルのパスを指定することもできますが、jsdom.jQueryify() は HTML コンテンツに path 引数の script タグを埋め込むことで jQuery の初期化を行っているため、document オブジェクトのオプションで指定した baseURI の値によっては、ローカルの jQuery ファイルを指定すると jQuery の読み込みに失敗することがあります。（baseURI/path を読み込もうとして失敗する。）</p>
<p>なので、この引数には通常 HTTP 経由でアクセスできる URL を指定してください。（file: プロトコルを指定しても意味がないようですので http: プロトコルでアクセス可能な URL が必要です。）</p>
<p>なお、この path 引数の処理の仕方は、jsdom.jsdom() で document を作成する過程と合わせて問題になることがあります。（この問題については以下の <a href="#problem">HTML コンテンツ中の script タグの扱いについて</a> で説明します。）</p>
<p>callback 引数には jQuery の初期化に成功した際に呼ばれるコールバック関数を渡します。コールバック関数のプロトタイプは以下のとおりです。window には jsdom.jQueryify() の第一引数に指定された window オブジェクトが、$ には jQuery オブジェクトが渡されます。</p>
<div class="codecolorer-container javascript dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">callback<span style="color: #009900;">&#40;</span>window<span style="color: #339933;">,</span> $<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></div>
<h3 id="problem">HTML コンテンツ中の script タグの扱いについて</h3>
<p>jsdom.jsdom() 関数は、HTML コンテンツを DOM ツリーに変換する過程で HTML コンテンツに含まれるすべての script タグを実行します。</p>
<p>例えば先ほどの test1.html を以下のように書き換え script タグを追加し、</p>
<div class="codecolorer-container javascript dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;!doctype html&gt;<br />
&lt;html&gt;<br />
&nbsp; &lt;head&gt;<br />
&nbsp; &nbsp; &lt;title&gt;テスト&lt;/title&gt;<br />
&nbsp; &nbsp; <span style="color: #339933;">&lt;</span>script type<span style="color: #339933;">=</span><span style="color: #3366CC;">&quot;text/javascript&quot;</span><span style="color: #339933;">&gt;</span><br />
&nbsp; &nbsp; &nbsp; console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;security vulnerability&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #339933;">&lt;/</span>script<span style="color: #339933;">&gt;</span><br />
&nbsp; &lt;/head&gt;<br />
&nbsp; &lt;body&gt;<br />
&nbsp; &nbsp; &lt;div&gt;Hello, World!&lt;/div&gt;<br />
&nbsp; &lt;/body&gt;<br />
&lt;/html&gt;</div></div>
<p>再度 exam1.js を実行すると以下のような出力が得られます。</p>
<div class="codecolorer-container bash dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ node exam1.js test1.html<br />
security vulnerability<br />
security vulnerability<br />
<span style="color: #000000; font-weight: bold;">&lt;!</span>doctype html<span style="color: #000000; font-weight: bold;">&gt;</span><br />
<span style="color: #000000; font-weight: bold;">&lt;</span>html<span style="color: #000000; font-weight: bold;">&gt;</span><br />
&nbsp; <span style="color: #000000; font-weight: bold;">&lt;</span><span style="color: #c20cb9; font-weight: bold;">head</span><span style="color: #000000; font-weight: bold;">&gt;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">&lt;</span>title<span style="color: #000000; font-weight: bold;">&gt;</span>テスト<span style="color: #000000; font-weight: bold;">&lt;/</span>title<span style="color: #000000; font-weight: bold;">&gt;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">&lt;</span>script <span style="color: #007800;">type</span>=<span style="color: #ff0000;">&quot;text/javascript&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span><br />
&nbsp; &nbsp; &nbsp; console.log<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #ff0000;">&quot;security vulnerability&quot;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>;<br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">&lt;/</span>script<span style="color: #000000; font-weight: bold;">&gt;</span><br />
&nbsp; <span style="color: #000000; font-weight: bold;">&lt;/</span><span style="color: #c20cb9; font-weight: bold;">head</span><span style="color: #000000; font-weight: bold;">&gt;</span><br />
&nbsp; <span style="color: #000000; font-weight: bold;">&lt;</span>body<span style="color: #000000; font-weight: bold;">&gt;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">&lt;</span>div<span style="color: #000000; font-weight: bold;">&gt;</span>Hello, World<span style="color: #000000; font-weight: bold;">!&lt;/</span>div<span style="color: #000000; font-weight: bold;">&gt;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">&lt;</span>script <span style="color: #007800;">src</span>=<span style="color: #ff0000;">&quot;https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js&quot;</span><span style="color: #000000; font-weight: bold;">&gt;&lt;/</span>script<span style="color: #000000; font-weight: bold;">&gt;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">&lt;</span>div<span style="color: #000000; font-weight: bold;">&gt;</span>More Hello World<span style="color: #000000; font-weight: bold;">!!&lt;/</span>div<span style="color: #000000; font-weight: bold;">&gt;</span><br />
&nbsp; <span style="color: #000000; font-weight: bold;">&lt;/</span>body<span style="color: #000000; font-weight: bold;">&gt;</span><br />
<span style="color: #000000; font-weight: bold;">&lt;/</span>html<span style="color: #000000; font-weight: bold;">&gt;</span></div></div>
<p>jsdom.jsdom() が HTML コンテンツ中の JavaScript を実行しちゃってます。（security vulnerability メッセージがなんで二回出力されるのかは重要ではないので調べていません。）</p>
<p>jsdom のソースを見ますと、script タグに含まれる JavaScript は node.js の Script.runInContext() メソッドにより実行されています。</p>
<p>単純に eval せず runInContext() でラップしているため script タグから require 等は使用できません。そのため script タグ中の JavaScript から実行できることは限られていますが、ログを埋め尽くしたり無限ループを作ったりぐらいはできます。また document.write の動作がブラウザ上での動作とちょっと違ったりします（document.write の出力先が常に document 先頭になってるようです）ので、そのままサーバサイドスクリプトに組み込むのはちょっと厳しい感じです。</p>
<p>また script タグに src 属性が指定されている場合、src で指定されたファイルをダウンロードして実行します。そのためネットワークアクセスが必要なコンテンツの場合は処理に時間がかかるという問題もあります。</p>
<p>いずれにしてもこのままではスクレイピング用途には使いにくいので、HTML 中の script タグの処理を無効にする必要があります。ただ jsdom.jQueryify() の jQuery の実行方法に問題があり単純に無効にすることはできません。</p>
<p>以下に jQuery の実行方法のどの辺が問題か説明します。</p>
<h4>1. jsdom.jsdom() で script タグの無効にする</h4>
<p>まず HTML 中の script タグの処理を無効にすること自体は、jsdom.jsdom() のオプション引数で features.FetchExternalResources と features.ProcessExternalResources を false にすることで実現できます。</p>
<p>具体的には以下のように jsdom.jsdom() を呼び出します。</p>
<div class="codecolorer-container javascript dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #003366; font-weight: bold;">var</span> document <span style="color: #339933;">=</span> jsdom.<span style="color: #660066;">jsdom</span><span style="color: #009900;">&#40;</span>content<span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; features<span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; FetchExternalResources<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; ProcessExternalResources<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">false</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></div>
<p>ここまでは特に問題ありません。</p>
<h4>2. jsdom.jQueryify() の jQuery 埋め込み方法</h4>
<p>jsdom.jQueryify() では jQuery を実行するのに、HTML コンテンツの末尾に jsdom.jQueryify() の第二引数を src 属性に指定した script 要素を appendChild() メソッドを使って HTML body に追加する方法で行っています。</p>
<p>HTML コンテンツ中の JavaScript は jsdom ライブラリにより実行されますので、appendChild() されるタイミングで埋め込まれた jQuery スクリプトが実行されるという仕組みです。</p>
<p>先ほどのスクリプトの実行結果を見ると src=&#8221;https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js&#8221; を持つ script タグが埋め込まれていますが、これは上記の仕組みにより jsdom.jQueryify()  が追加したものです。</p>
<div class="codecolorer-container html4strict dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="html4strict codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">div</span>&gt;</span>Hello, World!<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">div</span>&gt;</span><br />
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">script</span> <span style="color: #000066;">src</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js&quot;</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">script</span>&gt;</span><br />
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">div</span>&gt;</span>More Hello World!!<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">div</span>&gt;</span></div></div>
<p>この動作自体も特に問題という訳ではありません。</p>
<h4>3. 1 と 2 を合わせると動かなくなる</h4>
<p>script タグの処理を無効にするには、jsdom.jsdom() を呼び出す際に options.features.FetchExternalResources と options.features.ProcessExternalResources を false にすれば良いです。これらのオプションを指定すると document に含まれる script タグがまったく実行されなくなります。</p>
<p>jsdom.jQueryify() は jQuery を埋め込むのに、DOM ツリーに script タグを埋め込みますが、jsdom.jsdom() で script の実行を無効にするとこの処理も無効になります。</p>
<p>これらを合わせると、jsdom.jsdom() のオプションを指定して script タグの処理を無効にすると、jsdom.jQueryify() も使用できなくなります。問題です。</p>
<h3>jsdom.jQueryify() を使用せずに jQuery を実行する</h3>
<p>とりあえずscript タグの処理を無効にして jsdom.jsdom() と jsdom.jQueryify() を使用できないということになりましたので、jQueryify と似たような処理を自前で実装することにしました。</p>
<p>以下の embedJQuery() 関数がその辺のややこいところを全部処理します。</p>
<div class="codecolorer-container javascript dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #006600; font-style: italic;">// embedJQuery.js</span><br />
<span style="color: #006600; font-style: italic;">// jsdomとjQueryのラッパー</span><br />
<br />
<span style="color: #003366; font-weight: bold;">var</span> fs <span style="color: #339933;">=</span> require<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'fs'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; Script <span style="color: #339933;">=</span> process.<span style="color: #660066;">binding</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'evals'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">Script</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; jsdom <span style="color: #339933;">=</span> require<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'jsdom'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; httpsubr <span style="color: #339933;">=</span> require<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'./httpsubr'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #006600; font-style: italic;">// jQuery を読み込む</span><br />
<span style="color: #003366; font-weight: bold;">var</span> jQueryPath <span style="color: #339933;">=</span> __dirname <span style="color: #339933;">+</span> <span style="color: #3366CC;">'/jquery.min.js'</span><span style="color: #339933;">;</span><br />
<span style="color: #003366; font-weight: bold;">var</span> jQueryScript <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Script<span style="color: #009900;">&#40;</span>fs.<span style="color: #660066;">readFileSync</span><span style="color: #009900;">&#40;</span>jQueryPath<span style="color: #339933;">,</span> <span style="color: #3366CC;">'utf-8'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; jQueryPath<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #006600; font-style: italic;">// HTMLコンテンツにjQueryを埋め込み、</span><br />
<span style="color: #006600; font-style: italic;">// windowオブジェクトとjQueryオブジェクトを返す</span><br />
exports.<span style="color: #660066;">embedJQuery</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>body<span style="color: #339933;">,</span> options<span style="color: #339933;">,</span> callback<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #006600; font-style: italic;">// HTMLファイル中のscriptタグの処理を無効にしてwindowを作成</span><br />
&nbsp; &nbsp; options <span style="color: #339933;">=</span> options <span style="color: #339933;">||</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; options.<span style="color: #660066;">features</span> <span style="color: #339933;">=</span> options.<span style="color: #660066;">features</span> <span style="color: #339933;">||</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; options.<span style="color: #660066;">features</span>.<span style="color: #660066;">FetchExternalResources</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; options.<span style="color: #660066;">features</span>.<span style="color: #660066;">ProcessExternalResources</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> window <span style="color: #339933;">=</span> jsdom.<span style="color: #660066;">jsdom</span><span style="color: #009900;">&#40;</span>body<span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">,</span> options<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">createWindow</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #006600; font-style: italic;">// jQueryを実行</span><br />
&nbsp; &nbsp; jQueryScript.<span style="color: #660066;">runInNewContext</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; window<span style="color: #339933;">:</span> window<span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; navigator<span style="color: #339933;">:</span> window.<span style="color: #660066;">navigator</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; location<span style="color: #339933;">:</span> window.<span style="color: #660066;">location</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; setTimeout<span style="color: #339933;">:</span> setTimeout<span style="color: #339933;">,</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #006600; font-style: italic;">// callbackを呼び出す</span><br />
&nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>callback<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; callback<span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">,</span> window<span style="color: #339933;">,</span> window.<span style="color: #660066;">jQuery</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span><br />
<br />
<span style="color: #006600; font-style: italic;">// URLからリソースを読み込みjQueryを追加する</span><br />
exports.<span style="color: #660066;">jQueryRequest</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>targetUrl<span style="color: #339933;">,</span> callback<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; httpsubr.<span style="color: #660066;">get</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span> uri<span style="color: #339933;">:</span> targetUrl <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>err<span style="color: #339933;">,</span> response<span style="color: #339933;">,</span> raw<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>err<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>response.<span style="color: #660066;">statusCode</span> <span style="color: #339933;">!=</span> <span style="color: #CC0000;">200</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; err <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Error<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;HTTP Error&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>err<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>callback<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; callback<span style="color: #009900;">&#40;</span>err<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span> <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">throw</span> err<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">return</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> body <span style="color: #339933;">=</span> httpsubr.<span style="color: #660066;">convertCharset</span><span style="color: #009900;">&#40;</span>response<span style="color: #339933;">,</span> raw<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #006600; font-style: italic;">// コンテンツのbaseURIをtargetUrlにするためurlオプションを指定</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; exports.<span style="color: #660066;">embedJQuery</span><span style="color: #009900;">&#40;</span>body<span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span> url<span style="color: #339933;">:</span> targetUrl <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> callback<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span></div></div>
<p>embedJQuery.js ではローカルの jQuery を読み込むようにしています。jQuery 1.4.2 〜 1.4.4 とともに動くようにコーディングしていますので、予め <a href="https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js">https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js</a> などからファイルをダウンロードして embedJQuery.js と同じディレクトリに置いてください。ファイル名が jquery.min.js 以外のときは、jQueryPath 変数の値を書き換えてください。</p>
<p>先ほどの exam1.js を embedJQuery() 関数を使用するように書き換えると以下のようになります。</p>
<div class="codecolorer-container javascript dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">#<span style="color: #339933;">!/</span>usr<span style="color: #339933;">/</span>bin<span style="color: #339933;">/</span>env node<br />
<span style="color: #006600; font-style: italic;">// exam2.js</span><br />
<br />
<span style="color: #003366; font-weight: bold;">var</span> sys <span style="color: #339933;">=</span> require<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'sys'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; fs <span style="color: #339933;">=</span> require<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'fs'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; domToHtml <span style="color: #339933;">=</span> require<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'jsdom/browser/domtohtml'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; embedJQuery <span style="color: #339933;">=</span> require<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'./embedJQuery'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">embedJQuery</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #003366; font-weight: bold;">var</span> jquery_js <span style="color: #339933;">=</span> <span style="color: #3366CC;">'https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js'</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>process.<span style="color: #660066;">argv</span>.<span style="color: #660066;">length</span> <span style="color: #339933;">&lt;=</span> <span style="color: #CC0000;">2</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; sys.<span style="color: #660066;">puts</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'Usage: node exam2.js [FILE]'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; process.<span style="color: #660066;">exit</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><br />
<br />
<span style="color: #003366; font-weight: bold;">var</span> content <span style="color: #339933;">=</span> fs.<span style="color: #660066;">readFileSync</span><span style="color: #009900;">&#40;</span>process.<span style="color: #660066;">argv</span><span style="color: #009900;">&#91;</span><span style="color: #CC0000;">2</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'utf8'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #006600; font-style: italic;">// jsdom.jQueryifyがwindowにjQueryを追加してくれる</span><br />
embedJQuery<span style="color: #009900;">&#40;</span>content<span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>err<span style="color: #339933;">,</span> window<span style="color: #339933;">,</span> $<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>err<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">throw</span> err<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<br />
&nbsp; &nbsp; $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'body'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">append</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'&lt;div&gt;More Hello World!!&lt;/div&gt;'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> document <span style="color: #339933;">=</span> window.<span style="color: #660066;">document</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>document.<span style="color: #660066;">doctype</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; sys.<span style="color: #660066;">puts</span><span style="color: #009900;">&#40;</span>String<span style="color: #009900;">&#40;</span>document.<span style="color: #660066;">doctype</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; sys.<span style="color: #000066;">print</span><span style="color: #009900;">&#40;</span>domToHtml.<span style="color: #660066;">domToHtml</span><span style="color: #009900;">&#40;</span>document<span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></div>
<p>テスト用に無限ループを組み込んだ HTML を用意し、</p>
<div class="codecolorer-container html4strict dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="html4strict codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009900;">&lt;!doctype html&gt;</span><br />
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">html</span>&gt;</span><br />
&nbsp; <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">head</span>&gt;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">title</span>&gt;</span>テスト<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">title</span>&gt;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">script</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text/javascript&quot;</span>&gt;</span><br />
&nbsp; &nbsp; &nbsp; console.log(&quot;security vulnerability&quot;);<br />
&nbsp; &nbsp; &nbsp; for (;;) ;<br />
&nbsp; &nbsp; <span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">script</span>&gt;</span><br />
&nbsp; <span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">head</span>&gt;</span><br />
&nbsp; <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">body</span>&gt;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">div</span>&gt;</span>Hello, World!<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">div</span>&gt;</span><br />
&nbsp; <span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">body</span>&gt;</span><br />
<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">html</span>&gt;</span></div></div>
<p>exam2.js を実行すると以下のようになります。</p>
<div class="codecolorer-container bash dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ node exam2.js test2.html <br />
<span style="color: #000000; font-weight: bold;">&lt;!</span>doctype html<span style="color: #000000; font-weight: bold;">&gt;</span><br />
<span style="color: #000000; font-weight: bold;">&lt;</span>html<span style="color: #000000; font-weight: bold;">&gt;</span><br />
&nbsp; <span style="color: #000000; font-weight: bold;">&lt;</span><span style="color: #c20cb9; font-weight: bold;">head</span><span style="color: #000000; font-weight: bold;">&gt;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">&lt;</span>title<span style="color: #000000; font-weight: bold;">&gt;</span>テスト<span style="color: #000000; font-weight: bold;">&lt;/</span>title<span style="color: #000000; font-weight: bold;">&gt;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">&lt;</span>script <span style="color: #007800;">type</span>=<span style="color: #ff0000;">&quot;text/javascript&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span><br />
&nbsp; &nbsp; &nbsp; console.log<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #ff0000;">&quot;security vulnerability&quot;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000; font-weight: bold;">;;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> ;<br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">&lt;/</span>script<span style="color: #000000; font-weight: bold;">&gt;</span><br />
&nbsp; <span style="color: #000000; font-weight: bold;">&lt;/</span><span style="color: #c20cb9; font-weight: bold;">head</span><span style="color: #000000; font-weight: bold;">&gt;</span><br />
&nbsp; <span style="color: #000000; font-weight: bold;">&lt;</span>body<span style="color: #000000; font-weight: bold;">&gt;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">&lt;</span>div<span style="color: #000000; font-weight: bold;">&gt;</span>Hello, World<span style="color: #000000; font-weight: bold;">!&lt;/</span>div<span style="color: #000000; font-weight: bold;">&gt;</span><br />
&nbsp; <span style="color: #000000; font-weight: bold;">&lt;</span>div<span style="color: #000000; font-weight: bold;">&gt;</span>More Hello World<span style="color: #000000; font-weight: bold;">!!&lt;/</span>div<span style="color: #000000; font-weight: bold;">&gt;&lt;/</span>body<span style="color: #000000; font-weight: bold;">&gt;</span><br />
<span style="color: #000000; font-weight: bold;">&lt;/</span>html<span style="color: #000000; font-weight: bold;">&gt;</span></div></div>
<p>同じ HTML コンテンツを exam1.js で処理すると、for (;;) ; の部分で無限ループになり帰ってきませんが、exam2.js では embedJQuery が script タグを処理しないようにしてるので処理は終了します。また jQuery を使って埋め込んだ div タグもちゃんと表示されています。</p>
<h3>複数の文字エンコーディングに対応させる</h3>
<p>日本語の HTML コンテンツの場合 Shift_JIS / EUC-JP / UTF-8 等の文字エンコーディングを使用しますが、node.js 本体には UTF-8 以外の文字エンコーディングを処理する機能は付いてません。</p>
<p>日本語のコンテンツを処理するためには、<a href="https://github.com/bnoordhuis/node-iconv">node-iconv</a> パッケージ等を使用してダウンロードしたコンテンツを node.js で処理可能な文字コードに変換する必要があります。</p>
<p>node-iconv パッケージは npm からインスコできませんので、github からソースをダウンロードしてビルドする必要があります。</p>
<p>node-iconv の github には、node.js バージョン 0.3 系列向けのブランチとバージョン 0.2 系列向けのブランチが用意されています。</p>
<p>ブランチを指定せず git clone すると 0.3 系列向けのソースがダウンロードされます。</p>
<div class="codecolorer-container bash dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #666666;">$ </span><span style="color: #c20cb9; font-weight: bold;">git clone</span> git:<span style="color: #000000; font-weight: bold;">//</span>github.com<span style="color: #000000; font-weight: bold;">/</span>bnoordhuis<span style="color: #000000; font-weight: bold;">/</span>node-iconv.git</div></div>
<p>0.2 系列向けのソースが必要な場合は、-b オプションを付けて v0.2.x ブランチをダウンロードしてください。（v0.2.6 等、node.js の個別のバージョン向けのブランチが用意されているわけではありません。v0.2.x ブランチをダウンロードしてください。）</p>
<div class="codecolorer-container bash dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #666666;">$ </span><span style="color: #c20cb9; font-weight: bold;">git clone</span> <span style="color: #660033;">-b</span> v0.2.x git:<span style="color: #000000; font-weight: bold;">//</span>github.com<span style="color: #000000; font-weight: bold;">/</span>bnoordhuis<span style="color: #000000; font-weight: bold;">/</span>node-iconv.git</div></div>
<p>ビルドは make のみです。NODE_PATH 引数には node.js をインストールしたプレフィクスを指定してください。デフォルトは /usr/local です。</p>
<div class="codecolorer-container bash dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ <span style="color: #c20cb9; font-weight: bold;">make</span><br />
$ <span style="color: #c20cb9; font-weight: bold;">make</span> <span style="color: #c20cb9; font-weight: bold;">install</span> <span style="color: #007800;">NODE_PATH</span>=<span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span><span style="color: #7a0874; font-weight: bold;">local</span></div></div>
<p>node-iconv がインスコできたら、文字コードを考慮した HTTP クライアントモジュールを作ります。</p>
<p>node.js でオクテットを扱う場合は、通常 Buffer オブジェクトを使用します。Buffer オブジェクトを String（文字列）オブジェクトに変換するには、buffer.toString(encoding) メソッドを使用します。</p>
<p>今から作るモジュールは <a href="https://github.com/mikeal/node-utils">request</a> パッケージを参考にしていまして、request パッケージの関数が HTTP レスポンスを Buffer オブジェクトじゃなくて文字列で返してくるため、node-iconv にそのままレスポンスを渡すと文字化けするようなのでその辺を直した感じのものになっています。</p>
<p>ちなみに node-iconv は、libiconv が文字コード変換に失敗し EILSEQ エラーが発生した場合、常に例外を発生します。一般的な LL 言語の文字コード変換ライブラリでは、文字コード変換に失敗したら適当な代替え文字で差し替える処理が実装されていると思いますが、node-iconv ではそういった処理はできませんので注意してください。ただ今回は node.js と jQuery がメインですので、この辺にはこれ以上触れずに進めます。</p>
<p>ということで書いたコードは↓です。HTTP レスポンスと Buffer オブジェクトから文字コードを検出して文字列に変換する関数と、HTTP リクエストのラッパー関数を実装しています。</p>
<p>HTTP リクエスト関数では、生の Buffer オブジェクトではなく文字コード変換した文字列をコールバック関数に返すようにもできますが、エラー処理が分かりにくくなりそうなので raw buffer を返すことにしてます。</p>
<div class="codecolorer-container javascript dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #006600; font-style: italic;">// httpsubr.js</span><br />
<span style="color: #006600; font-style: italic;">// HTTP関連のサブルーチン</span><br />
<br />
<span style="color: #003366; font-weight: bold;">var</span> http <span style="color: #339933;">=</span> require<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'http'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; iconv <span style="color: #339933;">=</span> require<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'iconv'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; url <span style="color: #339933;">=</span> require<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'url'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #006600; font-style: italic;">// Bufferを連結する</span><br />
<span style="color: #003366; font-weight: bold;">function</span> concatBuffer<span style="color: #009900;">&#40;</span>src1 <span style="color: #006600; font-style: italic;">/* , src2, ... */</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> i<span style="color: #339933;">,</span> buf<span style="color: #339933;">,</span> start<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> len <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span>i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> arguments.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> <span style="color: #339933;">++</span>i<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; len <span style="color: #339933;">+=</span> arguments<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span>.<span style="color: #660066;">length</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<br />
&nbsp; &nbsp; buf <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Buffer<span style="color: #009900;">&#40;</span>len<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; start <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span>i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> arguments.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> <span style="color: #339933;">++</span>i<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> chunk <span style="color: #339933;">=</span> arguments<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; chunk.<span style="color: #660066;">copy</span><span style="color: #009900;">&#40;</span>buf<span style="color: #339933;">,</span> start<span style="color: #339933;">,</span> <span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; start <span style="color: #339933;">+=</span> chunk.<span style="color: #660066;">length</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">return</span> buf<span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><br />
<br />
<span style="color: #006600; font-style: italic;">// HTTPレスポンスとBufferからエンコーディングを検出し</span><br />
<span style="color: #006600; font-style: italic;">// レスポンスボディを文字列で返す</span><br />
exports.<span style="color: #660066;">convertCharset</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>response<span style="color: #339933;">,</span> buf<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> charset <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> content_type <span style="color: #339933;">=</span> response.<span style="color: #660066;">headers</span><span style="color: #009900;">&#91;</span><span style="color: #3366CC;">'content-type'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>content_type<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; re <span style="color: #339933;">=</span> content_type.<span style="color: #660066;">match</span><span style="color: #009900;">&#40;</span><span style="color: #009966; font-style: italic;">/\bcharset=([\w\-]+)\b/i</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>re<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; charset <span style="color: #339933;">=</span> re<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>charset<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> bin <span style="color: #339933;">=</span> buf.<span style="color: #660066;">toString</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'binary'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; re <span style="color: #339933;">=</span> bin.<span style="color: #660066;">match</span><span style="color: #009900;">&#40;</span><span style="color: #009966; font-style: italic;">/&lt;meta\b[^&gt;]*charset=([\w\-]+)/i</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>re<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; charset <span style="color: #339933;">=</span> re<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span> <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; charset <span style="color: #339933;">=</span> <span style="color: #3366CC;">'utf-8'</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">switch</span> <span style="color: #009900;">&#40;</span>charset<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #3366CC;">'ascii'</span><span style="color: #339933;">:</span><br />
&nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #3366CC;">'utf-8'</span><span style="color: #339933;">:</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">return</span> buf.<span style="color: #660066;">toString</span><span style="color: #009900;">&#40;</span>charset<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">default</span><span style="color: #339933;">:</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> ic <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> <span style="color: #009900;">&#40;</span>iconv.<span style="color: #660066;">Iconv</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span>charset<span style="color: #339933;">,</span> <span style="color: #3366CC;">'utf-8'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> buf2 <span style="color: #339933;">=</span> ic.<span style="color: #660066;">convert</span><span style="color: #009900;">&#40;</span>buf<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">return</span> buf2.<span style="color: #660066;">toString</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'utf8'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span><br />
<br />
<span style="color: #006600; font-style: italic;">// 文字列ではなくBufferを返す版の</span><br />
<span style="color: #006600; font-style: italic;">// requestパッケージ (https://github.com/mikeal/node-utils) のrequest関数</span><br />
<span style="color: #006600; font-style: italic;">// とほぼ同等な関数</span><br />
<span style="color: #006600; font-style: italic;">// request関数にある一部機能は実装していない</span><br />
exports.<span style="color: #660066;">httpRequest</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>options<span style="color: #339933;">,</span> callback<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; options <span style="color: #339933;">=</span> options <span style="color: #339933;">||</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">typeof</span><span style="color: #009900;">&#40;</span>options.<span style="color: #660066;">uri</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> <span style="color: #3366CC;">'string'</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; options.<span style="color: #660066;">uri</span> <span style="color: #339933;">=</span> url.<span style="color: #660066;">parse</span><span style="color: #009900;">&#40;</span>options.<span style="color: #660066;">uri</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; options.<span style="color: #660066;">method</span> <span style="color: #339933;">=</span> options.<span style="color: #660066;">method</span> <span style="color: #339933;">||</span> <span style="color: #3366CC;">'GET'</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; options.<span style="color: #660066;">headers</span> <span style="color: #339933;">=</span> options.<span style="color: #660066;">headers</span> <span style="color: #339933;">||</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; options._nRedirect <span style="color: #339933;">=</span> options._nRedirect <span style="color: #339933;">||</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">typeof</span><span style="color: #009900;">&#40;</span>options.<span style="color: #660066;">maxRedirects</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> <span style="color: #3366CC;">'undefined'</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; options.<span style="color: #660066;">maxRedirects</span> <span style="color: #339933;">=</span> <span style="color: #CC0000;">10</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>options.<span style="color: #660066;">headers</span>.<span style="color: #660066;">host</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; options.<span style="color: #660066;">headers</span>.<span style="color: #660066;">host</span> <span style="color: #339933;">=</span> options.<span style="color: #660066;">uri</span>.<span style="color: #660066;">hostname</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>options.<span style="color: #660066;">uri</span>.<span style="color: #660066;">port</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; options.<span style="color: #660066;">headers</span>.<span style="color: #660066;">host</span> <span style="color: #339933;">+=</span> <span style="color: #3366CC;">':'</span> <span style="color: #339933;">+</span> options.<span style="color: #660066;">uri</span>.<span style="color: #660066;">port</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> port <span style="color: #339933;">=</span> <span style="color: #CC0000;">80</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> https <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>options.<span style="color: #660066;">uri</span>.<span style="color: #660066;">protocol</span> <span style="color: #339933;">==</span> <span style="color: #3366CC;">'https:'</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; port <span style="color: #339933;">=</span> <span style="color: #CC0000;">443</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; https <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>options.<span style="color: #660066;">uri</span>.<span style="color: #660066;">port</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; port <span style="color: #339933;">=</span> port<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> path <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>options.<span style="color: #660066;">uri</span>.<span style="color: #660066;">pathname</span> <span style="color: #339933;">?</span> options.<span style="color: #660066;">uri</span>.<span style="color: #660066;">pathname</span> <span style="color: #339933;">:</span> <span style="color: #3366CC;">'/'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>options.<span style="color: #660066;">uri</span>.<span style="color: #660066;">search</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; path <span style="color: #339933;">+=</span> options.<span style="color: #660066;">uri</span>.<span style="color: #660066;">search</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>options.<span style="color: #660066;">uri</span>.<span style="color: #660066;">hash</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; path <span style="color: #339933;">+=</span> options.<span style="color: #660066;">uri</span>.<span style="color: #660066;">hash</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> client <span style="color: #339933;">=</span> http.<span style="color: #660066;">createClient</span><span style="color: #009900;">&#40;</span>port<span style="color: #339933;">,</span> options.<span style="color: #660066;">uri</span>.<span style="color: #660066;">hostname</span><span style="color: #339933;">,</span> https<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; client.<span style="color: #660066;">addListener</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'error'</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>err<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>callback<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; callback<span style="color: #009900;">&#40;</span>err<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span> <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">throw</span> err<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> request <span style="color: #339933;">=</span> client.<span style="color: #660066;">request</span><span style="color: #009900;">&#40;</span>options.<span style="color: #660066;">method</span><span style="color: #339933;">,</span> path<span style="color: #339933;">,</span> options.<span style="color: #660066;">headers</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; request.<span style="color: #660066;">addListener</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'response'</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>response<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>response.<span style="color: #660066;">headers</span>.<span style="color: #660066;">location</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>options._nRedirect<span style="color: #339933;">++</span> <span style="color: #339933;">&gt;=</span> options.<span style="color: #660066;">maxRedirect</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; client.<span style="color: #660066;">emit</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'error'</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">new</span> Error<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'Too many redirects'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> loc <span style="color: #339933;">=</span> response.<span style="color: #660066;">headers</span>.<span style="color: #660066;">location</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>loc.<span style="color: #660066;">match</span><span style="color: #009900;">&#40;</span><span style="color: #009966; font-style: italic;">/^https?:/i</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; loc <span style="color: #339933;">=</span> url.<span style="color: #660066;">resolve</span><span style="color: #009900;">&#40;</span>options.<span style="color: #660066;">uri</span>.<span style="color: #660066;">href</span><span style="color: #339933;">,</span> response.<span style="color: #660066;">headers</span>.<span style="color: #660066;">location</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; options.<span style="color: #660066;">uri</span> <span style="color: #339933;">=</span> loc<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; exports.<span style="color: #660066;">httpRequest</span><span style="color: #009900;">&#40;</span>options<span style="color: #339933;">,</span> callback<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span> <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> chunks <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; response.<span style="color: #660066;">on</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'data'</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>chunk<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; chunks.<span style="color: #660066;">push</span><span style="color: #009900;">&#40;</span>chunk<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .<span style="color: #660066;">on</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'end'</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>callback<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> buf <span style="color: #339933;">=</span> concatBuffer.<span style="color: #660066;">apply</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> chunks<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">delete</span><span style="color: #009900;">&#40;</span>chunks<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; callback<span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">,</span> response<span style="color: #339933;">,</span> buf<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>options.<span style="color: #660066;">requestBody</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">typeof</span><span style="color: #009900;">&#40;</span>options.<span style="color: #660066;">requestBody</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> <span style="color: #3366CC;">'string'</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; request.<span style="color: #000066; font-weight: bold;">write</span><span style="color: #009900;">&#40;</span>options.<span style="color: #660066;">requestBody</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; request.<span style="color: #660066;">end</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span> <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sys.<span style="color: #660066;">pump</span><span style="color: #009900;">&#40;</span>options.<span style="color: #660066;">requestBody</span><span style="color: #339933;">,</span> request<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span> <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; request.<span style="color: #660066;">end</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span><br />
<br />
exports.<span style="color: #660066;">get</span> <span style="color: #339933;">=</span> exports.<span style="color: #660066;">httpRequest</span><span style="color: #339933;">;</span><br />
<br />
exports.<span style="color: #660066;">post</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>options<span style="color: #339933;">,</span> callback<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>options.<span style="color: #660066;">requestBody</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; options.<span style="color: #660066;">requestBody</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">''</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; exports.<span style="color: #660066;">request</span><span style="color: #009900;">&#40;</span>options<span style="color: #339933;">,</span> callback<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span></div></div>
<h3>マジでスクレイピングする</h3>
<p>jQuery を使ってスクレイピングする準備が整いましたので、ネットワークから HTML を読み込んでスクレイピングするスクリプトを作ります。</p>
<h4>スクレイピングするモジュール</h4>
<p>まずネットワークから HTML を読み込みスクレイピングする部分のモジュールを作ります。a タグを読み込んでサーバ別にリンクを取得する関数と、リンクの配列をホスト別に分類してソートする関数を実装しています。</p>
<div class="codecolorer-container javascript dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #006600; font-style: italic;">// linkPicker.js</span><br />
<span style="color: #006600; font-style: italic;">// HTMLコンテンツからリンク（aタグ）を取り出す</span><br />
<br />
<span style="color: #003366; font-weight: bold;">var</span> url <span style="color: #339933;">=</span> require<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'url'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; embedJQuery <span style="color: #339933;">=</span> require<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'./embedJQuery'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #006600; font-style: italic;">// jQueryでaタグを取り出しcallbackを起動</span><br />
exports.<span style="color: #660066;">pickupLinks</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>targetUrl<span style="color: #339933;">,</span> callback<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; embedJQuery.<span style="color: #660066;">jQueryRequest</span><span style="color: #009900;">&#40;</span>targetUrl<span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>err<span style="color: #339933;">,</span> window<span style="color: #339933;">,</span> $<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>err<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>callback<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; callback<span style="color: #009900;">&#40;</span>err<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span> <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">throw</span> err<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">return</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> links <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'a'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">each</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; links.<span style="color: #660066;">push</span><span style="color: #009900;">&#40;</span>url.<span style="color: #660066;">parse</span><span style="color: #009900;">&#40;</span>String<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">href</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; links.<span style="color: #660066;">sort</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>a<span style="color: #339933;">,</span> b<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>a.<span style="color: #660066;">href</span> <span style="color: #339933;">&lt;</span> b.<span style="color: #660066;">href</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #339933;">-</span><span style="color: #CC0000;">1</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>a.<span style="color: #660066;">href</span> <span style="color: #339933;">&gt;</span> b.<span style="color: #660066;">href</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">else</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>callback<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; callback<span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">,</span> links<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><br />
<br />
<span style="color: #006600; font-style: italic;">// リンクをホストごとに分類してソート</span><br />
exports.<span style="color: #660066;">sortLinksByHost</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>links<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> i<span style="color: #339933;">,</span> j<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> host <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> hosts <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> hostLinks <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span>i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> links.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> <span style="color: #339933;">++</span>i<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> link <span style="color: #339933;">=</span> links<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> fqHost <span style="color: #339933;">=</span> link.<span style="color: #660066;">protocol</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>link.<span style="color: #660066;">slashes</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fqHost <span style="color: #339933;">+=</span> <span style="color: #3366CC;">'//'</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; fqHost <span style="color: #339933;">+=</span> link.<span style="color: #660066;">host</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>host <span style="color: #339933;">!=</span> fqHost<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; host <span style="color: #339933;">=</span> fqHost<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; hosts.<span style="color: #660066;">push</span><span style="color: #009900;">&#40;</span>fqHost<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; hostLinks<span style="color: #009900;">&#91;</span>fqHost<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; hostLinks<span style="color: #009900;">&#91;</span>fqHost<span style="color: #009900;">&#93;</span>.<span style="color: #660066;">push</span><span style="color: #009900;">&#40;</span>link<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #009900;">&#123;</span> hosts<span style="color: #339933;">:</span>hosts<span style="color: #339933;">,</span> hostLinks<span style="color: #339933;">:</span>hostLinks <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span></div></div>
<h4>コマンドラインからスクレイピング</h4>
<p>コマンドラインから起動され、上の linkPicker.js を使ってスクレイピングするスクリプトはこんな感じになります。</p>
<div class="codecolorer-container javascript dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">#<span style="color: #339933;">!/</span>usr<span style="color: #339933;">/</span>bin<span style="color: #339933;">/</span>env node<br />
<span style="color: #006600; font-style: italic;">// client.js</span><br />
<br />
<span style="color: #003366; font-weight: bold;">var</span> sys <span style="color: #339933;">=</span> require<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'sys'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; linkPicker <span style="color: #339933;">=</span> require<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'./linkPicker'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
process.<span style="color: #660066;">argv</span>.<span style="color: #660066;">forEach</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>val<span style="color: #339933;">,</span> index<span style="color: #339933;">,</span> array<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>index <span style="color: #339933;">&gt;=</span> <span style="color: #CC0000;">2</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; linkPicker.<span style="color: #660066;">pickupLinks</span><span style="color: #009900;">&#40;</span>val<span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>err<span style="color: #339933;">,</span> links<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>err<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">throw</span> err<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sys.<span style="color: #660066;">puts</span><span style="color: #009900;">&#40;</span>val <span style="color: #339933;">+</span> <span style="color: #3366CC;">' contains '</span> <span style="color: #339933;">+</span> links.<span style="color: #660066;">length</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">' links'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> sorted <span style="color: #339933;">=</span> linkPicker.<span style="color: #660066;">sortLinksByHost</span><span style="color: #009900;">&#40;</span>links<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span>i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> sorted.<span style="color: #660066;">hosts</span>.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> <span style="color: #339933;">++</span>i<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> host <span style="color: #339933;">=</span> sorted.<span style="color: #660066;">hosts</span><span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sys.<span style="color: #660066;">puts</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'¥t'</span> <span style="color: #339933;">+</span> host <span style="color: #339933;">+</span> <span style="color: #3366CC;">', '</span> <span style="color: #339933;">+</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;sorted.<span style="color: #660066;">hostLinks</span><span style="color: #009900;">&#91;</span>host<span style="color: #009900;">&#93;</span>.<span style="color: #660066;">length</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">' links'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> j <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> j <span style="color: #339933;">&lt;</span> sorted.<span style="color: #660066;">hostLinks</span><span style="color: #009900;">&#91;</span>host<span style="color: #009900;">&#93;</span>.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> <span style="color: #339933;">++</span>j<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sys.<span style="color: #660066;">puts</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'¥t¥t'</span> <span style="color: #339933;">+</span> sorted.<span style="color: #660066;">hostLinks</span><span style="color: #009900;">&#91;</span>host<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>j<span style="color: #009900;">&#93;</span>.<span style="color: #660066;">href</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></div>
<p>スクリプトに実行パーミッションをセットし、必要なファイル（embedJQuery.js、jquery.min.js、linkPicker.js）をこのスクリプトと同じディレクトリに置いてから、スクレイピングしたい URL を引数に実行すると、こんな感じに a タグのリンクを表示します。</p>
<div class="codecolorer-container bash dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ .<span style="color: #000000; font-weight: bold;">/</span>client.js &nbsp;http:<span style="color: #000000; font-weight: bold;">//</span>www.google.co.jp<span style="color: #000000; font-weight: bold;">/</span><br />
http:<span style="color: #000000; font-weight: bold;">//</span>www.google.co.jp<span style="color: #000000; font-weight: bold;">/</span> contains <span style="color: #000000;">28</span> links<br />
&nbsp; &nbsp; http:<span style="color: #000000; font-weight: bold;">//</span>blogsearch.google.co.jp, <span style="color: #000000;">1</span> links<br />
&nbsp; &nbsp; &nbsp; &nbsp; http:<span style="color: #000000; font-weight: bold;">//</span>blogsearch.google.co.jp<span style="color: #000000; font-weight: bold;">/</span>?<span style="color: #007800;">hl</span>=ja<span style="color: #000000; font-weight: bold;">&amp;</span><span style="color: #007800;">tab</span>=wb<br />
&nbsp; &nbsp; http:<span style="color: #000000; font-weight: bold;">//</span>books.google.co.jp, <span style="color: #000000;">1</span> links<br />
&nbsp; &nbsp; &nbsp; &nbsp; http:<span style="color: #000000; font-weight: bold;">//</span>books.google.co.jp<span style="color: #000000; font-weight: bold;">/</span>bkshp?<span style="color: #007800;">hl</span>=ja<span style="color: #000000; font-weight: bold;">&amp;</span><span style="color: #007800;">tab</span>=wp<br />
&nbsp; &nbsp; http:<span style="color: #000000; font-weight: bold;">//</span>docs.google.com, <span style="color: #000000;">1</span> links<br />
&nbsp; &nbsp; &nbsp; &nbsp; http:<span style="color: #000000; font-weight: bold;">//</span>docs.google.com<span style="color: #000000; font-weight: bold;">/</span>?<span style="color: #007800;">hl</span>=ja<span style="color: #000000; font-weight: bold;">&amp;</span><span style="color: #007800;">tab</span>=wo<br />
&nbsp; &nbsp; http:<span style="color: #000000; font-weight: bold;">//</span>groups.google.co.jp, <span style="color: #000000;">1</span> links<br />
&nbsp; &nbsp; &nbsp; &nbsp; http:<span style="color: #000000; font-weight: bold;">//</span>groups.google.co.jp<span style="color: #000000; font-weight: bold;">/</span>grphp?<span style="color: #007800;">hl</span>=ja<span style="color: #000000; font-weight: bold;">&amp;</span><span style="color: #007800;">tab</span>=wg<br />
&nbsp; &nbsp; http:<span style="color: #000000; font-weight: bold;">//</span>mail.google.com, <span style="color: #000000;">1</span> links<br />
&nbsp; &nbsp; &nbsp; &nbsp; http:<span style="color: #000000; font-weight: bold;">//</span>mail.google.com<span style="color: #000000; font-weight: bold;">/</span>mail<span style="color: #000000; font-weight: bold;">/</span>?<span style="color: #007800;">hl</span>=ja<span style="color: #000000; font-weight: bold;">&amp;</span><span style="color: #007800;">tab</span>=wm<br />
... 以下省略</div></div>
<h4>ウェブアプリでスクレイピング</h4>
<p>上のコマンドラインスクリプトと同じ処理を行うウェブサーバスクリプトも書いてみます。</p>
<div class="codecolorer-container javascript dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #006600; font-style: italic;">// server.js</span><br />
<br />
<span style="color: #003366; font-weight: bold;">var</span> hostname <span style="color: #339933;">=</span> <span style="color: #3366CC;">'localhost'</span><span style="color: #339933;">;</span><br />
<span style="color: #003366; font-weight: bold;">var</span> port <span style="color: #339933;">=</span> <span style="color: #CC0000;">8124</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #003366; font-weight: bold;">var</span> express <span style="color: #339933;">=</span> require<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'express'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; ejs <span style="color: #339933;">=</span> require<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'ejs'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; linkPicker <span style="color: #339933;">=</span> require<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'./linkPicker'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #003366; font-weight: bold;">var</span> app <span style="color: #339933;">=</span> express.<span style="color: #660066;">createServer</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
app.<span style="color: #660066;">register</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'.ejs'</span><span style="color: #339933;">,</span> ejs<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
app.<span style="color: #660066;">get</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'/'</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>req<span style="color: #339933;">,</span> res<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>req.<span style="color: #660066;">query</span> <span style="color: #339933;">&amp;&amp;</span> req.<span style="color: #660066;">query</span>.<span style="color: #660066;">url</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; linkPicker.<span style="color: #660066;">pickupLinks</span><span style="color: #009900;">&#40;</span>req.<span style="color: #660066;">query</span>.<span style="color: #660066;">url</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>err<span style="color: #339933;">,</span> links<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>err<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span>err<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; res.<span style="color: #660066;">send</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'403 Forbidden'</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">403</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">return</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; res.<span style="color: #660066;">render</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'result.ejs'</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; locals<span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; url<span style="color: #339933;">:</span> req.<span style="color: #660066;">query</span>.<span style="color: #660066;">url</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; links<span style="color: #339933;">:</span> links<span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sorted<span style="color: #339933;">:</span> linkPicker.<span style="color: #660066;">sortLinksByHost</span><span style="color: #009900;">&#40;</span>links<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span> <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; res.<span style="color: #660066;">render</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'index.ejs'</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; locals<span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; url<span style="color: #339933;">:</span> <span style="color: #3366CC;">''</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
app.<span style="color: #660066;">listen</span><span style="color: #009900;">&#40;</span>port<span style="color: #339933;">,</span> hostname<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></div>
<p>スクリプトでは <a href="http://expressjs.com/">express</a> フレームワークと <a href="https://github.com/visionmedia/ejs">ejs</a> テンプレートエンジンを使用しています。手元に無い場合は npm でインスコしてください。</p>
<div class="codecolorer-container bash dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #666666;">$ </span>npm <span style="color: #c20cb9; font-weight: bold;">install</span> express ejs</div></div>
<p>テンプレートエンジン用に、以下の3つのファイルを views サブディレクトリに作ります。</p>
<ul>
<li>views/layout.ejs
<div class="codecolorer-container html4strict dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="html4strict codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009900;">&lt;!doctype html&gt;</span><br />
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">html</span>&gt;</span><br />
&nbsp; <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">head</span>&gt;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">meta</span> <span style="color: #000066;">charset</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;UTF-8&quot;</span>&gt;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">title</span>&gt;</span>node.js example - link picker<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">title</span>&gt;</span><br />
&nbsp; <span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">head</span>&gt;</span><br />
&nbsp; <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">body</span>&gt;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">h1</span>&gt;</span>node.js example - link picker<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">h1</span>&gt;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">form</span> <span style="color: #000066;">method</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;GET&quot;</span>&gt;</span><br />
&nbsp; &nbsp; &nbsp; Enter URL:<br />
&nbsp; &nbsp; &nbsp; <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">input</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text&quot;</span> <span style="color: #000066;">name</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;url&quot;</span> <span style="color: #000066;">size</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;40&quot;</span> <span style="color: #000066;">value</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;&lt;%= url %&gt;</span></span>&quot;&gt;<br />
&nbsp; &nbsp; &nbsp; <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">input</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;submit&quot;</span> <span style="color: #000066;">value</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;Submit&quot;</span>&gt;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">form</span>&gt;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&lt;%- body %&gt;</span><br />
&nbsp; <span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">body</span>&gt;</span><br />
<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">html</span>&gt;</span></div></div>
</li>
<li>views/index.ejs
<div class="codecolorer-container html4strict dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="html4strict codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009900;">&lt;% <span style="color: #66cc66;">/</span>* empty *<span style="color: #66cc66;">/</span> %&gt;</span></div></div>
</li>
<li>views/result.ejs
<div class="codecolorer-container html4strict dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="html4strict codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">p</span>&gt;&lt;<span style="color: #000000; font-weight: bold;">a</span> <span style="color: #000066;">href</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;/&quot;</span>&gt;</span>Back to the top page<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">a</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">p</span>&gt;</span><br />
<br />
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">p</span>&gt;&lt;%<span style="color: #66cc66;">=</span> url %&gt;</span> contains <span style="color: #009900;">&lt;%<span style="color: #66cc66;">=</span> links.length %&gt;</span> links<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">p</span>&gt;</span><br />
<br />
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">ul</span>&gt;</span><br />
&nbsp; <span style="color: #009900;">&lt;% <span style="color: #000066;">for</span> <span style="color: #66cc66;">&#40;</span>var i <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">0</span>; i &lt; sorted.hosts.length; ++i<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span> %&gt;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&lt;% var host <span style="color: #66cc66;">=</span> sorted.hosts<span style="color: #66cc66;">&#91;</span>i<span style="color: #66cc66;">&#93;</span>; %&gt;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">li</span>&gt;&lt;%<span style="color: #66cc66;">=</span> host %&gt;</span> - <span style="color: #009900;">&lt;%<span style="color: #66cc66;">=</span> sorted.hostLinks<span style="color: #66cc66;">&#91;</span>host<span style="color: #66cc66;">&#93;</span>.length %&gt;</span> links<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">td</span>&gt;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">ul</span>&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&lt;% <span style="color: #000066;">for</span> <span style="color: #66cc66;">&#40;</span>var j <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">0</span>; j &lt; sorted.hostLinks<span style="color: #66cc66;">&#91;</span>host<span style="color: #66cc66;">&#93;</span>.length; ++j<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span> %&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">li</span>&gt;&lt;%<span style="color: #66cc66;">=</span> sorted.hostLinks<span style="color: #66cc66;">&#91;</span>host<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#91;</span>j<span style="color: #66cc66;">&#93;</span>.<span style="color: #000066;">href</span> %&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">li</span>&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&lt;% <span style="color: #66cc66;">&#125;</span> %&gt;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">ul</span>&gt;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">li</span>&gt;</span><br />
&nbsp; <span style="color: #009900;">&lt;% <span style="color: #66cc66;">&#125;</span> %&gt;</span><br />
<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">ul</span>&gt;</span></div></div>
</li>
</ul>
<p>できたらサーバスクリプトを起動します。</p>
<div class="codecolorer-container bash dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #666666;">$ </span>node server.js</div></div>
<p>http://localhost:8124/ にブラウザからアクセスするとフォームが表示されます。</p>
<p><a href="http://sakuratan.biz/blog/wp-content/uploads/2011/01/linkpicker1.png"><img src="http://sakuratan.biz/blog/wp-content/uploads/2011/01/linkpicker1-300x213.png" alt="node.js link picker" width="300" height="213" class="aligncenter size-medium wp-image-3513" /></a></p>
<p>フォームに URL を入力して submit するとスクレイピングします。<br />
<a href="http://sakuratan.biz/blog/wp-content/uploads/2011/01/linkpicker2.png"><img src="http://sakuratan.biz/blog/wp-content/uploads/2011/01/linkpicker2-300x213.png" alt="node.js link picker" width="300" height="213" class="aligncenter size-medium wp-image-3514" /></a></p>
<p>もうちょい改造してデッドリンク検出とかできるようにしようかと思いましたが面倒なので却下ということで。</p>
<p>んでわ。</p>
]]></content:encoded>
			<wfw:commentRss>http://sakuratan.biz/archives/3393/feed</wfw:commentRss>
		<slash:comments>550</slash:comments>
		</item>
	</channel>
</rss>
