以下代码主要功能为 爬取 微信小程序开发者平台页面,实现登录,发送二维码,点击版本管理等点击操作
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 ./ 文件名,的方式启动,以上代码并不能直接运行,需自己修改一些,仅本人记录使用