精华 request 请求到的数据为乱码,求解决
发布于 3个月前 作者 shanelau 789 次浏览 来自 问答

这个链接请求的数据结果乱码,求解决

http://zhuanlan.zhihu.com/api/columns/bigertech/posts/19885746

在浏览器中打开是正确的,自己使用 request 模块,请求到的数据就是乱码, 不知道用的什么编码格式编码的 , 跪求指导怎么解码?

var request = require('request');
request('http://zhuanlan.zhihu.com/api/columns/bigertech/posts/19885746', function (req,res,body) {
    console.log(body);
});
20 回复

设置gzip为true

var request = require('request');
request({url:'http://zhuanlan.zhihu.com/api/columns/bigertech/posts/19885746',gzip:true}, function (err,response,body) {
        console.log(body);
});

还是我来回答把,楼上的我用了是不行的! 以后回答,请先自己测试

下面测试过可用:只是我换成了superagent

var request = require('superagent');
request
.get('http://zhuanlan.zhihu.com/api/columns/bigertech/posts/19885746')
.end(function(res){
    console.log(res.body);
});

你可以把http的header打印出来看看返回的数据有没有经过gzip压缩,如果有压缩的话我得先解压缩。然后查看一下返回数据的编码, 在浏览器里直接访问返回数据好像是unicode编码,所以在接收到数据后最好使用birnary来接收,使用iconv转成utf8编码

@yaochun 一楼方法是可以的,你可能把unicode当成乱码了。

@ruanyl 我想LZ要的是和浏览器访问一样的正常的数据结构,而不是你说的【unicode】,这个有什么用?你能解码吗?

我也碰到过这种情况,取出来的内容是乱码。乱码的原因的话编码问题造成的,有的网页是utf-8,有的是gb2312。 我处理这个问题思路是这样的:把希望取出来的内容通过buffer = new Buffer(content)存进去,了解网页的编码模式, 然后用iconv-lite进行decode转码 可以试一下~~

@yessirpopesama 他这不是爬虫爬取,是直接api获取

@yaochun 如果你想看汉字,输出的那一句敲成:console.log(JSON.parse(body)); 不就好了?楼主问的是浏览器能看,但是用request看到的是乱码,这是因为用浏览器请求该url,因为Headers带有“Content-Encoding:gzip”,所以浏览器会decompress。你用浏览器能看到正常文本可能是因为你装了JSON Formatter一类的插件,不然你看到还是unicode。

但是楼主究竟问的是gzip的问题还是楼主想看正常文字,只有他自己知道了。你认为是楼主想看文字, 而@airyland 理解的是gzip。但你不能说人家的方法不行嘛,还怀疑人回答问题的态度。况且楼主的代码第一感觉是没有对gzip进行处理导致看到乱码的嘛。所以嘛,大家都是搬砖的,互相理解,互相学习嘛,我明显不能凭大脑强行解码Unicode的嘛。。

@ruanyl 我花点时间来回答一下你,混社区这么久没进前十也是一个十一,作为一个node一线老兵,遇到一个不容易

console.log(JSON.parse(body)); 

请问你实践过嘛?

我把代码给你:

var request = require('request');
request({url:'http://zhuanlan.zhihu.com/api/columns/bigertech/posts/19885746',gzip:true}, function (err,response,body) {
        console.log(JSON.parse(body)); 
});

你难道看不到错误吗?

我们现在讨论的是在node下面来访问zhihu的这个接口,LZ希望直接看到我给出的答案的这个方式,直接是没有任何编码的正常的JSON,{json太大,有兴趣的CNoder可以使用以下我的方案看看}

var request = require('superagent');
request
.get('http://zhuanlan.zhihu.com/api/columns/bigertech/posts/19885746')
.end(function(res){
    console.log(res.body);
});

而不是编码后的,如果你用request的gzip,那输出的body,我按照你的方式加了JSON.parse这样的,有用吗?

至于你说的:

你用浏览器能看到正常文本可能是因为你装了JSON Formatter一类的插件,不然你看到还是unicode。

这个和我的回答没有任何关系啊,亲,看看我们的场景~

你应该想的是当你在node下

var request = require('request');
request({url:'http://zhuanlan.zhihu.com/api/columns/bigertech/posts/19885746',gzip:true}, function (err,response,body) {
       //这个body的转码问题?如何转?
});

当然你可能觉得我提供的方案并不是最佳的,因为很简单,我就是换了一个工具包-superagent,哈哈

我的观点是:希望回答至少是实践过的,并不是针对任何人,我也鼓励大伙踊跃帮助提问的人

找到原因之后。通过 urlencode2iconv-lite 肯定能解决乱码问题。

@ruanyl @yaochun 你们的解决方案其实是一回事。 楼主之所以看到了乱码,是因为没有 ungzip。request 需要手工指定,superagent 自动 ungzip 了。 至于 JSON.parse 的问题,来看一下代码

var request = require('request');
request({url:'http://zhuanlan.zhihu.com/api/columns/bigertech/posts/19885746',gzip:true}, function (err,response,body) {
  console.log(typeof body); // => string
});

var request = require('superagent');
request
.get('http://zhuanlan.zhihu.com/api/columns/bigertech/posts/19885746')
.end(function(res){
  console.log(typeof res.body); // => object
});

在 request 库里面,body 是字符串,对应 superagent 的 res.text,superagent 里面的 body 其实是 JSON.parse(res.text)。body 只是方便调用者,省去调用 JSON.parse 而已。

@ruanyl @yaochun 在我这里,浏览器楼主的地址后,给出的源码长这样: untitled1.png

之所以里面有那些 \u 的东西,是因为知乎用 Python 开发,Python 对于内部字符串的存储形式就是 \uxxxx。因为 Python 2.x 默认不是支持 unicode 的,而 Python 3k 几乎没人用,所以存成那样保险。 我认为嘛,把楼主的问题解决到 \uxxxx 的形式就已经足够了,至于这个 \uxxxx 他怎么处理,他应该也懂得 JSON.parse 一下的。

@yaochun 别质疑我没测试过。LZ问题是乱码,我的代码我运行过已经正常了。 请问你觉运行我的代码不行是什么不行?

第一,我自己翻了下文档,写了代码,还测试过了。因此不要随便指责别人态度不对。 第二,解决到正常String已经算解决问题了,会JS的不会JSON.parse ?! 第三,你明明就是针对人,还在争辩中说不要针对人。哪来的道德高度?

看这里争论的这么开心,最后楼主跑出来说,其实我想问的是学习挖掘技术哪家强?:D

@airyland @yaochun @jinphen @jinphen @ruanyl @yessirpopesama 谢谢你们,问题已经解决了,确实是gzip压缩和解压的问题 。 不过你们好热闹,大家都是追求真理的人呐

我的chrome 确实安装了 json 自动转换工具, 所以在浏览器中 就能看到正确的 json格式

看了诸位道友的回答受益颇多,自己也动手尝试并总结了下: 1 request中如果不手动设置gzip的话显示的的确是乱码,加gzip参数后显示的便是unicode,想要看中文的话还是需要用json去parse下的。 2 superagent自带parseJson方法,内部做过处理。 3 我装的chrome是原版无插件的,浏览器看出来的就是unicode代码。诚如楼主所说能看到中文是装过json自动转换工具的。 4 我是路过度劫的~~

乱码解决 主要是为了这个 模块的, zhihu_module

回到顶部