puppeteer操控浏览器模拟登录、生成pdf

学习使用,仅供参考。

1、安装

npm i puppeteer

备注: 当你安装 Puppeteer 时,它会下载最新版本的Chromium(~170MB Mac,~282MB Linux,~280MB Win),以保证可以使用 API。 如果想要跳过下载,请阅读环境变量

2、基本使用

备注: Puppeteer 至少需要 Node v6.4.0,async / await 仅在 Node v7.6.0 或更高版本中被支持。

Puppeteer 使用起来和其他测试框架类似。你需要创建一个 Browser 实例,打开页面,然后使用 Puppeteer 的 API

2.1 使用流程

  1. 引入puppeteer
  2. 使用puppeteer的launch()方法获得一个操控浏览器的实例browser
  3. 使用browser实例在内存中新建一个网页page,方便后续操作
  4. 使用网页page的setViewport()方法设置网页的尺寸大小。Puppeteer 初始化的屏幕大小默认为 800px * 600px。
  5. 使用网页page的goto()方法进入指定的页面
  6. 使用网页page的screenshot()方法进行截图操作
  7. 完成功能后处理掉操控浏览器的实例browser
const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.setViewport({ width:'1000px', height:'800px' });
  await page.goto('https://example.com');
  await page.screenshot({path: 'example.png'});

  await browser.close();
})();

3、使用Puppeteer 创建一个 PDF。

3.1、文件为 hn.js
  1. 引入puppeteer
  2. 使用puppeteer.launch()新建实例browser
  3. 使用browser实例新建一个网页page
  4. 使用网页page的setViewport()方法设置页面尺寸。
  5. 使用网页page的goto()方法进入指定的页面
  6. 使用网页page的pdf()方法进行pdf转化
  7. page.pdf( { } )配置项功能介绍     Page.pdf() 
  8. 完成功能后关掉实例browser
const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.setViewport({ width:'1000px', height:'800px' });
  await page.goto('https://news.ycombinator.com', {waitUntil: 'networkidle2'});
  await page.pdf({path: 'hn.pdf', format: 'A4'});

  await browser.close();
})();

4、实战一:去花瓣网截图保存为pdf

4.1、安装第三方依赖

npm i puppeteer
npm i pdfkit

4.2、引入需要的模块

const fs = require('fs')
const path = require('path')
const puppeteer = require('puppeteer')
const PDFDocument = require('pdfkit')

4.3、模拟登录

const fs = require('fs')
const path = require('path')
const puppeteer = require('puppeteer')
const PDFDocument = require('pdfkit')

// 有时候操作需要暂停下
const sleep = (time) =>
  new Promise((resolve) => {
    setTimeout(resolve, time)
  })

const login = async ({ username, pwd }) => {
  // 使用puppeteer的launch()方法获得一个操控浏览器的实例browser
  const browser = await puppeteer.launch({
    slowMo: 100, //放慢速度
    headless: false, //无头浏览器:关闭
    defaultViewport: { width: 1920, height: 1000 }, //设置网页的尺寸
    ignoreHTTPSErrors: false //忽略 https 报错
  })
  
  // 使用browser实例在内存中新建一个网页page
  const page = await browser.newPage()
  
  // 使用网页page的goto()方法进入指定的花瓣网页面
  await page.goto('https://huaban.com/')

  // 先使用page.screenshot()方法截图看下非登录页面
  await page.screenshot({
    path: path.resolve(__dirname, 'notLogin.png')
  })

  // 通过page.$()方法找到右上角登录按钮,点击
  const btnLogin = await page.$('.lUDCpxvZ')
  await btnLogin.click()

  // 找到登录弹框的其他登录方式,点击
  const btnOtherWay = await page.$('.__9_KlPtcX')
  await btnOtherWay.click()

  // 延迟1秒再操作
  sleep(1000)

  // 获取账号的DOM,对其进行操作,输入账号
  const inputUsername = await page.$('#email')
  inputUsername.focus()
  for (let i = 0; i < username.length; i++) {
    await inputUsername.type(username[i])
  }

  // 获取密码的DOM,对其进行操作,输入密码
  const inputPwd = await page.$('#password')
  inputPwd.focus()
  for (let i = 0; i < pwd.length; i++) {
    await inputPwd.type(pwd[i])
  }

  // 获取提交按钮的DOM
  const btnConfirm = await page.$('.CtUqjjIt')
  
  // 等待页面跳转完成,一般点击某个按钮需要跳转时,都需要等待 page.waitForNavigation() 执行完毕才表示跳转成功
  await Promise.all([btnConfirm.click(), page.waitForNavigation()])

  await sleep(3000)

  // 找到弹层关闭按钮,点击
  const btnClose = await page.$('.ant-modal-close')
  await btnClose.click()
}

