node爬虫遇到的各种问题(cheerio+puppeteer)

Ethan

时间:2021年4月1号,文中各版本号以该时间为背景

问题一、网页采用gb2312编码,爬取后中文全部乱码

环境:node@8.12.0,cheerio@0.22.0
网站使用的gb2312编码,开始用http直接访问网页,cheerio加载后console出来中文全部乱码:
image

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解析:
image
不解析:

function downloadHandler(html) {
  const $ = cheerio.load(html,{ decodeEntities: false }) // 不解析
  console.log($.html());
}

image

原因: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版本即可

阅读 939

水平较低,只是记录,谨慎参阅

131 声望
10 粉丝
0 条评论
你知道吗?

水平较低,只是记录,谨慎参阅

131 声望
10 粉丝
宣传栏