新手求教关于Nodejs模块同步问题
新手求教关于Nodejs模块同步问题
描述
- 本月刚接触nodejs,想用它做一个网页爬虫
- 因为有的网站没有header就不能爬,所以要加上header才可以。
- 但是总是加上会很麻烦,所以考虑把这部分获取网页代码的功能提取出来。
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以来,一直对这方面不太明白,求各位大神指点一二。。。
新手求教关于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);
});
解释
-
异步回调:Node.js 是单线程的事件驱动模型,因此大多数操作都是异步的。这意味着你不能直接通过
return
返回异步操作的结果,而需要使用回调函数来处理异步操作的结果。 -
错误处理:在回调函数中处理错误是一个良好的实践。如果请求过程中发生错误(例如网络问题),我们可以立即通知调用者。
-
解码:由于网页可能使用不同的字符编码,我们使用
iconv-lite
库来解码页面内容。这里使用gbk
编码进行解码。 -
回调参数:在回调函数中,第一个参数通常用于传递错误信息,第二个参数用于传递成功的结果。这样可以方便地在调用者那里处理错误或使用结果。
通过这种方式,你可以更方便地复用获取网页内容的功能,并且能够更好地处理异步操作的结果。
额。。。 我知道怎么可以让它正确显示了,虽然还不太理解为什么
测试文件中也用回调函数
//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
作为错误参数,并传递响应体作为第二个参数。如果请求失败,则传递错误对象作为第一个参数。 - 处理结果:在测试代码中,我们同样定义了一个回调函数来处理异步请求的结果。这样可以确保我们在收到响应后正确地处理数据。
希望这能解决你的问题!如果你有任何进一步的问题,请随时提问。