login({ username: '13655246078', pwd: 'Zhu138157' })
未登录的页面

登录方式选择

登录的表单

关闭广告弹层

4.4、登录后操控浏览器去截图

const fs = require('fs')
const path = require('path')
const puppeteer = require('puppeteer')
const PDFDocument = require('pdfkit')

// 有时候操作需要暂停下
const sleep = (time) =>
  new Promise((resolve) => {
    setTimeout(resolve, time)
  })

const login = async ({ username, pwd }) => {
  // 使用puppeteer的launch()方法获得一个操控浏览器的实例browser
  const browser = await puppeteer.launch({
    slowMo: 100, //放慢速度
    headless: false, //无头浏览器:关闭
    defaultViewport: { width: 1920, height: 1000 }, //设置网页的尺寸
    ignoreHTTPSErrors: false //忽略 https 报错
  })
  
  // 使用browser实例在内存中新建一个网页page
  const page = await browser.newPage()
  
  // 使用网页page的goto()方法进入指定的花瓣网页面
  await page.goto('https://huaban.com/')

  // 先使用page.screenshot()方法截图看下非登录页面
  await page.screenshot({
    path: path.resolve(__dirname, 'notLogin.png')
  })

  // 通过page.$()方法找到右上角登录按钮,点击
  const btnLogin = await page.$('.lUDCpxvZ')
  await btnLogin.click()

  // 找到登录弹框的其他登录方式,点击
  const btnOtherWay = await page.$('.__9_KlPtcX')
  await btnOtherWay.click()

  // 延迟1秒再操作
  sleep(1000)

  // 获取账号的DOM,对其进行操作,输入账号
  const inputUsername = await page.$('#email')
  inputUsername.focus()
  for (let i = 0; i < username.length; i++) {
    await inputUsername.type(username[i])
  }

  // 获取密码的DOM,对其进行操作,输入密码
  const inputPwd = await page.$('#password')
  inputPwd.focus()
  for (let i = 0; i < pwd.length; i++) {
    await inputPwd.type(pwd[i])
  }

  // 获取提交按钮的DOM
  const btnConfirm = await page.$('.CtUqjjIt')
  
  // 等待页面跳转完成,一般点击某个按钮需要跳转时,都需要等待 page.waitForNavigation() 执行完毕才表示跳转成功
  await Promise.all([btnConfirm.click(), page.waitForNavigation()])

  await sleep(3000)

  // 找到弹层关闭按钮,点击
  const btnClose = await page.$('.ant-modal-close')
  await btnClose.click()

  // 操控浏览器做一些事情
  let rect = await page.evaluate(() => {
    const element = document.querySelector('.infinite-scroll-component ') // 选择包含指定class属性的dom节点
    const res = element.getBoundingClientRect() // 返回元素的大小及其相对于视口的位置。
    return {
      left: res.x,
      top: res.y,
      width: res.width,
      height: res.height
    }
  })

  // 截图
  await page.screenshot({
    path: path.resolve(__dirname, 'login.png'),
    clip: {
      x: rect.left,
      y: rect.top,
      width: rect.width,
      height: rect.height
    }
  })
}

