新手求教关于Nodejs模块同步问题

新手求教关于Nodejs模块同步问题

描述

  • 本月刚接触nodejs,想用它做一个网页爬虫
  • 因为有的网站没有header就不能爬,所以要加上header才可以。
  • 但是总是加上会很麻烦,所以考虑把这部分获取网页代码的功能提取出来。

//helper.js

var request = require('request');
var iconv = require('iconv-lite');

function _get (_url,type,callback){ request({url:_url,headers:{‘User-Agent’:‘Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11’, ‘Accept’:‘text/html;q=0.9,/;q=0.8’, ‘Accept-Charset’:‘ISO-8859-1,utf-8;q=0.7,*;q=0.3’, ‘Connection’:‘close’, ‘Referer’:‘None’},encoding:null}, function (err, res,body) { if (err) return callback(err);

  // 根据网页内容创建DOM操作对象
  body = iconv.decode(body, 'gbk');

  // console.log(body);
  // return body;
  callback(body);	
});

};

exports.get = get;

测试代码如下

//test.js
var helper = require('./helper.js');
var cheerio = require('cheerio');

var body = helper.get("http://taobao.com");

var $ = cheerio.load(body);
console.log(body);

结果:

node test.js undefined Iconv-lite warning: decode()-ing strings is deprecated. Refer to https://github.com/ashtuchkin/iconv-lite/wiki/Use-Buffers-when-decoding

TypeError: undefined is not a function at Request._callback (d:\workplace\crawler\update\helper.js:34:4) at Request.self.callback (d:\workplace\crawler\node_modules\request\request.js:129:22) at Request.emit (events.js:98:17) at Request.<anonymous> (d:\workplace\crawler\node_modules\request\request.js:873:14) at Request.emit (events.js:117:20) at IncomingMessage.<anonymous> (d:\workplace\crawler\node_modules\request\request.js:824:12) at IncomingMessage.emit (events.js:117:20) at _stream_readable.js:943:16 at process._tickCallback (node.js:419:13)

如果是callback的话,就是上面那个结果,如果是return的话,就只有一句undefined。

接触nodejs以来,一直对这方面不太明白,求各位大神指点一二。。。


4 回复

新手求教关于Nodejs模块同步问题

描述

本月刚接触Nodejs,想用它做一个网页爬虫。因为有的网站没有header就不能爬,所以要加上header才可以。但是每次都手动加上会很麻烦,所以考虑把这部分获取网页代码的功能提取出来。

示例代码

首先,我们创建一个辅助模块 helper.js 来处理HTTP请求并返回解码后的页面内容:

// helper.js
var request = require('request');
var iconv = require('iconv-lite');

function get(_url, callback) {
    request({
        url: _url,
        headers: {
            'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11',
            'Accept': 'text/html;q=0.9,*/*;q=0.8',
            'Accept-Charset': 'ISO-8859-1,utf-8;q=0.7,*;q=0.3',
            'Connection': 'close',
            'Referer': 'None'
        },
        encoding: null
    }, function (err, res, body) {
        if (err) return callback(err);

        // 解码页面内容
        body = iconv.decode(body, 'gbk');

        // 调用回调函数传递解码后的页面内容
        callback(null, body);
    });
}

module.exports.get = get;

然后,在测试文件 test.js 中调用这个辅助模块:

// test.js
var helper = require('./helper.js');
var cheerio = require('cheerio');

helper.get("http://taobao.com", function(err, body) {
    if (err) {
        console.error(err);
        return;
    }

    var $ = cheerio.load(body);
    console.log(body);
});

解释

  1. 异步回调:Node.js 是单线程的事件驱动模型,因此大多数操作都是异步的。这意味着你不能直接通过 return 返回异步操作的结果,而需要使用回调函数来处理异步操作的结果。

  2. 错误处理:在回调函数中处理错误是一个良好的实践。如果请求过程中发生错误(例如网络问题),我们可以立即通知调用者。

  3. 解码:由于网页可能使用不同的字符编码,我们使用 iconv-lite 库来解码页面内容。这里使用 gbk 编码进行解码。

  4. 回调参数:在回调函数中,第一个参数通常用于传递错误信息,第二个参数用于传递成功的结果。这样可以方便地在调用者那里处理错误或使用结果。

通过这种方式,你可以更方便地复用获取网页内容的功能,并且能够更好地处理异步操作的结果。


额。。。 我知道怎么可以让它正确显示了,虽然还不太理解为什么

测试文件中也用回调函数

//test.js
var helper = require('./helper.js');
var cheerio = require('cheerio');

helper.get(“http://taobao.com”,function(data){ console.log(data); });

//var $ = cheerio.load(body); //console.log(body);

helper.get(“http://taobao.com”); 没有回调函数引起的

你遇到的问题主要是由于异步编程的理解不够深入。在Node.js中,网络请求等操作是异步的,你需要使用回调函数来处理结果。你的代码中helper.get方法返回的是undefined,而不是你期望的结果,这是因为request操作是异步的。

解决方案

1. 修改helper.js中的get函数

确保你在调用回调函数时传递了正确的参数:

// helper.js
var request = require('request');
var iconv = require('iconv-lite');

function get(_url, type, callback) {
    request({
        url: _url,
        headers: {
            'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11',
            'Accept': 'text/html;q=0.9,*/*;q=0.8',
            'Accept-Charset': 'ISO-8859-1,utf-8;q=0.7,*;q=0.3',
            'Connection': 'close',
            'Referer': 'None'
        },
        encoding: null
    }, function (err, res, body) {
        if (err) return callback(err, null);

        // 根据网页内容创建DOM操作对象
        body = iconv.decode(body, 'gbk');

        callback(null, body);
    });
}

module.exports.get = get;

2. 修改测试代码test.js

使用回调函数来处理异步操作的结果:

// test.js
var helper = require('./helper.js');
var cheerio = require('cheerio');

helper.get("http://taobao.com", function(err, body) {
    if (err) {
        console.error(err);
        return;
    }

    var $ = cheerio.load(body);
    console.log(body);
});

解释

  • 异步操作:在Node.js中,网络请求等I/O操作是异步的,这意味着它们不会阻塞程序的执行。因此,你需要提供一个回调函数来处理这些操作完成后的结果。
  • 回调函数:在helper.get中,我们定义了一个回调函数来处理异步请求的结果。如果请求成功,我们传递null作为错误参数,并传递响应体作为第二个参数。如果请求失败,则传递错误对象作为第一个参数。
  • 处理结果:在测试代码中,我们同样定义了一个回调函数来处理异步请求的结果。这样可以确保我们在收到响应后正确地处理数据。

希望这能解决你的问题!如果你有任何进一步的问题,请随时提问。

回到顶部