Javascript中关于抓取网络资源之后的解码问题

最近研究了一点点关于nodejs的东西,然后发现了一个简单但是不知道就要查好久的知识点(浪费了我1个多小时,资源也少),这里记录分享一下。

引子

想写一个服务器程序,可惜手头上没有什么资源拿来测试,于是就写了个小爬虫去别人网站上面偷偷扒一点,结果内容是扒下来了,但是乱码了。


悲剧的乱码

然后只能根据我iOS开发的经验,去网上找转码工具,然后就发现了这货。

https://github.com/ashtuchkin/iconv-lite

根据网上扒来的资讯,这个包是纯js编写的转码工具,相对而言,会比iconv这个要更适合js。
这个东西的用法也很简单,如下:

var iconv = require('iconv-lite');

// Convert from an encoded buffer to js string.
str = iconv.decode(new Buffer([0x68, 0x65, 0x6c, 0x6c, 0x6f]), 'win1251');

// Convert from js string to an encoded buffer.
buf = iconv.encode("Sample input string", 'win1251');

// Check if encoding is supported
iconv.encodingExists("us-ascii")

但是,结合我的请求网页内容的方法总有些问题,先贴网络请求库。

https://github.com/request/request

也是眼下用的比较多的网络请求库,基本用法如下:

var request = require('request');
request('http://www.google.com', function (error, response, body) {
  if (!error && response.statusCode == 200) {
    console.log(body) // Show the HTML for the Google homepage.
  }
})

开始遇坑

我被这个基本用法给坑了,它这个默认请求是以utf8进行解码的,然后我这个扒的站的编码是:

这个编码

然后拿到的结果就是文章开头那个样子了,中文就是个悲剧啊。

接下来的结果就是,我用这个已经被utf8解码的文本,编码回原始数据,可惜我不知道它已经用了utf8,所以就用了gb2312,最后就是错上加错。

折腾了20分钟后

我无奈了,来来回回搞了好多次,开始慢慢看这些库的源代码。

好嘛,原来request里面有这么一段介绍:

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.)

不用转来转去了,直接扒到的数据就是不编码的了,然后只要用这样一个小方法就搞定了:

function decodeData(data) {
    return iconv.decode(data, 'gb2312');
}

以后用request请求数据,建议都使用无解码请求,然后再进行转码。
好了,最终效果出来了~

千呼万唤shi出来

有什么问题欢迎大家留言讨论~~

为啥不用request请求数据的时候直接解码啊?

因为人家不支持啊。

相关内容有利益问题我可以修改的,请通知我,谢谢~~(我扒的网站不会来找我吧。。)

推荐阅读更多精彩内容