4

我正在尝试使用 Node.js 包请求和 jsdom 来抓取网页,我想知道如何提交表单并获得他们的回复。我不确定 jsdom 或其他模块是否可以做到这一点,但我知道请求支持 cookie。

以下代码演示了我如何使用 jsdom(以及 request 和 jQuery)来检索和解析网页(在本例中为 Wikipedia 主页)。(请注意,此代码改编自本教程http://blog.nodejitsu.com/jsdom-jquery-in-5-lines-on-nodejs中的 jquery-request.js 代码)

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();
    );
  });
});

上面的代码从 Wikipedia 的搜索表单中打印 HTML,然后是“Wood”,这是我设置 searchInput 字段要包含的值。当然,这里的 click() 方法实际上并没有做任何事情,因为 jQuery 不是在浏览器中运行的;我什至不知道 jsdom 是否支持任何类型的事件处理。

是否有任何模块可以帮助我以这种方式或以类似的非 jQuery 方式与网页交互?这可以在jsdom中完成吗?

提前致谢!

4

2 回答 2

4

如果您不想像在其他答案中那样自己处理 POST 请求,则可以使用 jsdom 的替代方案,它确实支持浏览器中的更多内容。

http://www.phantomjs.org/

于 2012-01-10T19:54:55.680 回答
0

我不熟悉可以让您获得网页的完全交互式客户端视图的 nodejs 库,但您可以轻松获得表单提交的结果。

HTML 表单本质上只是一种将 HTTP 请求发送到特定 URL(可以作为标记的action属性找到form)的方式。通过访问 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. “提交搜索”实际上只是意味着向标签属性中指定的 URL 发送 HTTPGETPOST请求。actionform
  2. name使用每个表单标签的属性创建用于表单提交的字符串input,并结合它们实际提交的值,格式如下:name1=value1&name2=value2
  3. 对于GET请求,只需将该字符串作为查询字符串 ( URL?query-string)附加到 URL
  4. 对于POST请求,将该字符串作为请求的正文发布。
  5. 请注意,用于表单提交的字符串必须进行转义,并且空格表示为+.
于 2012-01-10T15:35:19.873 回答