login({ username: '13655246078', pwd: 'Zhu138157' })

4.5、使用pdfkit根据图片生成PDF

const fs = require('fs')
const path = require('path')
const puppeteer = require('puppeteer')
const PDFDocument = require('pdfkit')

// 有时候操作需要暂停下
const sleep = (time) =>
  new Promise((resolve) => {
    setTimeout(resolve, time)
  })

const login = async ({ username, pwd }) => {
  // 使用puppeteer的launch()方法获得一个操控浏览器的实例browser
  const browser = await puppeteer.launch({
    slowMo: 100, //放慢速度
    headless: false, //无头浏览器:关闭
    defaultViewport: { width: 1920, height: 1000 }, //设置网页的尺寸
    ignoreHTTPSErrors: false //忽略 https 报错
  })
  
  // 使用browser实例在内存中新建一个网页page
  const page = await browser.newPage()
  
  // 使用网页page的goto()方法进入指定的花瓣网页面
  await page.goto('https://huaban.com/')

  // 先使用page.screenshot()方法截图看下非登录页面
  await page.screenshot({
    path: path.resolve(__dirname, 'notLogin.png')
  })

  // 通过page.$()方法找到右上角登录按钮,点击
  const btnLogin = await page.$('.lUDCpxvZ')
  await btnLogin.click()

  // 找到登录弹框的其他登录方式,点击
  const btnOtherWay = await page.$('.__9_KlPtcX')
  await btnOtherWay.click()

  // 延迟1秒再操作
  sleep(1000)

  // 获取账号的DOM,对其进行操作,输入账号
  const inputUsername = await page.$('#email')
  inputUsername.focus()
  for (let i = 0; i < username.length; i++) {
    await inputUsername.type(username[i])
  }

  // 获取密码的DOM,对其进行操作,输入密码
  const inputPwd = await page.$('#password')
  inputPwd.focus()
  for (let i = 0; i < pwd.length; i++) {
    await inputPwd.type(pwd[i])
  }

  // 获取提交按钮的DOM
  const btnConfirm = await page.$('.CtUqjjIt')
  
  // 等待页面跳转完成,一般点击某个按钮需要跳转时,都需要等待 page.waitForNavigation() 执行完毕才表示跳转成功
  await Promise.all([btnConfirm.click(), page.waitForNavigation()])

  await sleep(3000)

  // 找到弹层关闭按钮,点击
  const btnClose = await page.$('.ant-modal-close')
  await btnClose.click()

  // 操控浏览器做一些事情
  let rect = await page.evaluate(() => {
    const element = document.querySelector('.infinite-scroll-component ') // 选择包含指定class属性的dom节点
    const res = element.getBoundingClientRect() // 返回元素的大小及其相对于视口的位置。
    return {
      left: res.x,
      top: res.y,
      width: res.width,
      height: res.height
    }
  })

  // 截图
  await page.screenshot({
    path: path.resolve(__dirname, 'login.png'),
    clip: {
      x: rect.left,
      y: rect.top,
      width: rect.width,
      height: rect.height
    }
  })

  // 使用pdfkit创建一个新的PDF文档
  const doc = new PDFDocument()
  
  // 添加图像到 PDF 文档中
  doc
    .image(path.resolve(__dirname, 'login.png'), 0, 0, {
      fit: [595.28, 841.89],
      align: 'center',
      valign: 'center'
    })
    .text('Giao', 0, 0)
  // 结束并保存PDF文档
  doc.pipe(fs.createWriteStream(path.resolve(__dirname, 'login.PDF')))
  doc.end()
  await page.close()
  await browser.close()
}

login({ username: '13655246078', pwd: 'Zhu138157' })

5、实战二:保险项目历史查询生成pdf

5.1、安装第三方依赖

npm i puppeteer
npm i pdfkit

5.2、引入需要的模块

const fs = require('fs')
const path = require('path')
const request = require('request')
const puppeteer = require('puppeteer')
const PDFDocument = require('pdfkit')

