Node.js爬取网页数据出现乱码,如何显示正常字符?
解决Node.js爬取网页HTML乱码问题
你遇到的乱码问题,本质是编码不匹配——目标网页大概率使用了GBK/GB2312这类非UTF-8的中文编码,而你直接用toString('utf-8')解析二进制Buffer,自然会出现那些奇怪的乱码字符。下面给你几个实用的解决方案:
方案一:用iconv-lite手动指定编码转码
这是处理中文网页乱码最常用的办法,iconv-lite库能完美兼容GBK、GB2312等常见中文编码。
- 先安装依赖:
npm install iconv-lite
- 修改你的主代码,用
iconv-lite解码Buffer:
const urlLib = require('url'); const dataLib = require('./data'); const iconv = require('iconv-lite'); dataLib.getUrl('你的网页链接', (buffer) => { // 替换成目标网页实际的编码(比如GBK/GB2312) const decodedHtml = iconv.decode(buffer, 'gbk'); console.log('done', decodedHtml); }, () => { console.log('error') });
如果你不确定网页编码,可以打开目标网页,按F12查看源码里的meta标签,比如<meta charset="gb2312">,这里的gb2312就是网页使用的编码。
方案二:自动识别响应头编码(更严谨)
很多网站会在响应头的Content-Type字段里标注编码,我们可以自动提取并转码,兼容性更好。修改你的data.js文件:
const http = require('http'); const https = require('https'); const urlLib = require('url'); const iconv = require('iconv-lite'); function getUrl(url, successCallback, errorCallback) { const parsedUrl = urlLib.parse(url); const protocol = parsedUrl.protocol === 'https:' ? https : http; protocol.get(url, (res) => { const chunks = []; res.on('data', (chunk) => { chunks.push(chunk); }); res.on('end', () => { const buffer = Buffer.concat(chunks); // 从响应头提取编码 const contentType = res.headers['content-type'] || ''; const charsetMatch = contentType.match(/charset=([^;]+)/); // 默认用GBK(中文网页常见编码),如果有指定则用指定编码 const charset = charsetMatch ? charsetMatch[1].toLowerCase() : 'gbk'; // 根据编码解码并返回 const decodedHtml = iconv.decode(buffer, charset); successCallback(decodedHtml); }); }).on('error', (err) => { errorCallback(err); }); } module.exports = { getUrl };
然后主代码可以直接接收解码后的HTML:
const urlLib = require('url'); const dataLib = require('./data'); dataLib.getUrl('你的网页链接', (html) => { console.log('done', html); }, (err) => { console.log('error occurred:', err) });
特殊情况处理
如果响应头没标注编码,且网页的编码是通过meta标签动态设置的,你可以先临时转成UTF-8字符串,匹配meta标签里的编码后再重新解码:
// 临时转成UTF-8(可能乱码,但不影响匹配meta标签) const tempHtml = buffer.toString('utf-8'); // 匹配meta标签里的charset const metaCharsetMatch = tempHtml.match(/<meta[^>]+charset=["']?([^"'>]+)["']?/i); const finalCharset = metaCharsetMatch ? metaCharsetMatch[1].toLowerCase() : 'gbk'; // 用正确编码重新解码 const decodedHtml = iconv.decode(buffer, finalCharset);
这样基本能覆盖大部分中文网页的乱码问题啦。
内容的提问来源于stack exchange,提问作者Sylvia
相关产品推荐
相关产品推荐

