node爬虫遇到的各种问题(cheerio+puppeteer)
时间: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
解决:重新安装0.22.0版本即可
推荐阅读
this,caller和react中的this丢失
this代表的,是函数的调用者,函数被谁调用,this就是谁caller代表的,是函数的执行环境,函数在哪个作用域中执行,caller就是谁
Ethan阅读 339
CSS 实例系列 - 02 - 2023 兔年祝福
Hello 小伙伴们早上、中午、下午、晚上和深夜好,这里是 jsliang~新年新气象,让我们耍一个兔飞猛进的祝福吧:这个是一个完整的线上小实例,小伙伴们可以填写数据,服务器会用 Node.js 定期读取数据:填写数据:[...
jsliang阅读 598
使用nodejs的http和https下载远程资源,post数据
经常用到nodejs下载资源的情况(简单的爬虫),可以考虑直接使用nodejs内置的http/https模块。test.mjs {代码...} post数据 {代码...}
jsoncode阅读 534
linux 解决 npm 安装依赖时跳过下载 puppeteer
报错 {代码...} 解决 {代码...} 引用[链接]
WingDust阅读 414
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。