web-dev-qa-db-ja.com

Node.jsCheerioパーサーがUTF-8エンコーディングを破る

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());は依然として奇妙なテキストを返します。

15
MeetJoeBlack

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>

たとえば、&#x423;は、エンティティУ&gt;を表すのと同じように、HTMLエンティティとしてエンコードされた文字>です。

ただし、エンコードされていないテキストを取得する場合は、decodeEntitiesオプションを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/[email protected]"></script>
30
Jordan Running

çáéなどの特殊文字が含まれるページをcheerioで読み込もうとしたときに問題が発生しました。

Cheerioが機能する方法は、文字を本質的にデコードし、Unicode文字の数値HTMLエンコーディングを提示しようとすることです。

例:çの代わりに&#xE7;が返されます。

この問題を並べ替えるには、cheerio loadparamとしてdecodeEntities: falseを追加してこの構成をオフにする必要がありました。

const $ = cheerio.load(body, { decodeEntities: false });
1
costargc