5.3、模拟登录

  1. 使用puppeteer的 launch()方法获得一个操控浏览器的实例browser
  2. 使用browser实例在内存中新建一个网页page
  3. 使用网页page.goto()方法进入指定的保险登录页面
  4. 先使用page.screenshot()方法截图看下非登录页面
  5. 登录页面的人机验证码截图至当前目录的loginCode.png文件
  6. 获取本地验证码图片转为base64
  7. 配置使用超级鹰的基本信息:需要先注册账号并购买次数才可使用
  8. 调用超级鹰的验证码识别接口,成功解析出人机验证码
  9. 获取账号的DOM,对其进行操作,输入账号
  10. 获取密码的DOM,对其进行操作,输入密码
  11. 获取验证码的DOM,对其进行操作,输入验证码
  12. 获取用户协议的DOM,勾选用户协议
  13. 获取提交按钮的DOM,进行点击登录,等待跳转成功后,预留出1秒时间用来渲染页面
登录页面
人机验证码截图

超级鹰:https://www.chaojiying.com/

        登录超级鹰后可以获取到软件id

const fs = require('fs')
const path = require('path')
const request = require('request')
const puppeteer = require('puppeteer')
const PDFDocument = require('pdfkit')

// 有时候操作需要暂停下
const sleep = (time) =>
  new Promise((resolve) => {
    setTimeout(resolve, time)
  })

const login = async ({ username, pwd }) => {
  // 使用puppeteer的launch()方法获得一个操控浏览器的实例browser
  const browser = await puppeteer.launch({
    slowMo: 100, //放慢速度
    headless: false, //无头浏览器:关闭
    defaultViewport: { width: 1920, height: 1000 }, //设置网页的尺寸
    ignoreHTTPSErrors: false //忽略 https 报错
  })
  
  // 使用browser实例在内存中新建一个网页page
  const page = await browser.newPage()
  
  // 使用网页page的goto()方法进入指定的保险登录页面
  await page.goto('http://10.79.188.18:31901/#/login')

  // 先使用page.screenshot()方法截图看下非登录页面
  await page.screenshot({
    path: path.resolve(__dirname, 'notLogin.png')
  })

  // 验证码截图
  let rectCode = await page.evaluate(() => {
    const element = document.querySelector('.code') // 选择包含指定class属性的dom节点
    const res = element.getBoundingClientRect() // 返回元素的大小及其相对于视口的位置。
    return {
      left: res.x,
      top: res.y,
      width: res.width,
      height: res.height
    }
  })

  await page.screenshot({
    path: path.resolve(__dirname, 'loginCode.png'),
    clip: {
      x: rectCode.left,
      y: rectCode.top,
      width: rectCode.width,
      height: rectCode.height
    }
  })

  // 获取本地验证码图片
  let image = fs.readFileSync('loginCode.png').toString('base64')
  let code = ''

  // 配置使用超级鹰的基本信息
  const formData = {
    user: '13655246078',
    pass: 'Zhu138157',
    softid: '955014', //软件ID 可在用户中心生成
    codetype: '1005', //验证码类型 http://www.chaojiying.com/price.html 选择
    file_base64: image
  }

  // 调用超级鹰的验证码识别接口,成功解析出人机验证码
  await request(
    {
      url: 'http://upload.chaojiying.net/Upload/Processing.php',
      method: 'POST',
      headers: {
        'content-type': 'application/x-www-form-urlencoded'
      },
      body: JSON.stringify(formData)
    },
    function (error, response, body) {
      if (!error && response.statusCode == 200) {
        console.log('请求成功的处理逻辑', JSON.parse(body)['pic_str']) // 请求成功的处理逻辑
        code = JSON.parse(body)['pic_str']
      }
    }
  )

  // 获取账号的DOM,对其进行操作,输入账号
  const inputUsername = await page.$$('.n-input__input-el')
  inputUsername[0].focus()
  await inputUsername[0].type(username)

  // 获取密码的DOM,对其进行操作,输入密码
  const inputPwd = await page.$$('.n-input__input-el')
  inputPwd[1].focus()
  await inputPwd[1].type(pwd)

  // 获取验证码的DOM,对其进行操作,输入验证码
  const verification = await page.$$('.n-input__input-el')
  verification[2].focus()
  await verification[2].type(code)

  // 获取用户协议的DOM,勾选用户协议
  const checkbox = await page.$('.n-checkbox')
  await checkbox.click()

  // 获取提交按钮的DOM
  const btnConfirm = await page.$('.n-base-wave')
  // 等待页面跳转完成,一般点击某个按钮需要跳转时,都需要等待 page.waitForNavigation() 执行完毕才表示跳转成功
  await Promise.all([btnConfirm.click(), page.waitForNavigation()])

  await sleep(1000)

}

