iconv-lite 的使用


2019-1-9 nodejs iconv-lite

简单使用

var iconv = require('iconv-lite')
# 从一个buffer 中解码
str = iconv.decode(Buffer.from([0x68, 0x65, 0x6c, 0x6c, 0x6f]), 'win1251')//解码
buf = iconv.encode('Sample input string', 'win1251') //编码
iconv.encodingExists('us-ascii') //查询是否支持这个解码

#用法
const fs = require('fs')
const iconv = require('iconv-lite')
//读文件的方法
function read(file, encoding) {
    return new Promise((resolve, reject) => {
        fs.readFile(file, encoding, (err, date) => {
            if (err) {
                reject(err)
            } else {
                resolve(date)
            }
        })
    })
}

;(async () => {
    const jsonObj1 = await read('hahaha.json')
    console.log('jsonObj1 :', jsonObj1);
    var test = iconv.decode(jsonObj1, 'gbk2322')
    console.log(`${test}`)
})()
.then(r => {})
    .catch(e => {})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

在 node 中读取到流中

// 从流中读取使用 decodeStream 方法
http.createServer(function(req, res) {
  var converterStream = iconv.decodeStream('win1251') //创建格式
  req.pipe(converterStream) //根据格式创建管道
  converterStream.on('data', function(str) {
    //流通过管道的同时会被解码
    //TODO
  })
})

// 把流中的文件从一个格式转换到另外的格式  不会改写原文件
fs.createReadStream('file-in-win1251.txt') //从文件路径中船舰一个流格式
  .pipe(iconv.decodeStream('win1251')) //解码到计算机码
  .pipe(iconv.encodeStream('ucs2')) //重新编码
  .pipe(fs.createWriteStream('file-in-ucs2.txt')) //写到新文件

// 语法糖 所有的解码和编码方法都由一个collect方法,这个方法用作累积数据
http.createServer(function(req, res) {
  req.pipe(iconv.decodeStream('win1251')).collect(function(err, body) {
    assert(typeof body == 'string')
    console.log(body) // full request body string
  })
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

使用爬虫过程中编码解码的过程

因为 node 对很多老的编码格式不是很友好,在使用 http 的请求后默认得到的是 utf8 编码格式的,在解码过程中由很多不方便,在使用 axios 抓取网站页面过程中如果拿到页面再进行解码,那么页面已经被 node 重新编码过一遍了,这个时候数据已经被破坏了,因此要在爬取前设置返回的内容的格式 arrayBuffer 或者设置为解码格式 具体代码;

const axios = require('axios')
const $ = require('cheerio')
const iconv = require('iconv-lite')
const fs = require('fs')
const headers = {
  Accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
  'Accept-Encoding': 'gzip, deflate',
  'Accept-Language': 'zh-CN,zh;q=0.9',
  'Content-Type': 'application/json; charset=UTF-8',
  'Cache-Control': 'max-age=0',
  Connection: 'keep-alive',
  Referer: 'http: //www.ygdy8.net/html/gndy/dyzz/index.html',
  'User-Agent':
    'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36'
}
const opitions = {
  responseType: 'arraybuffer',
  headers: headers,
  baseURL: 'https://www.dytt8.net/html/'
}
const $get = async function(url, op) {
  //重新包装get方法
  return await axios.get(url, op)
}
axios.interceptors.response.use(function(response) {
  response.data = iconv.decode(response.data, 'gbk')
  return response
})
const url = 'gndy/dyzz/20190128/58123.html'
;(async () => {
  const response = await $get(url, opitions)
  if (!response) {
    console.log(``)
    return
  }
  //TODO
})()
  .then(r => {
    console.log(r)
  })
  .catch(e => {
    console.log('e :', e)
  })
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43