《高阶前端指北》之JavaScript爬虫速成-无头浏览器(第二弹)

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第10天,点击查看活动详情

上一篇我们简单讲了JS爬虫的起步挂挡,这次我们解决稍微复杂一点的功能,以案例来说

HeadeLess浏览器Puppeteer

Puppeteer是一个Node.js库,提供了一个简单但高效的API,使您能够控制谷歌的Chrome或Chromium浏览器。
它还能够在headless模式下运行Chromium(对于在服务器上运行浏览器非常有用),并且可以发送和接收请求,而不需要用户界面。 最棒的是其可在后台操作,按照API的指示执行操作。

特点

· 单击按钮、链接和图像等元素
· 自动提交表单
· 导航页面
· 使用时间轴跟踪来找出问题所在
· 直接在浏览器中对用户界面和各种前端应用程序进行自动化测试
· 截屏
· 将网页转换为pdf文件

案例1

将《2022年前端发展态势》原文:State of Frontend 2022,文章保存为PDF文件。

const puppeteer = require('puppeteer')
const savePdf = async (url, path) => {
    // 启动浏览器
    const browser = await puppeteer.launch()
    // 打开页面
    const page = await browser.newPage()
    // 地址栏输入网页地址
    await page.goto(url)
    // 保存文件
    await page.pdf({
        path,
        format: 'A4'
    })
    // 关闭浏览器
    await browser.close()
}
savePdf('https://tsh.io/state-of-frontend/#report', './fe.pdf')
复制代码

运行一下脚本看看结果: image.png

好,完工。PDF功能使用场景还是比较多的,如果你不想处理爬取文章的格式,直接保存PDF是个不错的选择。另外还可以结合去除水印的API,做进一步处理。

案例2

理论上讲,你在浏览器做的所有操作,它均能通过js脚本的形式实现。比如:

  • 将网页保存图片
  • 在网页中执行脚本(类似按键精灵)
  • 自动提交表单
  • 模拟人机交互,绕过登录校验
  • 模拟淘宝,京东,外卖自动下单,抢单等能力
  • 批量下载电子书
  • 监听浏览器请求

这里面稍微复杂一点的便是模拟人机交互,由于滑块更多的是业务逻辑这里就不再坑爹的CV了,推荐大神的原理讲解模拟滑块破解

但是个人认为它的实现策略有些复杂,更优的方案是,将滑块图片加载下来,创建canvas绘制图片,通过读取imageDatargb值判断灰色区域的定位,通过左边计算滑块在x轴移动的距离。有时间给大家做一个详细版。这里简单列举一下核心逻辑:

      const canvas = document.createElement('canvas')
      canvas.width = image.width
      canvas.height = image.height
      const ctx = canvas.getContext('2d')
      ctx.drawImage(image, 0, 0)
      const imageInfo = ctx.getImageData(0, 0, image.width, image.height)
      const imageData = imageInfo.data;
      const gap = 1;
      let positionX = []
      for (var h = 0; h < image.height; h += gap) {
          for (var w = 0; w < image.width; w += gap) {
              var position = (image.width * h + w) * 4;
              var r = imageData[position], g = imageData[position + 1], b = imageData[position + 2];
              let num = 0;
              if (r >= 252) num += 1;
              if (g >= 252) num += 1;
              if (b >= 252) num += 1;
              if (num >= 2) {
                  positionX.push(w)
              }
          }
      }
复制代码

再选一个监听浏览器请求的案例:

/**
 * 监听浏览器请求
 */
const puppeteer = require('puppeteer');

const onRequest = async (url) => {

    const browser = await puppeteer.launch();

    const page = await browser.newPage();

    // 监听请求
    page.on('request', (request) => {
        console.log('request', `${request.method}, ${request.url}`);
    });

    // 监听响应
    page.on('response', (response) => {
        console.log('response', `${response.status}, ${response.url}`);
    });

    await page.goto(url);

    await browser.close();
};
onRequest('http://baidu.com');

复制代码

总结

今天我们主要了解了Puppeteer是什么?有什么用?怎么用?个人建议:现在技术发展TTMD快,想要保持高效敏捷的学习能力,不要过于执着AllIN。通过简单对其概念的理解,快速的动手调用能力,来快速掌握其原理并用于解决实际问题,到业务所需或深入时再去通览文档不迟。
很多小伙伴问我:为什么我需要很长时间才能学透一个工具或类库。其实,再聪明的人也会花费精力才能透彻一项技能。在如今TTMDK的节奏下,我们不得已也没精力样样精通,所以要掌握灵活的学习方式。
不必一切就绪,才开始行动。不必万事俱备,只待东风。 下节课我们讲,如何爬取数据存储数据库?

如果喜欢我的文章,麻烦点个赞评个论收个藏关个注

image.png 手绘图,手打字,纯原创,摘自未发布的书籍:《高阶前端指北》,转载请获得本人同意。

猜你喜欢

转载自juejin.im/post/7132393375717654535