Node.js爬虫请求返回二进制乱码问题排查与修复咨询
Node.js爬虫爬取Giustizia Civile移动端页面乱码/空结果排查与修复方案
一、核心问题分析
控制台输出的二进制乱码大概率是响应内容被HTTP压缩(gzip/deflate),而非单纯的参数编码问题。移动端网站通常会启用内容压缩以节省带宽,Node.js的HTTP客户端(如http/https模块、默认配置的axios)如果未开启自动解压,就会直接拿到压缩后的二进制数据,导致显示乱码、无法解析内容。当然参数编码错误也可能导致服务器返回空结果,需同步排查。
二、代码排查与修复
假设你使用的原生请求代码(常见错误写法)
const https = require('https'); // 错误:可能对整个URL编码,或未处理压缩响应 const url = 'https://mobile.giustizia-civile.it/target-path?' + encodeURIComponent('参数键=参数值'); https.get(url, (res) => { let data = ''; res.on('data', (chunk) => { data += chunk; // 直接拼接二进制压缩数据成字符串,导致乱码 }); res.on('end', () => { console.log(data); // 输出乱码、空结果 }); }).on('error', (err) => { console.error(err); });
修复方案1:处理HTTP压缩响应(优先解决乱码)
通过zlib模块手动解压,同时在请求头告知服务器支持压缩格式,模拟移动端UA(多数网站会校验UA):
const https = require('https'); const zlib = require('zlib'); const options = { hostname: 'mobile.giustizia-civile.it', path: '/target-path?' + encodeURIComponent('参数键=参数值'), // 仅对参数部分编码 headers: { 'Accept-Encoding': 'gzip, deflate', // 告知服务器可返回压缩内容 'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 16_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148' // 模拟iPhone移动端UA } }; https.get(options, (res) => { // 根据响应头判断是否需要解压 const encoding = res.headers['content-encoding']; let stream = res; if (encoding === 'gzip') { stream = res.pipe(zlib.createGunzip()); } else if (encoding === 'deflate') { stream = res.pipe(zlib.createInflate()); } let data = ''; stream.on('data', (chunk) => { data += chunk.toString('utf8'); // 指定UTF-8编码拼接内容 }); stream.on('end', () => { console.log(data); // 正常显示网页内容,可继续提取目标数据 }); }).on('error', (err) => { console.error('请求错误:', err); });
修复方案2:简化版(用axios自动处理压缩与编码)
axios默认支持自动解压,且会自动处理参数编码,无需手动调用encodeURIComponent:
const axios = require('axios'); async function crawlGiustizia() { try { const response = await axios.get('https://mobile.giustizia-civile.it/target-path', { params: { // 直接传入参数键值对,axios自动完成编码 参数键: '参数值' }, headers: { 'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 16_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148' }, decompress: true // 显式开启自动解压,默认已启用 }); console.log(response.data); // 正常返回网页内容 } catch (err) { console.error('爬取失败:', err); } } crawlGiustizia();
参数编码校验要点
如果确实存在参数编码问题,需注意:
- 仅对单个参数值调用
encodeURIComponent,不要对整个URL或参数键编码 - 错误示例:
encodeURIComponent('https://xxx?a=1&b=2')(会转义整个URL,导致服务器无法识别) - 正确示例:
'https://xxx?a=' + encodeURIComponent('特殊值@#$') + '&b=' + encodeURIComponent('另一个值')
三、额外注意事项
- Cookie校验:部分页面需要携带有效Cookie才能访问,可从浏览器开发者工具中复制对应Cookie添加到请求头
- 请求速率:避免短时间内发起大量请求,可添加
setTimeout控制间隔,防止IP被封禁 - 响应编码:若仍有乱码,可尝试指定其他编码(如
ISO-8859-1,意大利语页面可能使用该编码)
内容的提问来源于stack exchange,提问作者user18918352
相关产品推荐
相关产品推荐

