Node.js Cheerio解析器破坏了UTF-8编码

21

我用Cheerio解析我的请求,就像这样:

var url = http://shop.nag.ru/catalog/16939.IP-videonablyudenie-OMNY/16944.IP-kamery-OMNY-c-vario-obektivom/16704.OMNY-1000-PRO;
request.get(url, function (err, response, body) {
  console.log(body);
   $ = cheerio.load(body);
   console.log($(".description").html());
});

我看到的输出内容是乱码,很难读懂:

//Plain body console.log(body) (p.s. russian chars): 
<h1><span style="font-size: 16px;">Уличная 3Мп IP HD камера OMNY - попробуйте найти лучше</span></h1><p style

//  cheerio's console.log $(".description").html()
<h1><span style="font-size: 16px;">&#x423;&#x43B;&#x438;&#x447;&#x43D;&#x430;&#x44F; 3&#x41C;&#x43F; IP HD &#x43A;&#x430;&#x43C;&#x435;&#x440;&#x430; OMNY

目标URL链接编码为UTF-8格式。那么为什么Cheerio会破坏我的编码?

尝试使用iconv对我的响应正文进行编码:

var body1 = iconv.decode(body, "utf-8");

但是console.log($(".description").html());仍然返回奇怪的文本。


您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - snozza
还是没有改变结果 :( - MeetJoeBlack
2个回答

49
Cheerio没有破坏任何内容。它输出HTML实体,任何浏览器都会将其渲染为与HTML输入完全相同的内容。运行此片段以查看我的意思:

<h1><span style="font-size: 16px;">Уличная 3Мп IP HD камера OMNY - попробуйте найти лучше</span></h1>

<h1><span style="font-size: 16px;">&#x423;&#x43B;&#x438;&#x447;&#x43D;&#x430;&#x44F; 3&#x41C;&#x43F; IP HD &#x43A;&#x430;&#x43C;&#x435;&#x440;&#x430; OMNY - &#x43F;&#x43E;&#x43F;&#x440;&#x43E;&#x431;&#x443;&#x439;&#x442;&#x435; &#x43D;&#x430;&#x439;&#x442;&#x438; &#x43B;&#x443;&#x447;&#x448;&#x435;</span></h1>

< p >举个例子,< code >&#x423;这个字符被编码成了HTML实体,就像实体< code >&gt;代表的是< code >>一样。 < p >但是,如果您想要获取未编码的文本,则可以将< code >decodeEntities选项设置为< code >false:

const $ = cheerio.load(
  `<h1><span style="font-size: 16px;">Уличная 3Мп IP HD камера OMNY - попробуйте найти лучше</span></h1>`,
  { decodeEntities: false }
);


console.log($('span').html())
// => Уличная 3Мп IP HD камера OMNY - попробуйте найти лучше
.as-console-wrapper{min-height:100%}
<script src="https://bundle.run/cheerio@1.0.0-rc.3"></script>


这也避免了 Cheerio 输出中添加的第一个  字符,谢谢。 - Bruno J. S. Lesieur
1
谢谢!您的解决方案也适用于gulp-cheerio。我只是像这样使用了这个选项:gulp.src(“./mysrc”) .pipe(cheerio({ run:function($,file){ //在此处执行某些操作... }, parserOptions:{ xmlMode:true, decodeEntities:false } })) - Johnny Svarog

4
今天早些时候,我在使用cheerio加载包含特殊字符(如çáé等)的页面时遇到了问题。
Cheerio的工作方式是尝试通过本质解码字符,并呈现Unicode字符的数字HTML编码。
例如:它会将ç替换为&#xE7;
为了解决这个问题,我只需要添加一个参数decodeEntities: false到Cheerio加载参数中,就可以关闭此配置。
const $ = cheerio.load(body, { decodeEntities: false });

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接