IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    node 爬虫,使用 Google puppeteer 抓取 One一个 的网页数据

    zuley发表于 2022-04-03 14:44:07
    love 0

    puppeteer 就不多介绍了,就是一个无界面化的谷歌浏览器。 作者本人是前端,后端方面的知识不太擅长,感觉漏洞还是蛮多的。 本教程是作者见猎心喜然后把玩了一下写的,有不合理的地方还请包涵。

    爬虫思路

    本例子是使用顺序爬取,没有用并行爬取,并设置了延时器,主要是担心访问频次太高会被屏蔽访问。

    puppeteer 写爬虫感觉思路比别的更简单,按视觉化的流程去走就可以。

    1. 启动浏览器和打开一个新页面
    2. 跳转到要抓取数据的页面
    3. 获取页面上的信息和图片
    4. 打印信息和保存图片
    5. 重复 2 ~ 4 步,直到所有页面抓取结束
    6. 关闭浏览器退出进程

    爬虫代码

    要抓取的页面:http://wufazhuce.com/one/35

    对于要抓取的资源,没有弄复杂的逻辑,根据 URL 推断是按ID排列的。 那么只要对页面 ID 依次累加就行了成功就抓取,错误就跳过。

    const puppeteer = require('puppeteer');
    const fs = require('fs');
    const request = require('request');
    
    // 延时器
    let timeout = function (delay) {
      console.log('延迟函数:', `延迟 ${delay} 毫秒`)
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          try {
            resolve(1)
          } catch (error) {
            reject(error)
          }
        }, delay);
      })
    }
    
    /**
     * One 爬虫类
     */
    class OnePaChong {
      constructor () {
        // 最大索引
        this.maxIndex = 40
        // 初始化
        this.init()
      }
      // 初始化函数
      async init () {
        console.log('正在启动浏览器...')
        this.browser = await puppeteer.launch();
        console.log('正在打开新页面...')
        this.page = await this.browser.newPage();
        // 顺序爬取页面
        for (let i = 30; i < this.maxIndex; i++) {
          await this.getPageInfo(i)
        }
        this.closeBrowser()
      }
      // 抓取页面内容
      async getPageInfo (actPage) {
        // 延时 1000 毫秒
        await timeout(1000);
        let page = this.page
        await page.goto(`http://wufazhuce.com/one/${actPage}`);
        // 获取信息
        try {
          // 获取文本
          let sText = await page.$eval('.one-cita', el => el.innerText);
          // 获取图片描述,清除空格和特殊字符 & 和 /
          let sImgName = await page.$eval('.one-imagen-leyenda', el => {
            let str = el.innerText
            str = str.replace(/^\s+|\s+$/g, '')
            str = str.replace(/\&+|\/+/g, '-')
            return str;
          });
          // 获取图片URL
          let sImgURL = await page.$eval('.one-imagen img', el => el.src);
    
          console.log('-------------------------------------------- start')
          console.log('页面页码:', actPage);
          console.log('采集状态:', '成功');
          console.log('标题句子:', sText);
          console.log('图片描述:', sImgName);
          console.log('图片地址:', sImgURL);
          console.log('-------------------------------------------- end')
          
          // 保存图片
          await request(sImgURL).pipe(fs.createWriteStream(`data/${sImgName}.png`));
        
        } catch (error) {
          console.log('-------------------------------------------- start')
          console.log('页面页码:', actPage);
          console.log('采集状态:', '失败');
          console.log('错误信息:', error)
          console.log('-------------------------------------------- end')
        }
      }
      // 关闭浏览器
      async closeBrowser () {
        console.log('正在关闭浏览器...')
        await this.browser.close()
      }
    }
    
    // 启用爬虫
    new OnePaChong()


沪ICP备19023445号-2号
友情链接