2012-01-10 8 views
3

私はNode.jsパッケージのリクエストとjsdomを使ってウェブページを掻き集めようとしています。フォームを提出して回答を得る方法を知りたいと思います。 jsdomや他のモジュールでこれが可能かどうかはわかりませんが、リクエストがクッキーをサポートしていることはわかります。jsdomフォーム提出ですか?

次のコードは、jsdom(requestおよびjQueryとともに)を使用してWebページ(この場合はWikipediaのホームページ)を取得および解析する方法を示しています。上記のコードは、ウィキペディアの検索フォームは、「ウッド」、私はsearchInputフィールドを設定した値からHTMLを出力します

var request = require('request'), 
    jsdom = require('jsdom'), 

    url = 'http://www.wikipedia.org'; 

request({ uri:url }, function (error, response, body) { 
    if (error && response.statusCode !== 200) { 
    console.log('Error when contacting '+url); 
    } 

    jsdom.env({ 
    html: body, 
    scripts: [ 
     'http://code.jquery.com/jquery-1.5.min.js' 
    ] 
    }, function (err, window) { 
    var $ = window.jQuery, 
     // jQuery is now loaded on the jsdom window created from 'agent.body' 
     $searchform = $('#searchform'); //search form jQuery object 

    $('#searchInput').val('Wood'); 

    console.log('form HTML is ' + $searchform.html(), 
     'search value is ' + $('#searchInput').val() 

    //how I'd like to submit the search form 
    $('#searchform .searchButton').click(); 
    ); 
    }); 
}); 

(このコードは、このチュートリアルhttp://blog.nodejitsu.com/jsdom-jquery-in-5-lines-on-nodejsからjqueryの-request.jsコードから構成されていることに注意してください)含有すること。もちろん、click()メソッドは実際には何もしません.jQueryがブラウザで動作していないためです。 jsdomがあらゆる種類のイベント処理をサポートしているかどうかはわかりません。

この方法で、または同様の非jQueryの方法でWebページとやりとりするのに役立つモジュールはありますか?これはjsdomで行うことができますか?

ありがとうございます!

+0

フォーム上で ')('提出してください。 – fent

+0

@DeaDEnD お返事ありがとうございます。 私が不明な場合は申し訳ありませんが、私が使用している方法は実際には問題ではありません。jsdomでエミュレートされている環境です。私が使用している方法では、jsdomは単純にページ上のHTMLを解析し、結果として得られるDOMへのインタフェースを提供しています。 このように、click()またはsubmit()のどちらを使用しても、jsdomはものを見ているので、これらのハンドラは存在しません。 – Aaron

答えて

3

他の回答のように自分でPOSTリクエストを処理したくない場合は、ブラウザでもっと多くのことをサポートするjsdomの代わりに使うことができます。

http://www.phantomjs.org/

+0

ありがとう!これは私が探していたものです! ここで、PhantomJSとNode .. [リンク](https://github.com/sgentle/phantomjs-node)を統合する方法を見つけることは、ハッキーで未熟な場合には目に見えます。 もう一度おねがいします! – Aaron

+1

PhantomJSはブラウザですが、jsdomはそうではありません。したがって、PhantomJSははるかに遅く複雑です。 https://www.npmjs.com/package/phantom-ノードファントムの統合に役立ちます。 – DUzun

0

私は完全にインタラクティブなWebページのクライアント側のビューを得ることができるnodejsライブラリに精通していませんが、あまり心配することなくフォーム提出の結果を得ることができます。

HTMLフォームは基本的にHTTPリクエストを特定のURL(formタグのactionという属性)に送信する単なる方法です。 DOMにアクセスすると、これらの値を取り出して、指定されたURLに対する独自のリクエストを作成できます。このような

何かウィキペディアのホーム・ページを要求してからのコールバックはあなたに英語で「キーボードの猫」を検索して結果を取得するよう:

var $ = window.jQuery; 

var search_term = "keyboard cat"; 
var search_term_safe = encodeURIComponent(search_term).replace("%20", "+"); 

var lang = "en"; 
var lang_safe = encodeURIComponent(lang).replace("%20", "+"); 

var search_submit_url = $("#searchform").attr("action"); 
var search_input_name = $("#searchInput").attr("name"); 
var search_language_name = $("#language").attr("name"); 

var search_string = search_input_name + "=" + search_term_safe + "&" + search_language_name + "=" + lang_safe; 

// Note the wikipedia specific hack by prepending "http:". 
var full_search_uri = "http:" + search_submit_url + "?" + search_string; 

request({ uri: full_search_uri }, function(error, response) { 
    if (error && response.statusCode != 200) { 
     console.log("Got an error from the search page: " + error); 
    } else { 
     // Do some stuff with the response page here. 
    } 
}); 

基本的に重要なものは次のとおりです。

  1. 「検索を送信する」とは、formタグのaction属性で指定されたURLにHTTP GETまたはPOSTのいずれかの要求を送信することだけです。
  2. 彼らは実際にこの形式では、提出された値と組み合わせて、フォームのinputタグのそれぞれのname属性、使用してフォームの送信に使用する文字列を作成します。name1=value1&name2=value2
  3. GETの要求を、ちょうどにその文字列を追加クエリ文字列としてのURL(URL?query-string
  4. POSTリクエストの場合は、その文字列をリクエストの本文として指定します。
  5. フォーム提出に使用される文字列は、エスケープされ、空白が+である必要があります。
+0

非常に詳細な応答をありがとう! これは、特にWikipediaのようなJavaScriptライトサイトの場合、これがこの問題を解決する方法の1つであることはよく知っています。 しかし、私はJavaScriptが重いサイトが心配です。そのため、アクション属性の設定以外にフォームを送信する方法があるかもしれません。 たとえば、多くのサイトでは、フォームアクションを/#に設定し、ボタンのonclickハンドラ(JavaScriptを使用)に作業を行うハンドラをバインドします。 私のスクリプトがこのようなフォームを手作業で提出しようとすると、HTTP標準に準拠し、ハンドラをトリガーする代わりにURL /#にリクエストを送信します。 – Aaron