前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >nodejs使用superagent爬取网站内容中文乱码的解决方法

nodejs使用superagent爬取网站内容中文乱码的解决方法

作者头像
飞奔去旅行
发布2019-06-13 14:38:25
1.9K0
发布2019-06-13 14:38:25
举报
文章被收录于专栏:智慧协同

使用superagent爬取网站内容,当网页编码不是utf-8编码时,中文就会返回乱码,原因是superagent只支持utf-8的网页编码,我们可以使用其扩展的一个npm模块superagent-charset

superagent-charset使用说明

superagent-charset扩展了superagent的功能,使其可以手动指定编码功能。

  1. 安装
代码语言:javascript
复制
$ npm i superagent-charset
  1. 使用 使用.charset(encoding)方法,就可以指定编码,详细如下:
代码语言:javascript
复制
var assert = require('assert');
var request = require('superagent-charset');
request
    .get('http://www.sohu.com/')
    .charset('gbk')
    .end(function(err,res) {
         assert(res.text.indexOf('搜狐') > -1);
  });

潜在问题

到目前为止,仅仅是解决了我们如何设置编码的问题,但是通常我们在爬取网页的时候,都是动态爬取的,也就是说并不是人工来指定网页的编码,那么如何才能做到动态指定网页编码呢?可以这么来做:

  1. 动态获取网站编码
  2. 指定网站编码并爬去

如何动态获取网站编码呢? 为了浏览器能正常渲染网页信息,网站通常都会在设置meta charset信息,如

代码语言:javascript
复制
<meta charset='utf-8'>

或者

代码语言:javascript
复制
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>

我们可以写一个正则匹配规则,来匹配这段信息中的charset内容来获取编码,如下:

代码语言:javascript
复制
var charset = "utf-8";
var arr = res.text.match(/<meta([^>]*?)>/g);
if (arr) {
    arr.forEach(function (val) {
        var match = val.match(/charset\s*=\s*(.+)\"/);
        if (match && match[1]) {
            if (match[1].substr(0, 1) == '"')match[1] = match[1].substr(1);
            charset = match[1].trim();
        }
    })
}

当然,前提是我们需要将网页先爬下来。完整的代码如下:

代码语言:javascript
复制
parseUrl: function (url, callback) {
    async.waterfall([
            function (callback) {   // 动态获取网站编码
                superagent.get(url).end(function (err, res) {
                    var charset = "utf-8";
                    var arr = res.text.match(/<meta([^>]*?)>/g);
                    if (arr) {
                        arr.forEach(function (val) {
                            var match = val.match(/charset\s*=\s*(.+)\"/);
                            if (match && match[1]) {
                                if (match[1].substr(0, 1) == '"')match[1] = match[1].substr(1);
                                charset = match[1].trim();
                            }
                        })
                    }
                    callback(err, charset)
                })
            }, function (charset, callback) {   // 内容爬取
                superagent
                    .get(url)
                    .charset(charset)
                    .end(function (err, res) {
                        if (err) {
                            console.log(err);
                            callback(err);
                            return;
                        }
                        var model = {};
                        var $ = cheerio.load(res.text);
                        var title = _.trim($('title').text());
                        if (title.indexOf('-') > 0) {
                            var strs = _.split(title, '-');
                            model.title = _.trim(title.substr(0, title.lastIndexOf('-')));
                            model.source = _.trim(_.last(strs));
                        } else {
                            model.title = _.trim(title);
                        }
                        callback(err, model);
                    })
            }
        ],
        function (err, model) {
            callback(err, model);
        });
}

整体思路:

  1. 现将网页内容爬下来,动态获取编码
  2. 再用得到的编码再爬一次。

所以,弊端就是:同一个页面要爬两次!同一个页面要爬两次!同一个页面要爬两次!

谨慎使用!

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2016.02.29 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • superagent-charset使用说明
  • 潜在问题
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档