返回顶部
首页 > 资讯 > 前端开发 > node.js >详解nodejs爬虫程序解决gbk等中文编码问题
  • 362
分享到

详解nodejs爬虫程序解决gbk等中文编码问题

爬虫中文详解 2022-06-04 17:06:21 362人浏览 安东尼
摘要

使用nodejs写了一个爬虫的demo,目的是提取网页的title部分。 遇到最大的问题就是网页的编码与nodejs默认编码不一致造成的乱码问题。nodejs支持utf8, ucs2, ascii, b

使用nodejs写了一个爬虫的demo,目的是提取网页的title部分。

遇到最大的问题就是网页的编码与nodejs默认编码不一致造成的乱码问题。nodejs支持utf8, ucs2, ascii, binary, base64, hex等编码方式,但是对于汉语言来说编码主要分为三种,utf-8,gb2312,gbk。这里面gbk是完全兼容gb2312的,因此在处理编码的时候主要就分为utf-8以及gbk两大类。(这是在没有考虑到其他国家的编码情况,比如日本的Shift_JIS编码等,同时这里这个iconv-lite模块支持的编码方法有限)。

首先说一下浏览器显示网页内容的时候是如何处理编码问题的。服务器和客户端进行通信,服务端将网页按照指定的编码方式(比如gbk)编码成为二进制码流(即我们使用wireshark抓包看到额16进制码流)传送给我们的客户端。客户端则会根据网页源码中所规定的编码方式,由浏览器调用对应的解码器,将二进制码流解码后显示出来。而编码方式通常在网页中是如下内容表示:


<meta Http-equiv="Content-Type" content="text/html; charset=UTF-8"/>

或者


<meta charset=utf-8"/>

如果客户端是nodejs爬虫请求程序,由于nodejs默认的编码方式是utf-8,因此爬虫程序将接收到的二进制码流以字符串(默认方式utf-8)显示的时候则会显示乱码。这个时候需要将原始的二进制码流按照网页原来的编码方式解码,则不会出现乱码。

因此解决方法如下:

将接收到的网页源码以二进制的方式存储下来,处理二进制数据流使用Buffer全局对象。


res.on('data', function(data) {

  htmlData.push(data);
  htmlDataLength += data.length;
 });
var bufferHtmlData = Buffer.concat(htmlData,htmlDataLength);

然后对这些二进制的数据调用对应的解码程序。iconv-lite模块用于解码,cheerio模块用于解析网页内容。


decodeHtmlData = iconv.decode(bufferHtmlData,'gbk');

var $ = cheerio.load(decodeHtmlData, {decodeEntities: false});

 $('title','head').each(function(i, e) {

  htmlHeadTitle = $(e).text();
  console.log(htmlHeadTitle);
 });

上述bufferHtmlData为二进制码流,decodeHtmlData为将二进制码流通过gbk编码规则转换为unicode编码对应的数字(即usc2字节流),然后在转换为对应的字符串。下述为iconv-lite源码中解码部分,地址在这里:


fromEncoding: function(buf) {
          buf = ensureBuffer(buf);
          var idx = 0, len = 0,
            newBuf = new Buffer(len*2),unicode,gbkcode;
          for (var i = 0, _len = buf.length; i < _len; i++, len++) {
            if (!!(buf[i] & 0x80)) {//the high bit is 1, so this byte is gbkcode's high byte.skip next byte
              i++;
            }
          }
          var newBuf = new Buffer(len*2);
          for (var i = 0, j = 0, _len = buf.length; i < _len; i++, j++) {
            var temp = buf[i], gbkcode, unicode;
            if (temp & 0x80) {
              gbkcode = (temp << 8) + buf[++i];
              unicode = table[gbkcode] || iconv.defaultCharUnicode.charCodeAt(0);//not found in table, replace with defaultCharUnicode
            }else {
              unicode = temp;
            }
            newBuf[j*2] = unicode & 0xFF;//low byte
            newBuf[j*2+1] = unicode >> 8;//high byte
          }
          return newBuf.toString('ucs2');
        }

