php网页抓取乱码(一个需求需要用cheerio抓取一个网页js脚本插入末尾)
优采云 发布时间: 2021-10-06 16:02php网页抓取乱码(一个需求需要用cheerio抓取一个网页js脚本插入末尾)
最近有开发需求,使用cheerio抓取一个网页,然后在标签的末尾插入一个js脚本。然后确保浏览器正常运行。现将遇到的问题记录下来。
这里有一个问题:
Node.js 默认不支持 utf-8 编码,所以在抓取非 utf-8 中文网页时会出现乱码。比如网易的首页代码是gb2312,爬取就会出现乱码。百度大佬都用icon-lite转码(有兴趣的可以百度cheerio中文乱码)。(只是他们说的和我说的不一样。我需要将网页返回给浏览器)。然后我开始尝试。思路大概是这样:获取代理层将请求返回的html请求头的header中的content-type,来确定这个网页的编码方式。然后使用 iconv.decode 进行相应的转码,然后进行 js 替换。但是这种情况有一个漏洞,如下图
有些网站开发不够规范,甚至在content-type中没有声明网页的编码方式。因此,这条路是行不通的,只能通过抓取标签来确定网页的相应编码,然后进行转码。
var newDataStr = '';
var charset="utf-8";
var arr=responseDetail.response.body.toString().match(/]*?)>/g);
if(arr){
arr.forEach(function(val){
var match=val.match(/charset\s*=\s*(.+)\"/);
if(match && match[1]){
if(match[1].substr(0,1)=='"')match[1]=match[1].substr(1);
charset=match[1].trim();
return false;
}
})
}
var html = iconv.decode(responseDetail.response.body, charset);
// var html = responseDetail.response.body.toString();
var $ = cheerio.load(html);
responseDetail.response.body = newDataStr;
return {response: responseDetail.response}
试了下,大部分网页中文编码问题都解决了,但是还是有一些地方出现中文乱码
这个问题主要是因为节点转码成gbk后我没有将新插入的页面转码到初始状态。浏览器下载后,浏览器无法识别部分js xhr代码,导致出现部分代码。所以
newDataStr=iconv.encode($.html(), charset); 只需将其恢复为原创编码方式