爬取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()