nodeをクローラとして使用した際に遭遇した中国語文字化け問題が解決していないので今日はメモを整理します。 (追記: インターネット上の一部の解決策は機能しなくなりました)
中国語の文字化けコードは、特にノードを使用して gbk エンコードされた Web ページをリクエストすることを指しており、Web ページ内の中国語を正しく取得できません (トランスコーディングが必要です)。 、「gbk」と「web page」「中文」の2つの条件が必須です。 utf-8 でエンコードされた Web ページでは中国語を取得できます。また、gbk でエンコードされた Web ページなどでは英語の数字を取得できます。
簡単な例を挙げてください。 http://acm.hdu.edu.cn/statistic.php?pid=1000 に対する最初の答えが得られるユーザー名は「Aurora Dazzling Shadow」です。スクラッチして次のコードを書きます:
var cheerio = require('cheerio') , superagent = require('superagent') , express = require('express');var url = 'http://acm.hdu.edu.cn/statistic.php?pid=1000';var app = express();app.get('/', function (req, res, next) { superagent.get(url) .end(function (err, sres) { var html = sres.text; var $ = cheerio.load(html, {decodeEntities: false}); var ans = $('.table_text td a').eq(0).html(); res.send(ans); }); });app.listen(3000, function () { console.log('app is listening at port 3000');});
次のように文字化けしてしまいました:
������Ӱ
正しい中国語を取得するにはどうすればよいですか?ここでは、緊急時の解決策をいくつか紹介します (原則には関係ありません。緊急時のみです)。
方法 1:
superagent-charset モジュールを使用します。
var cheerio = require('cheerio') , superagent = require('superagent-charset') , express = require('express');var url = 'http://acm.hdu.edu.cn/statistic.php?pid=1000';var app = express();app.get('/', function (req, res, next) { superagent.get(url) .charset('gbk') .end(function (err, sres) { var html = sres.text; var $ = cheerio.load(html, {decodeEntities: false}); var ans = $('.table_text td a').eq(0).html(); res.send(ans); });});app.listen(3000, function () { console.log('app is listening at port 3000');});
使い方は非常に簡単で、superagent-charset モジュールを導入し、チェーンを呼び出すときに charset パラメータを追加するだけです。 superagent-charset モジュールには、superAgent モジュールと iconv-lite モジュールが含まれています。ソースコードはGithubで見つけることができます。
方法 2:
iconv-lite モジュールを直接使用してトランスコードします。
iconv-lite は、エンコード変換用のモジュールです(ノードのデフォルトエンコードはutf-8)。デコードが必要なエンコードは、Buffer タイプである必要があります。
http モジュールを使用します:
http.get(url, function(sres) { var chunks = []; sres.on('data', function(chunk) { chunks.push(chunk); }); sres.on('end', function() { // 将二进制数据解码成 gb2312 编码数据 var html = iconv.decode(Buffer.concat(chunks), 'gb2312'); var $ = cheerio.load(html, {decodeEntities: false}); var ans = $('.table_text td a').eq(0).html(); res.send(ans); });});
リクエスト モジュールを使用します:
request({ url: url, encoding: null // 关键代码}, function (err, sres, body) { var html = iconv.decode(body, 'gb2312') var $ = cheerio.load(html, {decodeEntities: false}); var ans = $('.table_text td a').eq(0).html(); res.send(ans);});
iconv を使用してデコードして渡しますin パラメーターはバッファーである必要があります。
エンコーディング - 応答データの setEncoding で使用されるエンコーディング。null の場合、その他の値 ( のデフォルト値である未定義 を含む) がエンコーディングとして渡されます。 toString() のパラメータ (つまり、これはデフォルトでは事実上 utf8 です) (注意: バイナリ データを期待する場合は、エンコーディングを null に設定する必要があります。)
iconv - lite モジュールは、http モジュールおよび request モジュールとともに使用できますが、superAgent モジュールとともに直接使用することはできません。 superAgent は utf8 を使用してデータをフェッチし、iconv を使用して変換するため、機能しません。ページは gbk でエンコードされており、sres.text はデコードされています。つまり、utf8 に変換されており、バッファーに変換した結果は正しくないはずです。