zoukankan      html  css  js  c++  java
  • 记录一次使用 puppeteer 爬 微信小程序发布平台

    以下代码主要功能为 爬取 微信小程序开发者平台页面,实现登录,发送二维码,点击版本管理等点击操作

    const util = require('./utilVes5')
    const puppeteer = require('puppeteer')
    const fs = require('fs')
    const { exit } = require('process')
    const path = require('path')
    const db = require('./dbVes5')
    const wxWorkServerHost = 'http://00.0.0.0:0000'
    const wxWorkNotification = async ({ content, image, touser }) => {
      if (content) {
        await util.req('POST', `${wxWorkServerHost}/api/txt`, { content, touser }, {})
      }
      if (image) {
        await util.req('POST', `${wxWorkServerHost}/api/image`, {}, {}, { json: null, body: null, headers: { 'content-type': 'multipart/form-data' }, formData: { touser, file: fs.createReadStream(image) } })
      }
    }
    (async () => {
      await db.init()
      const col = db.getCol('user')
      const cursor = await col.find()
      const list = await cursor.toArray()
      const enameList = []
      list.forEach(item => {
        if (item.role && item.role.admin && item.role.admin.indexOf('super') !== -1) enameList.push(item.ename)
      })
      if (enameList.length === 0) exit(0)
      try {
        const browser = await puppeteer.launch({
          // 是否开启无头模式
          headless: true
        })
        const page = await browser.newPage()
        // 打开页面
        await page.goto('https://mp.weixin.qq.com', {
          waitUntil: 'networkidle2'
        })
        const selectType = await page.$$('.login__type__container__select-type')
        // 点击使用账户登录
        await selectType[1].click()
        const formInput = await page.$$('.weui-desktop-form__input')
        const $username = formInput[0]
        const $password = formInput[1]
        // 输入账户
        await $username.type('xxxxx@qq.com')
        // 输入密码
        await $password.type('xxxxxxx')
        const btnLogin = await page.$('.btn_login')
        // 点击登录
        await btnLogin.click()
        // 等待登录,加载二维码
        await page.waitForNavigation({
          waitUntil: 'networkidle0'
        })
        // 保存截图,备企业微信发送图片使用
        await page.screenshot({ path: path.join(__dirname, '../../static/logQRCode.png') })
        enameList.forEach(async ename => {
          await wxWorkNotification({content: '小程序自动发布,请扫码登录', touser: ename, image: path.join(__dirname, '../../static/logQRCode.png')})
        })
        // 设置页面超时时间为半小时
        page.setDefaultNavigationTimeout(1800000)
        // 等待扫描二维码跳转页面
        await page.waitForNavigation({
          waitUntil: 'networkidle0'
        })
        const menuItem = await page.$$('.menu_item')
        // 点击版本管理
        await menuItem[0].click()
        // 恢复页面默认等待超时时间
        page.setDefaultNavigationTimeout(30000)
        // 等待页面渲染完毕
        await page.waitForNavigation({
          waitUntil: 'networkidle0'
        })
        // 获取所有 class 名为 code_version_log 的元素
        const codeVersionLog = await page.$$('.code_version_log')
        codeVersionLog.forEach(async parent => {
          // 查找名为 simple_preview_value的子级,是否满足 text 等于 uat
          const isUat = await parent.$$eval('.simple_preview_value', node => {
            for (let i = 0; i < node.length; i++) {
              if (node[i].innerText.indexOf('UAT') !== -1) return true
            }
          })
           // 查找名为 weui-desktop-btn的子级,是否满足 text 等于 提交审核
          const isTop = await parent.$$eval('.weui-desktop-btn', node => {
            for (let i = 0; i < node.length; i++) {
              if (node[i].innerText === '提交审核') return true
            }
          })
          if (isUat && isTop) {
            // 如果两者同时满足,点击提交审核按钮
            const weuiDesktopBtn = await parent.$('.weui-desktop-btn')
            await weuiDesktopBtn.click()
          }
        })
        // 延时 3500 毫秒,等待弹窗弹出
        await page.waitForTimeout(3500)
        // 获取所有名为 weui-desktop-dialog 的元素
        const weuiDesktopDialog = await page.$$('.weui-desktop-dialog')
        for (let p = 0; p < weuiDesktopDialog.length; p++) {
          const parent = weuiDesktopDialog[p]
          const text = await parent.$eval('h3', async node => {
            return node.innerText
          })
          if (text === '提交审核') {
            const weuiDesktopBtn = await parent.$('.weui-desktop-btn')
            await weuiDesktopBtn.click()
            break
          }
        }
        // 延时 3500 毫秒,等待弹窗更新
        await page.waitForTimeout(3500)
        for (let p = 0; p < weuiDesktopDialog.length; p++) {
          const parent = weuiDesktopDialog[p]
          const text = await parent.$eval('h3', async node => node.innerText)
          if (text === '提交审核的相关须知') {
            const checkLabel = await parent.$('.weui-desktop-form__check-label')
            await checkLabel.click()
            await page.waitForTimeout(600)
            const mr = await parent.$('.mr')
            await mr.click()
            break
          }
        }
        const weuiDesktopDialogV2 = await page.$$('.weui-desktop-dialog')
        const newPagePromise = new Promise(resolve => browser.once('targetcreated', target => resolve(target.page())))
        let newPage = ''
        // 延时 3500 毫秒,等待弹窗更新
        await page.waitForTimeout(3500)
        for (let p = 0; p < weuiDesktopDialogV2.length; p++) {
          const parent = weuiDesktopDialogV2[p]
          const text = await parent.$eval('h3', async node => node.innerText)
          if (text === '代码提醒') {
            const btnPrimary = await parent.$('.weui-desktop-btn_primary')
            await btnPrimary.click()
            // 点击提交审核后页面有跳转,将当前page对象抓取为新页面对象
            newPage = await newPagePromise
            await page.close()
            break
          }
        }
        // 等待页面渲染完毕
        await newPage.waitForNavigation({
          waitUntil: 'networkidle0'
        })
        // 点击提交审核
        const btnPrimary = await newPage.$('.btn_primary')
        await btnPrimary.click()
        enameList.forEach(async ename => {
          await wxWorkNotification({content: '小程序提交审核成功', touser: ename})
        })
        await newPage.close()
        // 强制结束node 进程
        exit(0)
      } catch (e) {
        enameList.forEach(async ename => {
          await wxWorkNotification({content: '小程序自动提交审核失败, 请手动提交审核', touser: ename})
        })
        exit(0)
      }
    })()

    用 node ./ 文件名,的方式启动,以上代码并不能直接运行,需自己修改一些,仅本人记录使用

  • 相关阅读:
    Linux定时任务调度
    Linux组管理和权限管理
    Linux压缩和解压缩类指令
    leetcode:Compare Version Numbers
    leetcode:Valid Palindrome
    Majority Element
    Min Stack
    leetcode:Intersection of Two Linked Lists(两个链表的交叉点)
    leetcode:Factorial Trailing Zeroes
    leetcode:Rotate Array
  • 原文地址:https://www.cnblogs.com/SuperBrother/p/15688310.html
Copyright © 2011-2022 走看看