之前在用 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. JavaScript 数据类型

    JavaScript 数据类型 字符串.数字.布尔.数组.对象.Null.Undefined JavaScript 拥有动态类型.这意味着相同的变量可用作不同的类型: 一,JavaScript 字符串 ...

  2. iOS 如何获取屏幕大小

    UIScreen *currentScreen = [UIScreen mainScreen]; NSLog(@"applicationFrame.size.height = %f" ...

  3. ArcGIS API for Silverlight 使用GeometryService求解线与线的交点

    ///画线 void btn_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { Button btn = sender as B ...

  4. MyEclipse使用心得:集成和使用Maven的方法

    MyEclipse下载:http://www.myeclipsecn.com/download/ 第一步:下载和安装 1.官网下载Maven:http://maven.apache.org/downl ...

  5. 【Swift】 应用内显示 AppStore 某个应用的详情

    前言 应用内跳转到 AppStore 的文章很多,一般都是用 SKStoreProductViewController 来实现的,不知道有没有在意一个问题:打开很慢!!怎么忍?! 声明 欢迎转载,但请 ...

  6. AtomicInteger源码注释

    AtomicInteger源码 在java.util.concurrent.atomic包下提供了大量的原子类,这里以AtomicInteger源码为例,添加了一些注释,个人理解,供参考: 其中比较重 ...

  7. 为项目配置logback日志

    为了保证系统在上线后亦能查看运行的日志,故为系统加入日志. 1:系统引入jar包 slf4j-api.jar logback-classic.jar logback-core.jar logback- ...

  8. 监控mysql各种选项

    安装mysql之后,需要对mysql服务进行监控.   nagios开源自带的check_mysql 对 mysql 的slave 机监控倒是不错.但是对数据库主机监控就略显不足了.   使用一个监控 ...

  9. List tuple 类型转成数组

    SKlearning大部分的输入数据都是M * N数组. 然而我们从数据库或文件读取得来的通常是Python内定的类型tuple或list 它们的优势就不说了,但是直接把list或tuple构成的二维 ...

  10. chrome 浏览器的预提取资源机制导致的一个请求发送两次的问题以及ClientAbortException异常

    调查一个 pdf 打印报错: ExceptionConverter: org.apache.catalina.connector.ClientAbortException: java.net.Sock ...