login({ username: '13655246078', pwd: 'Zhu138157' })

5.4、登录后操控浏览器去截图

  1. 登录后再次跳转页面至历史查询
  2. 延迟2秒用来渲染跳转到的历史页面
  3. 获取具体的所要点击的详情按钮,点击查看
  4. 详情页面出现,获取具体DOM,配置截图参数,使用puppeteer截出想要的尺寸的图
登录后的页面

登录后再次跳转页面至历史查询

点击具体的详情按钮

详情截图

const fs = require('fs')
const path = require('path')
const request = require('request')
const puppeteer = require('puppeteer')
const PDFDocument = require('pdfkit')

// 有时候操作需要暂停下
const sleep = (time) =>
  new Promise((resolve) => {
    setTimeout(resolve, time)
  })

const login = async ({ username, pwd }) => {
  // 使用puppeteer的launch()方法获得一个操控浏览器的实例browser
  const browser = await puppeteer.launch({
    slowMo: 100, //放慢速度
    headless: false, //无头浏览器:关闭
    defaultViewport: { width: 1920, height: 1000 }, //设置网页的尺寸
    ignoreHTTPSErrors: false //忽略 https 报错
  })
  
  // 使用browser实例在内存中新建一个网页page
  const page = await browser.newPage()
  
  // 使用网页page的goto()方法进入指定的保险登录页面
  await page.goto('http://10.79.188.18:31901/#/login')

  // 先使用page.screenshot()方法截图看下非登录页面
  await page.screenshot({
    path: path.resolve(__dirname, 'notLogin.png')
  })

  // 验证码截图
  let rectCode = await page.evaluate(() => {
    const element = document.querySelector('.code') // 选择包含指定class属性的dom节点
    const res = element.getBoundingClientRect() // 返回元素的大小及其相对于视口的位置。
    return {
      left: res.x,
      top: res.y,
      width: res.width,
      height: res.height
    }
  })

  await page.screenshot({
    path: path.resolve(__dirname, 'loginCode.png'),
    clip: {
      x: rectCode.left,
      y: rectCode.top,
      width: rectCode.width,
      height: rectCode.height
    }
  })

  // 获取本地验证码图片
  let image = fs.readFileSync('loginCode.png').toString('base64')
  let code = ''

  // 配置使用超级鹰的基本信息
  const formData = {
    user: '13655246078',
    pass: 'Zhu138157',
    softid: '955014', //软件ID 可在用户中心生成
    codetype: '1005', //验证码类型 http://www.chaojiying.com/price.html 选择
    file_base64: image
  }

  // 调用超级鹰的验证码识别接口,成功解析出人机验证码
  await request(
    {
      url: 'http://upload.chaojiying.net/Upload/Processing.php',
      method: 'POST',
      headers: {
        'content-type': 'application/x-www-form-urlencoded'
      },
      body: JSON.stringify(formData)
    },
    function (error, response, body) {
      if (!error && response.statusCode == 200) {
        console.log('请求成功的处理逻辑', JSON.parse(body)['pic_str']) // 请求成功的处理逻辑
        code = JSON.parse(body)['pic_str']
      }
    }
  )

  // 获取账号的DOM,对其进行操作,输入账号
  const inputUsername = await page.$$('.n-input__input-el')
  inputUsername[0].focus()
  await inputUsername[0].type(username)

  // 获取密码的DOM,对其进行操作,输入密码
  const inputPwd = await page.$$('.n-input__input-el')
  inputPwd[1].focus()
  await inputPwd[1].type(pwd)

  // 获取验证码的DOM,对其进行操作,输入验证码
  const verification = await page.$$('.n-input__input-el')
  verification[2].focus()
  await verification[2].type(code)

  // 获取用户协议的DOM,勾选用户协议
  const checkbox = await page.$('.n-checkbox')
  await checkbox.click()

  // 获取提交按钮的DOM
  const btnConfirm = await page.$('.n-base-wave')
  // 等待页面跳转完成,一般点击某个按钮需要跳转时,都需要等待 page.waitForNavigation() 执行完毕才表示跳转成功
  await Promise.all([btnConfirm.click(), page.waitForNavigation()])

  await sleep(1000)

  await page.goto('http://10.79.188.18:31901/#/personalCenter/historyView')

  await sleep(2000)

  // 模拟点击查看详情
  const viewDatail = await page.$$('.n-button--info-type')
  await viewDatail[2].click()

  await sleep(2000)

  // 截图
  let rect = await page.evaluate((id = '1711267842892300290') => {
    const element = document.querySelector('.detail') // 选择包含指定class属性的dom节点
    const res = element.getBoundingClientRect() // 返回元素的大小及其相对于视口的位置。
    return {
      left: res.x,
      top: res.y,
      width: res.width,
      height: res.height
    }
  })

  await page.screenshot({
    path: path.resolve(__dirname, 'detail.png'),
    clip: {
      x: rect.left,
      y: rect.top,
      width: rect.width,
      height: rect.height
    }
  })

}

