我正在尝试通过以下网址阅读Feed:
http://www.chinanews.com/rss/scroll-news.xml
使用request module。但我得到的内容有���� ʷ����)������(�й�)����
。
在审核XML
时,我发现编码设置为<?xml version="1.0" encoding="gb2312"?>
但是在尝试将编码设置为gb2312
时,我得到了未知的编码错误。
request({
url: "http://www.chinanews.com/rss/scroll-news.xml",
method: "GET",
headers: {
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
"Accept-Encoding": "gzip, deflate",
"Host": "www.chinanews.com",
"Accept-Language": "en-GB,en-US;q=0.8,en;q=0.6"
},
"gzip": true,
"encoding": "utf8"
}, (err, resp, data) => {
console.log(data);
});
有没有一种方法可以获得数据而不管它有什么编码?我该怎么做呢?
答案 0 :(得分:0)
你错过了character encoding的概念。
var iconv=require('iconv-lite'), request=require('request');
request({
url: "http://www.chinanews.com/rss/scroll-news.xml",
method: "GET",
headers: {
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
"Accept-Encoding": "gzip, deflate",
"Host": "www.chinanews.com",
"Accept-Language": "" // client accept language
},
gzip: true,
encoding: null // or 'ascii'
}, (err, resp, body) => {
console.log(iconv.decode(Buffer.from(body, 'ascii'), 'gb2312'));
});
chunk
是node.js中的Buffer
个实例。根据官方documention,只有
&#39; ASCII&#39; - 仅适用于7位ASCII数据。此编码速度很快,如果设置,将剥离高位。
&#39; UTF8&#39; - 多字节编码的Unicode字符。许多网页和其他文档格式使用UTF-8。
&#39; utf16le应按&#39; - 2或4个字节,little-endian编码的Unicode字符。支持代理对(U + 10000到U + 10FFFF)。
&#39; UCS2&#39; - 别名&#39; utf16le&#39;。
&#39; BASE64&#39; - Base64编码。从字符串创建缓冲区时,此编码也将正确接受&#34; URL和文件名安全字母&#34;如RFC4648第5节中所述。
&#39; LATIN1&#39; - 将缓冲区编码为单字节编码字符串的方法(由RFC1345中的IANA定义,第63页,为Latin-1补充块和C0 / C1控制代码)。
&#39;二进制&#39; - 别名为&#39; latin1&#39;。
&#39;十六进制&#39; - 将每个字节编码为两个十六进制字符。
node.js包含当前supported。要使用node.js不支持的编码natively,请使用iconv,iconv-lite或other libraries来获取字符映射表。这与this answer非常相似。
Accept-Language
表示客户接受的语言。 en-gb
代表English (United Kingdom)
,但不代表中文。根据RFC 7231,中文版本为zh-cn, zh
。
答案 1 :(得分:0)
棘手的部分是将编码传递为null以获取缓冲区而不是字符串。
encoding
- 用于响应数据的setEncoding的编码。 如果null
,正文将以Buffer
返回。
- request
var request = require('request');
var legacy = require('legacy-encoding');
var requestSettings = {
method: 'GET',
url: 'http://www.chinanews.com/rss/scroll-news.xml',
encoding: null,
};
request(requestSettings, function(error, response, body) {
var text = legacy.decode(body, 'gb2312');
console.log(text);
});
同样,在后续问题的背景下,&#34;
有没有办法检测编码?&#34;
通过&#34;检测&#34;我希望你的意思是,找到声明。 (...而不是猜测。如果你必须猜测,那么你的通信失败。)HTTP响应头Content-Type是传递编码的主要方式(如果适用于MIME类型)。某些MIME类型允许在内容中声明编码,因为服务器非常正确地遵循它。
对于您的RSS回复。服务器发送Content-Type:text/xml
。没有编码覆盖。内容的XML声明是<?xml version="1.0" encoding="gb2312"?>
XML规范具有查找此类声明的过程。它基本上等于用不同的编码读取,直到XML声明变得易懂,然后用声明的编码重新读取。
var request = require('request');
var legacy = require('legacy-encoding');
var convert = require('xml-js');
// specials listed here: https://www.w3.org/Protocols/rfc1341/4_Content-Type.html
var charsetFromContentTypeRegex = (/charset=([^()<>@,;:\"/[\]?.=\s]*)/i).compile();
var requestSettings = {
method: 'GET',
url: 'http://www.chinanews.com/rss/scroll-news.xml',
encoding: null,
};
request(requestSettings, function(error, response, body) {
var contentType = charsetFromContentTypeRegex.exec(response.headers['content-type'])
var encodingFromHeader = contentType.length > 1 ? contentType[1] : null;
var doc = convert.xml2js(body);
var encoding = doc.declaration.attributes.encoding;
doc = convert.xml2js(
legacy.decode(body, encodingFromHeader ? encodingFromHeader : encoding));
// xpath /rss/channel/title
console.log(doc.elements[1].elements[0].elements[0].elements[0].text);
});