Node.js Puppeteer 爬虫简单学习笔记

课程内容及目标

  • 1、爬虫介绍
  • 2、制作一个自动下载图片的小爬虫
  • 3、使用 Puppeteer 爬取动态网站

前置知识

  • 1、js 基础
  • 2、node.js 基础

第一部分

什么是爬虫?

  • 可以把互联网比做成一张“大网”,爬虫就是在这张大网上不断爬取信息的程序
  • 所以一句话总结:爬虫是请求网站并提取数据的自动化程序
  • 爬虫的基本工作流程如下:
    • 1、向指定的 URL 发送 Http 请求
    • 2、获取响应(HTML、XML、JSON、二进制等数据)
    • 3、处理数据(解析 DOM、解析 JSON 等)
    • 4、将处理好的数据进行存储
      在这里插入图片描述

2、爬虫的意义

  • 爬虫就是一个探测程序,它的基本功能就是模拟人的行为去各个网站转悠,点点按钮,找找数据,或者把看到的信息背回来。就像一只虫子在一幢楼里不知疲倦地爬来爬去。
  • 我们每天使用的百度和Google,其实就是利用了这种爬虫技术:每天放出无数爬虫到各个网站,把他们的信息抓回来,存到数据库中等你来检索。
  • 抢票软件,就相当于撒出去无数个分身,每一个分身都帮助你不断刷新 12306 网站的火车余票。一旦发现有票,就马上下单,然后对你喊:大爷快来付款呀。
  • 当然,有些网站是不能被过分骚扰的,其中排第一的就是出行类行业。
  • 12306 之所以会出如此变态的验证码,就是因为被爬虫折磨的无可奈何
    在这里插入图片描述
  • 正所谓道高一尺魔高一丈,某些爬虫工具,为了解决这种变态验证码,甚至推出了“打码平台”。原理就是爬虫还是不断工作,但只要遇到验证码,就通过打码平台下发任务,打码平台另一边就雇佣一大堆网络闲人,只要考到有验证码来了,就人工选一下验证码,完美的让程序与人工结合。

爬虫基础

简单例子:爬取黑马程序猿官网所有老师照片列表

1、发送一个 HTTP 请求

  • 发送 HTTP 请求并获取响应
    • 在学习爬虫之前,需要对 HTTP 请求充分了解,因为爬虫的原理就是发送请求到指定 URL ,获取响应后并处理
  • 最基础的发送 HTTP 请求,示例代码如下:
// 目标地址
const baseURL = 'https://web.itheima.com/teacher.html#ajavaee'

// 引入 HTTPS 模块
const http = require('https')

// 创建请求对象(此时未发送 HTTP 请求)
const req = http.request(baseURL, res => {
   
    // 异步的响应
    let chunks = []
    // 监听 data 事件,获取传递过来的数据片段
    // 拼接数据片段
    res.on('data', c => chunks.push(c))

    // 监听 end 事件,获取数据完毕时触发
    res.on('end', () => {
   
        // 拼接所有的 chunk ,并转换成字符串 ==> html 字符串
        console.log(Buffer.concat(chunks).toString('utf-8'));
    })
})

// 将请求发送出去
req.end()

2、使用 cheerio 库解析 HTML 结构

npm install cheerio

3、提取 img 标签的 src 属性

  • 示例代码如下:
// 目标地址
const HOST = 'https://web.itheima.com/'
const baseURL = HOST + 'teacher.html#ajavaee'

// 引入 HTTPS 模块
const http = require('https')
const cheerio = require('cheerio')


// 创建请求对象(此时未发送 HTTP 请求)
const req = http.request(baseURL, res => {
   
    // 异步的响应
    let chunks = []
    // 监听 data 事件,获取传递过来的数据片段
    // 拼接数据片段
    res.on('data', c => chunks.push(c))

    // 监听 end 事件,获取数据完毕时触发
    res.on('end', () => {
   
        // 拼接所有的 chunk ,并转换成字符串 ==> html 字符串
        let htmlStr = Buffer.concat(chunks).toString('utf-8')

        // 通过 cheerio 解析 html
        let $ = cheerio.load(htmlStr)

        // 所有老师照片列表数组
        const photoList = []

        // 分析网页 html 结构,通过 jQuery 选择器获取想要爬取的元素
        $('.tea_con .tea_txt ul li > img').each((index, item) => {
   
            // 获取照片地址
            // 防止 URL 地址中包含中文,需要通过 encodeURI 进行编码
            photoList.push(HOST + encodeURI($(item).attr('src')))
        })
    })
})

// 将请求发送出去
req.end()

注意: :请求 URL 地址中不能有中文,为了防止 URL 包含中文需要通过 encodeURI() 编码

4、将处理好的数据进行存储

  • 使用 download 库把照片存储到指定目录中
  • 安装
npm install download
  • 示例代码如下(完整代码)
// 目标地址
const HOST = 'https://web.itheima.com/'
const baseURL = HOST + 'teacher.html#ajavaee'

// 引入 HTTPS 模块
const http = require('https')
const cheerio = require('cheerio')
const download = require('download')

// 创建请求对象(此时未发送 HTTP 请求)
const req = http.request(baseURL, res => {
   
    // 异步的响应
    let chunks = []
    // 监听 data 事件,获取传递过来的数据片段
    // 拼接数据片段
    res.on('data', c => chunks.push(c))

    // 监听 end 事件,获取数据完毕时触发
    res.on('end', () => {
   
        // 拼接所有的 chunk ,并转换成字符串 ==> html 字符串
        let htmlStr = Buffer.concat(chunks).toString('utf-8')

        // 通过 cheerio 解析 html
        let $ = cheerio.load(htmlStr)

        // 所有老师照片列表数组
        const photoList = []

        // 分析网页 html 结构,通过 jQuery 选择器获取想要爬取的元素
        $('.tea_con .tea_txt ul li > img').each((index, item) => {
   
            // 获取照片地址
            // 注意:encodeURI() 函数可把字符串作为 URI 进行编码。
            photoList.push(HOST + encodeURI($(item).attr('src')))
        })

        // 存储照片
        // dist 为照片存储目录名称
        Promise.all(photoList.map(url => download(url, 'dist'))).then(() => {
   
            console.log('下载完成');
        });
    })
})

// 将请求发送出去
req.end()

爬取新闻信息

  • 爬取目标:http://www.sd.chinanews.com.cn/more/news/pic/2.html
  • 伪造请求头(headers),一般情况下从浏览器 Network 请求头中复制
  • 示例代码如下:
const http = require('https')
const cheerio = require('cheerio')

// 目标地址
const HOST = 'https://www.itheima.com/'
const baseURL = HOST + 'news/newschild_1.html'

// 创建发送请求对象
const req = http.request(baseURL, {
   
    method: 'GET', headers: {
   
        'Access-Control-Allow-Origin': '*'
    }
}, res => {
   
    // 一段一段数据
    let chunks = []
    res.on('data', c => chunks.push(c))

    res.on('end', () => {
   
        let htmlStr = Buffer.concat(chunks).toString()
        const $ = cheerio.load(htmlStr)

        // 解析 HTML 结构
        $('.bcon .box_inner .bcon_left .bconli_right h2').each((index, item) => {
   
    
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

W.Y.B.G

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值