爬取gbk编码的网页数据解决中文乱码需要以下3步:
1.安装模块
2.封装代码
3.引用代码编写爬取数据的代码
1.安装模块
# i是install的缩写
npm i axios # 用来发送请求
# cheerio是jquery核心功能的一个快速灵活而又简洁的实现,主要是为了用在服务器端需要对DOM进行操作的地方
npm i cheerio
# 当使用node获取GBK编码的数据时,nodejs只支持utf-8,node没有提供转换编码的原生支持.
# 因此我们要利用这个模块iconv转换编码格式
npm i iconv-lite
2.封装代码
// 安装完后需要引入,因为nodejs是基于COMMONJS规范,所以引入时都是利用require引入
const fs = require('fs')
const cheerio = require('cheerio')
const axios = require('axios')
const iconv = require('iconv-lite')
// 封装获取网页的函数
async function getHtml() {
const res = await axios({
url: "网址",
responseType: 'stream' // 以数据流的方式输出
})
// 返回一个promise实例对象
return new Promise(resolve => {
const chunks = []
res.data.on('data', chunk => {
chunks.push(chunk)
})
res.data.on('end', () => {
const buffer = Buffer.concat(chunks)
const str = iconv.decode(buffer, 'gbk')
resolve(str)
})
})
}
node处理IO采用了流(stream)的封装,分为四类,可读流、可写流和基于前者的读写流、转换流。
res.data.on(param1,param2)
这个方法主要就是监听数据变化,自动读取网页数据,两个参数分别是data
和一个回调处理函数,第一个参数只能是data
,一旦改动就无法自动获取网页数据, 回调函数的第一个参数就是获取到的流数据。
Buffer
是一个类,该类用来创建一个专门存放二进制数据的缓存区。在此代码里就是用来把获取到的所有数据流放到一个缓存区里,类似一个数组。
iconv.decode(data,'网页编码格式')
是一个iconv-lite
模块的一个方法,此方法主要就是用来解析其他编码格式的数据,当用nodejs爬取GBK格式的数据时,此方法很常用。
3.编写获取数据之后的函数
此函数只是我获取到数据后自己写的一个小案例,上面的函数是关键,获取到数据后其余的代码编写就靠自己掌控
const books = [];
async function fetchData() {
const html = await getHtml()
// decodeEntities:false设置了不会出现中文乱码。尽量都加上以防万一
const $ = cheerio.load(html, { decodeEntities: false })
const $list = $(".list").eq(0).find("ul").children()
// console.log($list.eq(0).find('a').text());
$list.each(function () {
let book = {};
book.chapter = $(this).find("a").text();
book.link = "url" + $(this).find("a").attr("href");
fs.mkdirSync("./books11/" + book.chapter, {
recursive: true,
}),
books.push(book);
})
fs.writeFileSync("./books11.json", JSON.stringify(books));
}
fetchData()