login({ username: '13655246078', pwd: 'Zhu138157' })

5.5、使用pdfkit根据图片生成PDF,关闭各个模块

  1. 新建一个PDF文档,并给定一个默认A4尺寸大小
  2. 添加图像到PDF文档中,并配置图像参数
  3. PDF文档通过管道符将流文件写入当前目录下的detail.PDF文件
  4. 关闭PDF文档
  5. 关闭网页
  6. 关闭浏览器实例
 根据截图生成PDF

const fs = require('fs')
const path = require('path')
const request = require('request')
const puppeteer = require('puppeteer')
const PDFDocument = require('pdfkit')

// 有时候操作需要暂停下
const sleep = (time) =>
  new Promise((resolve) => {
    setTimeout(resolve, time)
  })

const login = async ({ username, pwd }) => {
  // 使用puppeteer的launch()方法获得一个操控浏览器的实例browser
  const browser = await puppeteer.launch({
    slowMo: 100, //放慢速度
    headless: false, //无头浏览器:关闭
    defaultViewport: { width: 1920, height: 1000 }, //设置网页的尺寸
    ignoreHTTPSErrors: false //忽略 https 报错
  })
  
  // 使用browser实例在内存中新建一个网页page
  const page = await browser.newPage()
  
  // 使用网页page的goto()方法进入指定的保险登录页面
  await page.goto('http://10.79.188.18:31901/#/login')

  // 先使用page.screenshot()方法截图看下非登录页面
  await page.screenshot({
    path: path.resolve(__dirname, 'notLogin.png')
  })

  // 验证码截图
  let rectCode = await page.evaluate(() => {
    const element = document.querySelector('.code') // 选择包含指定class属性的dom节点
    const res = element.getBoundingClientRect() // 返回元素的大小及其相对于视口的位置。
    return {
      left: res.x,
      top: res.y,
      width: res.width,
      height: res.height
    }
  })

  await page.screenshot({
    path: path.resolve(__dirname, 'loginCode.png'),
    clip: {
      x: rectCode.left,
      y: rectCode.top,
      width: rectCode.width,
      height: rectCode.height
    }
  })

  // 获取本地验证码图片
  let image = fs.readFileSync('loginCode.png').toString('base64')
  let code = ''

  // 配置使用超级鹰的基本信息
  const formData = {
    user: '13655246078',
    pass: 'Zhu138157',
    softid: '955014', //软件ID 可在用户中心生成
    codetype: '1005', //验证码类型 http://www.chaojiying.com/price.html 选择
    file_base64: image
  }

  // 调用超级鹰的验证码识别接口,成功解析出人机验证码
  await request(
    {
      url: 'http://upload.chaojiying.net/Upload/Processing.php',
      method: 'POST',
      headers: {
        'content-type': 'application/x-www-form-urlencoded'
      },
      body: JSON.stringify(formData)
    },
    function (error, response, body) {
      if (!error && response.statusCode == 200) {
        console.log('请求成功的处理逻辑', JSON.parse(body)['pic_str']) // 请求成功的处理逻辑
        code = JSON.parse(body)['pic_str']
      }
    }
  )

  // 获取账号的DOM,对其进行操作,输入账号
  const inputUsername = await page.$$('.n-input__input-el')
  inputUsername[0].focus()
  await inputUsername[0].type(username)

  // 获取密码的DOM,对其进行操作,输入密码
  const inputPwd = await page.$$('.n-input__input-el')
  inputPwd[1].focus()
  await inputPwd[1].type(pwd)

  // 获取验证码的DOM,对其进行操作,输入验证码
  const verification = await page.$$('.n-input__input-el')
  verification[2].focus()
  await verification[2].type(code)

  // 获取用户协议的DOM,勾选用户协议
  const checkbox = await page.$('.n-checkbox')
  await checkbox.click()

  // 获取提交按钮的DOM
  const btnConfirm = await page.$('.n-base-wave')
  // 等待页面跳转完成,一般点击某个按钮需要跳转时,都需要等待 page.waitForNavigation() 执行完毕才表示跳转成功
  await Promise.all([btnConfirm.click(), page.waitForNavigation()])

  await sleep(1000)

  await page.goto('http://10.79.188.18:31901/#/personalCenter/historyView')

  await sleep(2000)

  // 模拟点击查看详情
  const viewDatail = await page.$$('.n-button--info-type')
  await viewDatail[2].click()

  await sleep(2000)

  // 截图
  let rect = await page.evaluate((id = '1711267842892300290') => {
    const element = document.querySelector('.detail') // 选择包含指定class属性的dom节点
    const res = element.getBoundingClientRect() // 返回元素的大小及其相对于视口的位置。
    return {
      left: res.x,
      top: res.y,
      width: res.width,
      height: res.height
    }
  })

  await page.screenshot({
    path: path.resolve(__dirname, 'detail.png'),
    clip: {
      x: rect.left,
      y: rect.top,
      width: rect.width,
      height: rect.height
    }
  })

  // 创建一个新的PDF文档
  const doc = new PDFDocument({ size: [841.89, 595.28] })
  // 添加图像到 PDF 文档中
  doc.image(path.resolve(__dirname, 'detail.png'), 20, 0, {
    fit: [800, 595.28],
    align: 'left',
    valign: 'top'
  })

  // 结束并保存PDF文档
  doc.pipe(fs.createWriteStream(path.resolve(__dirname, 'detail.PDF')))
  doc.end()
  await page.close()
  await browser.close()
}

login({ username: '13655246078', pwd: 'Zhu138157' })

5.6、需要攻克的问题

  1. 直接由页面DOM生成PDF:puppeteer的PDF功能模块暂时未提供api,需寻找替代方案。

  2. 模拟登录使用的超级鹰解析验证码收费:1元可使用80多次,需寻找替代方案。

    1. 注:百度云的验证码识别不智能,已 pass。

    2. 注:阿里云免费次数50次,超出收费。识别验证码会连空格一起识别出来。

  3. 图片转pdf生成的PDF不够清晰:需寻找替代方案。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值