node爬虫之gbk网页中文乱码解决方案_html/css_WEB-ITnose

WBOY
Release: 2016-06-21 08:58:42
Original
1853 people have browsed it

之前在用 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');});
Copy after login

得到了乱码,如下:

������Ӱ
Copy after login

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

方法一:

使用 superagent-charset模块。

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');});
Copy after login

使用非常简单,只需要引入 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);  });});
    Copy after login
  • 用 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);});
    Copy after login

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

    encoding- Encoding to be used on setEncoding of responsedata. If null, the bodyis 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 utf8by 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 出来的结果必须是不正确的。

source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!