时间:2021年4月1号,文中各版本号以该时间为背景
问题一、网页采用gb2312编码,爬取后中文全部乱码
环境:node@8.12.0,cheerio@0.22.0
网站使用的gb2312编码,开始用http直接访问网页,cheerio加载后console出来中文全部乱码:
const http = require('http')
const cheerio = require('cheerio')
const baseUrl = '******'
http.get(baseUrl, res => {
let html = ''
res.on('data', data => {
html += data
})
res.on('end', () => {
downloadHandler(html)
})
}).on('error', () => {
console.log('出错了')
})
function downloadHandler(html) {
const $ = cheerio.load(html) // 默认解析
console.log($.html());
}
cheerio解析:
不解析:
function downloadHandler(html) {
const $ = cheerio.load(html,{ decodeEntities: false }) // 不解析
console.log($.html());
}
原因:Node不支持gb2312
解决:使用superagent取代http,同时使用superagent-charset解决编码问题
const request = require('superagent')
require('superagent-charset')(request)
const cheerio = require('cheerio')
const baseUrl = '******'
request.get(baseUrl)
.buffer(true)
.charset('gbk')
.end((err, html) => {
downloadHandler(html)
})
function downloadHandler(html) {
const htmlText = html.text
const $ = cheerio.load(htmlText,{ decodeEntities: false })
}
问题二、一个循环内部,每次循环都会有一个异步请求;循环外部需要等内部所有请求返回结果后再执行
解决:
const idList = [1,2,3,4]
getData(idList).then(data => {
// get data
})
function getData(idList) {
let asyncPool = idList.map(id => {
return new Promise((resolve,reject) => {
request.get(`http://detail/${id}`)
.then(html => {
return resolve(html)
})
})
})
return Promise.all(asyncPool).then(data => {
return data
})
}
问题三、运行puppeteer报错:unexpected token {
环境:node@8.12.0,npm@6
原因:node版本过低
解决:升级node版本至最新稳定版14.16.0,重新安装puppeteer
问题四、运行puppeteer报错:could not find expected browser
环境:node@14.16.0,npm@6
升级好node,重新安装puppeteer。我亲眼看见他下载了版本号好像是865什么的chromium,然后运行代码puppeteer又报错说在本地找不到865版本的浏览器(明明刚才下载了,且版本号一致)。
最终在官方issues里找到了可能的答案:
https://github.com/puppeteer/puppeteer/issues/6586
原因:npm版本问题。貌似是npm6下载puppeteer时,实际下载的浏览器版本和puppeteer需要的并不一致
解决:升级npm至7,重新安装puppeteer,正常运行
问题五、升级node后,cheerio无法正常运行,报错:content.forEach() is not a function
环境:node@14.16.0,npm@7,cheerio@v1.0.0-rc5
升级了node和npm至最新稳定版后,把之前的包也全部重新安装了一遍
cheerio突然一直报错无法运行,之前是正常的。
还是在官方issues里找到了答案:
https://github.com/cheeriojs/cheerio/issues/1591
原因:cheerio版本问题
Cheerio.load expects there to be array. Older versions was there condition for checking, if it is not array. Seems like it is lost due to optimizations.
older version wraps it into array
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。