可以看到最终返回的是newBuf.toString(‘ucs2')字符串。

爬虫程序源码如下:


var cheerio = require('cheerio');
var http = require('http');
var iconv = require('iconv-lite');
var htmlData = [];
var htmlDataLength = 0;
var count = 0;

http.globalAgent = 'Mozilla/5.0 (windows NT 6.1; rv:2.0.1) Gecko/20100101 Firefox/4.0.1';
http.get('http://www.cr173.com', function(res) {

 res.on('data', function(data) {

  htmlData.push(data);
  htmlDataLength += data.length;
  count ++;
 });

 res.on('end',function(){

  callback(htmlData);
 });

});

function callback(htmlData){

 console.log(count);
 var bufferHtmlData = Buffer.concat(htmlData,htmlDataLength);
 var charset = '';
 var decodeHtmlData;
 var htmlHeadTitle = '';
 var htmlHeadCharset = '';
 var htmlHeadContent = '';
 var index = 0;

 var $ = cheerio.load(bufferHtmlData, {decodeEntities: false});

 $('meta','head').each(function(i, e) {

  htmlHeadCharset = $(e).attr('charset');
  htmlHeadContent = $(e).attr('content');

  if(typeof(htmlHeadCharset) != 'undefined'){

   charset = htmlHeadCharset;
  }

  if(typeof(htmlHeadContent) != 'undefined'){

   if(htmlHeadContent.match(/charset=/ig)){

    index = htmlHeadContent.indexOf('=');
    charset = htmlHeadContent.substring(index+1);
   }
  }
 });

 //此处为什么需要对整个网页进行转吗,是因为cheerio这个组件不能够返回buffer,iconv则无法转换之
 if(charset.match(/gb/ig)){

  decodeHtmlData = iconv.decode(bufferHtmlData,'gbk');
 }
 else{//因为有可能返回的网页中不存在charset字段,因此默认都是按照utf8进行处理

  decodeHtmlData = iconv.decode(bufferHtmlData,'utf8');
 }

 var $ = cheerio.load(decodeHtmlData, {decodeEntities: false});

 $('title','head').each(function(i, e) {

  htmlHeadTitle = $(e).text();
  console.log(htmlHeadTitle);
 });

 console.log(charset);

}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程网。

--结束END--

本文标题: 详解nodejs爬虫程序解决gbk等中文编码问题

本文链接: https://lsjlt.com/news/12698.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 详解nodejs爬虫程序解决gbk等中文编码问题
    使用nodejs写了一个爬虫的demo,目的是提取网页的title部分。 遇到最大的问题就是网页的编码与nodejs默认编码不一致造成的乱码问题。nodejs支持utf8, ucs2, ascii, b...
    99+
    2022-06-04
    爬虫 中文 详解
  • Python解决爬虫程序卡死问题
    目录前言:简单粗暴解决问题增加一点点难度的解决方案我们继续给爬虫程序加点料尾声前言: 之前的文章我们已经开启了爬虫程序的exe之旅,但是我们最终实现的程序存在一个非常大的问题,当进行...
    99+
    2024-04-02
  • python3里gbk编码的问题解决
    在python3有关字符串的处理当中,经常会遇到 'gbk' codec can't encode character '\xa0'这个问题,...
    99+
    2024-04-02
  • Python中爬虫编程的常见问题及解决方案
    Python中爬虫编程的常见问题及解决方案引言:随着互联网的发展,网络数据的重要性日益突出。爬虫编程成为大数据分析、网络安全等领域中必备的技能。然而,爬虫编程不仅需要良好的编程基础,还需要面对着各种常见的问题。本文将介绍Python中爬虫编...
    99+
    2023-10-22
    解决方案 常见问题 关键词:爬虫编程
  • 详解python中文编码问题
    目录 1.        在Python中使用中文1.1     Windows控制台1.2     Wi...
    99+
    2022-06-02
    python中文编码 python 编码
  • Python爬虫中的并发编程详解
    目录并发编程在爬虫中的应用什么是并发编程并发编程在爬虫中的应用单线程版本多线程版本异步I/O版本并发编程在爬虫中的应用 本文将为大家介绍 Python 中的多线程、多进程和异步编程,...
    99+
    2023-05-18
    Python并发编程 Python爬虫
  • 解决uWSGI的编码问题详解
    发现问题 最近工作中遇到一个问题,在把 Flask 写的应用通过 Supervisor+uWSGI 部署到正式服务器上时,出现了这样的错误: Unable to print the message an...
    99+
    2022-06-04
    详解 uWSGI
  • python中文编码乱码问题的解决
    目录前言:一、什么是字符编码。1.ASCII2.GB23123.Unicode4.UTF-8二、Python2中的字符编码三、decode()与encode()方法四、一个字符编码的...
    99+
    2024-04-02
  • 解决Java中properties文件编码问题
    目录1、properties文件显示乱码问题2、读取properties文件乱码3、Spring boot的@ConfigurationProperties读取properties文...
    99+
    2024-04-02
  • maven编码gbk的不可映射字符问题怎么解决
    在Maven编码为GBK的情况下,如果遇到不可映射字符的问题,可以使用下面的解决方法:1. 修改源代码文件的编码:将源代码文件的编码...
    99+
    2023-09-23
    maven
  • python如何解决中文编码乱码问题
    小编给大家分享一下python如何解决中文编码乱码问题,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!一、什么是字符编码。要彻底解决字符编码的问题就不能不去了解到底...
    99+
    2023-06-25
  • 简单解决Python文件中文编码问题
    读写中文 需要读取utf-8编码的中文文件,先利用sublime text软件将它改成无DOM的编码,然后用以下代码: with codecs.open(note_path, 'r+','utf-8')...
    99+
    2022-06-04
    中文 简单 文件
  • PHP中文乱码问题解决方法详解
    PHP中文乱码问题解决方法详解 在进行PHP开发过程中,经常会遇到中文乱码的问题,这种问题影响用户体验,也会降低网站的可读性。中文乱码问题的根本原因是编码不一致,导致服务器无法正确解析...
    99+
    2024-04-02
  • Python网络爬虫出现乱码问题的解决方法
    关于爬虫乱码有很多各式各样的问题,这里不仅是中文乱码,编码转换、还包括一些如日文、韩文 、俄文、藏文之类的乱码处理,因为解决方式是一致的,故在此统一说明。 网络爬虫出现乱码的原因 源网页编码和爬取下来后...
    99+
    2022-06-04
    爬虫 解决方法 出现乱码
  • 怎么用UTF-8解决GBK中生僻字乱码问题
    这篇文章主要介绍“怎么用UTF-8解决GBK中生僻字乱码问题”,在日常操作中,相信很多人在怎么用UTF-8解决GBK中生僻字乱码问题问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解...
    99+
    2024-04-02
  • Go语言做爬虫状态码返回418的问题解决
    目录背景原因分析代码部分背景  在使用Go语言做爬虫时,使用http.Get(url)去获取网页内容,状态码返回404,Body体为空。 原因分析  http.Get(ur...
    99+
    2022-06-07
    爬虫 GO go语言
  • Java中properties文件编码问题怎么解决
    本文小编为大家详细介绍“Java中properties文件编码问题怎么解决”,内容详细,步骤清晰,细节处理妥当,希望这篇“Java中properties文件编码问题怎么解决”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知...
    99+
    2023-06-29
  • Python3如何解决字符编码问题详解
    编码 因为计算机只能处理数字,如果要处理文本,就必须先把文本转换为数字才能处理。最早的计算机在设计时采用8个比特(bit)作为一个字节(byte),所以,一个字节能表示的最大的整数就是255(二进制1111...
    99+
    2022-06-04
    如何解决 详解 字符
  • python中——requests爬虫【中文乱码】的3种解决方法
    requests是一个较为简单易用的HTTP请求库,是python中编写爬虫程序最基础常用的一个库。 而【中文乱码】问题,是最常遇到的问题,对于初学者来说,是很困恼的。 本文将详细说明,python中...
    99+
    2023-09-01
    python 爬虫 开发语言
  • Python中常见的网络爬虫问题及解决方案
    Python中常见的网络爬虫问题及解决方案概述:随着互联网的发展,网络爬虫已经成为数据采集和信息分析的重要工具。而Python作为一种简单易用且功能强大的编程语言,被广泛应用于网络爬虫的开发。然而,在实际开发过程中,我们常会遇到一些问题。本...
    99+
    2023-10-22
    解决方案: 反爬虫机制 网络爬虫问题: IP封锁 动态网页渲染
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作