之前在用 node 做爬虫时碰到的中文乱码问题一直没有解决,今天整理下备忘。(PS:网上一些解决方案都已经不行了)

中文乱码具体是指用 node 请求 gbk 编码的网页,无法正确获取网页中的中文(需要转码),"gbk" 和 "网页中的中文" 两个条件是缺一不可的。可以获取 utf-8 编码的网页中的中文,也可以获取 gbk 编码网页中的英文数字等。

举个简单的例子。获取 http://acm.hdu.edu.cn/statistic.php?pid=1000 排名第一的答案的 username,是为 "极光炫影"。刷刷刷写下如下代码:

var cheerio = require('cheerio')
  , superagent = require('superagent')
  , express = require('express');

var url = 'http://acm.hdu.edu.cn/statistic.php?pid=1000';
var app = express();

app.get('/', function (req, res, next) {

  superagent.get(url)
    .end(function (err, sres) {
      var html = sres.text;
      var $ = cheerio.load(html, {decodeEntities: false});
      var ans = $('.table_text td a').eq(0).html();
      res.send(ans);
    });
  });

app.listen(3000, function () {
  console.log('app is listening at port 3000');
});

得到了乱码,如下:

������Ӱ

如何获取正确的中文呢?这里提供几个解决方案应急(不关心原理,只是为了应急)。

方法一:

使用 superagent-charset 模块(2016-08-26:如出错,请使用 0.1.1 版本)。

var cheerio = require('cheerio')
  , superagent = require('superagent-charset')
  , express = require('express');

var url = 'http://acm.hdu.edu.cn/statistic.php?pid=1000';
var app = express();

app.get('/', function (req, res, next) {

  superagent.get(url)
    .charset('gbk')
    .end(function (err, sres) {
      var html = sres.text;
      var $ = cheerio.load(html, {decodeEntities: false});
      var ans = $('.table_text td a').eq(0).html();
      res.send(ans);
    });

});

app.listen(3000, function () {
  console.log('app is listening at port 3000');
});

使用非常简单,只需要引入 superagent-charset 模块,且在链式调用时加入 charset 参数即可。superagent-charset 模块包括了 superAgent 模块以及 iconv-lite 模块。源码可以参考 Github

方法二:

直接用 iconv-lite 模块进行转码。

iconv-lite 是一个进行编码转换的模块(node 默认编码 utf-8)。需要 decode 的编码必须是 Buffer 类型。

  • http 模块:

    http.get(url, function(sres) {
      var chunks = [];
    
      sres.on('data', function(chunk) {
        chunks.push(chunk);
      });
    
      sres.on('end', function() {
        // 将二进制数据解码成 gb2312 编码数据
        var html = iconv.decode(Buffer.concat(chunks), 'gb2312');
        var $ = cheerio.load(html, {decodeEntities: false});
        var ans = $('.table_text td a').eq(0).html();
        res.send(ans);
      });
    });
  • request 模块:

    request({
      url: url,
      encoding: null  // 关键代码
    }, function (err, sres, body) {
      var html = iconv.decode(body, 'gb2312')
      var $ = cheerio.load(html, {decodeEntities: false});
      var ans = $('.table_text td a').eq(0).html();
      res.send(ans);
    });

    用 iconv 进行 decode 传入的参数必须是 Buffer。

    encoding - Encoding to be used on setEncoding of response data. If null, the body is returned as a Buffer. Anything else (including the default value of undefined) will be passed as the encoding parameter to toString() (meaning this is effectively utf8 by default). (Note: if you expect binary data, you should set encoding: null.)

iconv-lite 模块能配合 http 模块以及 request 模块使用,却不能直接和 superAgent 模块使用。因为 superAgent 是以 utf8 去取数据,然后再用 iconv 转也是不行的。页面是 gbk 编码的,sres.text 已经是 decode 过了的结果,也就是说它已经被转换成 utf8 了,再转换成 buffer 出来的结果必须是不正确的。

Read More:

node爬虫之gbk网页中文乱码解决方案的更多相关文章

  1. 使用notepad++学习python爬虫,print网页中文乱码问题

    今天学习使用python爬虫的时候发现爬到的网页中文会乱码,一直网上搜索解决办法,一个一个试验过去,发现还是乱码,然后我就开始使用其它方法测试,用python自带的编辑器打开是正常的,发现是notep ...

  2. JSP中pageEncoding和charset区别,中文乱码解决方案(转载)

    转载自:JSP中pageEncoding和charset区别,中文乱码解决方案 JSP指令标签中<%@ page contentType="text/html;charset=GB23 ...

  3. (转)JSP HTML JAVASCRIPT 中文乱码 解决方案 大全

    JSP HTML JAVASCRIPT 中文乱码 解决方案 大全 JSP的中文字符一直是各位初学者首先要解决的问题,下面进行了总结,也给出了解决办法.C4.1 HTML中文编码转换 在JSP文件中的静 ...

  4. java httpclient中文乱码解决方案,看注释

    @RequestMapping("getpage") public ModelAndView admin_checkurl(HttpServletRequest request) ...

  5. Ubuntu系统配置Zabbix前端及中文乱码解决方案

    Ubuntu系统配置Zabbix前端及中文乱码解决方案  作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.安装zabbix 博主推荐阅读: https://www.cnblogs ...

  6. aspx页面,中文乱码解决方案

    由于文件编码方式编码方式不统一出现样式中文乱码解决方案: 今天碰到的问题:页面字体样式设置的'微软雅黑',可页面没引用.我调试看到样式出现中文乱码了 这种问题,就需要转换文件的编码方式,如下两步即可解 ...

  7. boost::xml——基本操作以及中文乱码解决方案 (续)

    本博文主要想说明以下两点: 1.对于上一篇的<boost::xml——基本操作以及中文乱码解决方案>解释,这篇博文基本解决了正确输入输出中英文问题,但是好像还没有解决修改中文出现乱码的问题 ...

  8. 基于Windows环境下cmd/编译器无法输入中文,显示中文乱码解决方案

    基于Windows环境下cmd/编译器无法输入中文,显示中文乱码解决方案 两个月前做C++课设的时候,电脑编译器编译结果出现了中文乱码,寻求了百度和大神们,都没有解决这个问题,百度上一堆解释是对编译器 ...

  9. JS传值中文乱码解决方案

    JS传值中文乱码解决方案 一.相关知识 1,Java相关类: (1)java.net.URLDecoder类 HTML格式解码的实用工具类,有一个静态方法:public static  String ...

随机推荐

  1. CSS项目学习总结

    1.我过去在HTML和CSS阶段是如何学习的? 我一开始学HTML和CSS,更多的是通过看视频.书籍,一个知识点一个知识点地去学习,很少把他们串联起来,看代码多于敲代码. 然而,通过现在这几个项目的实 ...

  2. MyEclipse 2016 CI 4新增BootStrap模板

    Live Preview with CodeLive 目前CodeLive还只有Live Preview这一个功能,在后续的版本中会陆续添加新功能. 新增Bootstrap模板 在模板面板中选择相应的 ...

  3. [转]IPython Notebook简介1

    原文:http://hyry.dip.jp/tech/slice/slice.html/35 Python Notebook简介1 作者 : RY    标签: cython ipython-note ...

  4. Android系统的五种数据存储形式(二)

    之前介绍了Android系统下三种数据存储形式,今天补充介绍另外两种,分别是内容提供者和网络存储.有些人可能认为内存提供者和网络存储更偏向于对数据的操作而不是数据的存储,但这两种方式确实与数据有关,所 ...

  5. 【代码笔记】iOS-下拉选项cell

    一,效果图. 二,工程图. 三,代码. RootViewController.h #import <UIKit/UIKit.h> //加入头文件 #import "ComboBo ...

  6. RMAN冷备份异机还原

    1:环境准备 在新的服务器上安装ORACLE实例,安装过程中需要注意源服务器与目标服务器的ORACLE_SID一致,另外确保安装路径与源路径一致(不仅是安装目录,甚至包括数据文件.控制文件目录.联机重 ...

  7. Linux SendMail发送邮件失败诊断案例(二)

    Linux上Sendmail经常由于一些配置问题,导致邮件发送失败,下面整理.收集了一些邮件发送失败.异常的案例. 案例1:在新服务器上测试sendmail发送邮件时,发现邮件发送不成功,检查/var ...

  8. Linux系统检查查看桌面环境

    Linux的桌面系统系统多达十几种,像gnome.kde.mate.cinnamon.lxde.xfce.jwm等.比较常用的一般是gnome.kde.xfce等.那么如何判断Linux系统安装了哪种 ...

  9. 做的一个HTML表白页面

    页面地址: http://myspace123.qiniudn.com/love/index.html 目录文件结构: index.html <html xmlns="http://w ...

  10. MySQL行锁深入研究

    原文:http://blog.csdn.net/minipeach/article/details/5325161/ 做项目时由于业务逻辑的需要,必须对数据表的一行或多行加入行锁,举个最简单的例子,图 ...