使用nodejs抓取时,出现转码问题
newsList和newsDetail单独拿出来调试没有问题。但如下放在一起时,提示
body is not defined
经多次调试,错误节点应该是出现在readNewsDetail()中
// 转换 gbk 编码的网页内容
body2 = iconv.decode(body, 'gbk');
// 根据网页内容创建DOM操作对象
var $ = cheerio.load(body2);
这两句。因为直接 var $ = cheerio.load(res.body.toString()); 的话,不会报错。但这样一来,输出的就是乱码了,所以必须转码。但一按照我的写法转码,就会报错……
请教各位,这个问题应该怎么解决呢?
源码:
var request = require('request');
var cheerio = require('cheerio');
var iconv = require('iconv-lite');
var async = require('async');
var debug = require('debug')('sina1:update');
/**
* 获取新闻列表
*/
function readNewsList(url, callback) {
debug('读取新闻列表:%s', url);
request(url, function(err, res) {
if (err) return callback(err);
// 根据网页内容创建DOM操作对象
var $ = cheerio.load(res.body.toString());
// 读取新闻列表
var newsList = [];
$('.news-item').each(function() {
var $me = $(this);
var $title = $me.find('h2 a');
var $time = $me.find('.time');
var $url = $me.find('h2 a');
var item = {
title: $title.text().trim(),
url: $url.attr('href'),
time: $time.text().trim()
};
newsList.push(item);
});
// 返回结果
callback(null, newsList);
});
}
/**
* 获取新闻页面内容
*/
function readNewsDetail(url, callback) {
debug('读取新闻内容:%s', url);
request(url, function(err, res) {
if (err) return callback(err);
// 转换 gbk 编码的网页内容
body2 = iconv.decode(body, 'gbk');
// 根据网页内容创建DOM操作对象
var $ = cheerio.load(body2);
// 获取正文内容
var newsDetail = [];
$('.article').each(function() {
var $me = $(this);
var $img = $me.find('.img_wrapper img');
var item = {
content: $me.html().trim(),
img: $img.attr('src')
};
newsDetail.push(item);
});
// 返回结果
callback(null, newsDetail);
});
}
// 读取列表下的所有新闻
readNewsList('http://news.sina.com.cn/china/', function(err, newsList) {
if (err) return console.error(err.stack);
// 依次取出 newsList 数组的每个元素,调用第二个参数中传入的函数
// 函数的第一个参数即是 newsList 数组的其中一个元素
// 函数的第二个参数是回调函数
async.eachSeries(newsList, function(news, next) {
// 读取新闻正文
readNewsDetail(news.url, function(err, detail) {
console.log(detail);
// if (err) console.error(err.stack);
//
// // 直接显示
// console.log(detail);
//
//
// // 需要调用 next() 来返回
// next();
});
}, function(err) {
// 当遍历完 newsList 后,执行此回调函数
if (err) return console.error(err.stack);
console.log('完成');
});
});
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
帅哥,你确定你这个单独运行的时候可以?
应该是
var body2 = iconv.decode(res.body, 'gbk');
吧感谢楼上。另外还可以使用gbk库来转码