From 836bf7393a27b0a3f193d6bf62503896b6c8aaed Mon Sep 17 00:00:00 2001 From: yema <1304119519@qq.com> Date: Thu, 15 Jun 2023 23:13:46 +0800 Subject: [PATCH] commit --- electron/main/gpt/getLink.ts | 4 +- electron/main/index.ts | 48 +++------ electron/main/login.ts | 132 +++++++++++++++++------ electron/main/poe/index.js | 20 ++-- electron/main/poe/link_7day.ts | 159 ++++++++++++++++++++++------ electron/main/tools.ts | 144 +++++++++++++++++++++++-- package.json | 2 + response.png | Bin 0 -> 29182 bytes src/App.vue | 185 ++++++++++++++------------------- src/components.d.ts | 4 + src/components/TheButton.vue | 30 ++++++ 11 files changed, 501 insertions(+), 227 deletions(-) create mode 100644 response.png create mode 100644 src/components/TheButton.vue diff --git a/electron/main/gpt/getLink.ts b/electron/main/gpt/getLink.ts index 2d14f80..57ef783 100644 --- a/electron/main/gpt/getLink.ts +++ b/electron/main/gpt/getLink.ts @@ -4,11 +4,11 @@ import login from "../login"; export async function getLink(options) { const log = clog(options) log('开始', { ident: 'gpt-link' }) - const [page, browser] = await login.chatgpt(options) + const [page, browser] = await login.chatgpt({ ...options, changeUS: false }) // await page.waitForTimeout(500) - await page.waitForSelector('body > div.absolute.inset-0') + await page.waitForSelector('body > div.absolute.inset-0', { timeout: 0 }) await page.evaluate(() => { const $mark = document.querySelector("body > div.absolute.inset-0") if ($mark) $mark.hidden = true diff --git a/electron/main/index.ts b/electron/main/index.ts index c8228cf..161275a 100644 --- a/electron/main/index.ts +++ b/electron/main/index.ts @@ -3,7 +3,22 @@ import { release } from 'node:os' import { join } from 'node:path' import './poe/index' import './gpt/index' -import { browsers } from './tools' +import { browsers, test1 } from './tools' + +import puppeteer from 'puppeteer-extra' +import StealthPlugin from 'puppeteer-extra-plugin-stealth' +puppeteer.use(StealthPlugin()) + + +// test1() +// puppeteer.launch({ +// headless: false, +// args: [ +// '--no-sandbox', +// '--disable-setuid-sandbox', +// '--proxy-server=socks5://127.0.0.1:40000' +// ] +// }) // The built directory structure // @@ -64,7 +79,7 @@ async function createWindow() { console.log('process.env.VITE_DEV_SERVER_URL', process.env.VITE_DEV_SERVER_URL); // Open devTool if the app is not packaged - win.webContents.openDevTools() + // win.webContents.openDevTools() } else { win.loadFile(indexHtml) } @@ -127,32 +142,3 @@ ipcMain.handle('stop', async (event, arg) => { browsers.forEach(browser => browser.close()) return true }) - - -fetch("https://poe.com/api/gql_POST", { - "headers": { - "accept": "*/*", - "accept-language": "zh-CN,zh;q=0.9", - "content-type": "application/json", - "poe-formkey": "520a133912dc68714f36a5bcf4848e59", - "poe-tag-id": "0bc8018cd51c5229e87987cf31f8f89c", - "poe-tchannel": "poe-chan49-8888-qcbwsgypbumznmwlcfwi", - "sec-ch-ua": "\"Not.A/Brand\";v=\"8\", \"Chromium\";v=\"114\", \"Google Chrome\";v=\"114\"", - "sec-ch-ua-mobile": "?0", - "sec-ch-ua-platform": "\"macOS\"", - "Cookie": "p-b=l9xRB8cUvzqnE5Wu0JoLCQ%3D%3D", - "sec-fetch-dest": "empty", - "sec-fetch-mode": "cors", - "sec-fetch-site": "same-origin" - }, - "referrer": "https://poe.com/zhenjie", - "referrerPolicy": "strict-origin-when-cross-origin", - "body": "{\"queryName\":\"chatHelpers_sendMessageMutation_Mutation\",\"variables\":{\"chatId\":15454343,\"bot\":\"zhenjie\",\"query\":\"hi\",\"source\":null,\"withChatBreak\":false,\"clientNonce\":\"eBAHfmO3h41BlXK0\",\"sdid\":\"36988d7a-8ed4-4eaa-bbf8-24782e5b5461\"},\"query\":\"mutation chatHelpers_sendMessageMutation_Mutation(\\n $chatId: BigInt!\\n $bot: String!\\n $query: String!\\n $source: MessageSource\\n $withChatBreak: Boolean!\\n $clientNonce: String\\n $sdid: String\\n) {\\n messageEdgeCreate(chatId: $chatId, bot: $bot, query: $query, source: $source, withChatBreak: $withChatBreak, clientNonce: $clientNonce, sdid: $sdid) {\\n chatBreak {\\n cursor\\n node {\\n id\\n messageId\\n text\\n author\\n suggestedReplies\\n creationTime\\n state\\n }\\n id\\n }\\n message {\\n cursor\\n node {\\n id\\n messageId\\n text\\n author\\n suggestedReplies\\n creationTime\\n state\\n clientNonce\\n contentType\\n chat {\\n shouldShowDisclaimer\\n id\\n }\\n }\\n id\\n }\\n bot {\\n id\\n messageLimit {\\n dailySent\\n }\\n }\\n status\\n }\\n}\\n\"}", - "method": "POST", - "mode": "cors", - "credentials": "include" -}).then(res => { - console.log('ok', res) -}).catch(err=> { - console.log('err', err) -}) diff --git a/electron/main/login.ts b/electron/main/login.ts index 1ef651e..e3b373b 100644 --- a/electron/main/login.ts +++ b/electron/main/login.ts @@ -1,16 +1,21 @@ -import { Page } from 'puppeteer' -import { browsers, clog, elCheck } from './tools' +import type { Page, Browser } from 'puppeteer' +import { browsers, clog, statusCheck } from './tools' import { awaitWrap, browserAndPage, randomNum } from './tools' -import { Browser } from 'puppeteer' const login = { // poe 邮箱登录 - async poe_email(options, getCodeFn: Function): Promise<[Page, Browser]> { + async poe_email(options, getCodeFn: Function, tryCount = 1): Promise<[Page, Browser]> { const log = clog(options) + if (tryCount > 2) { + log('重试次数已达上限') + throw '重试次数已达上限' + return + } + log('启动浏览器') - const { browser, page } = await browserAndPage(options) + const { browser, page } = await browserAndPage({ ...options, proxy: true }) log('正在进入登录页面') await page.goto('https://poe.com/login') @@ -30,11 +35,37 @@ const login = { await page.waitForSelector('input[type="email"]') await page.type('input[type="email"]', options.user) await page.waitForTimeout(1000) - // elCheck() - await page.keyboard.press('Enter') + await statusCheck( + async () => await page.keyboard.press('Enter'), + async () => await page.$('.LoadingDots_wrapper__lXyQd'), // LoadingDots_wrapper__lXyQd + ) + + // 检查是否有错误 + const isOk = await Promise.race([ + page.waitForSelector('.InfoText_error__OQwmg').then(() => false), + page.waitForSelector('input[class^="VerificationCodeInput_verificationCodeInput"]').then(() => true) + ]) + + console.log('isOk', isOk) + if (!isOk) { + const reason = await page.$eval('.InfoText_error__OQwmg', (el: HTMLElement) => el.textContent.trim()) + if (reason.startsWith('Something')) { + await page.waitForTimeout(3482) + await statusCheck( + async () => await page.keyboard.press('Enter'), + async () => await page.$('.LoadingDots_wrapper__lXyQd'), // LoadingDots_wrapper__lXyQd + ) + } else { + log('', { result: `登录失败: ${reason}` }) + browser.close() + throw '登录失败' + } + // return login.poe_email(options, getCodeFn, tryCount + 1) + } + + // await page.keyboard.press('Enter') log('开始输入密码') - await page.waitForSelector('input[class^="VerificationCodeInput_verificationCodeInput"]') const code = await getCodeFn(options, { page, browser }) await page.type('input[class^=VerificationCodeInput_verificationCodeInput]', code) @@ -185,52 +216,85 @@ const login = { await page.keyboard.press('Enter') log('开始登录') + /** + * + * @param reload 是否点击刷新验证码按钮 + */ async function validateCode() { log('开始获取code') let $iframe = await page.$('#thirdPartyFrame_home') let frame = await $iframe?.contentFrame() if (!frame) { + log('未找到页面,刷新重试中...') await page.reload() return await validateCode() } + const [err] = await awaitWrap(frame.waitForSelector('ul.inbox-container li', { timeout: 4000 })) + if (err) { + console.log(err) + console.log('有报错') + await frame.waitForSelector('.ico.sync') + const sync = await page.$('.ico.sync') + if (!sync) { + console.log('未找到刷新按钮') + log('未找到刷新按钮') + return '' + } + await frame.click('.ico.sync') + await frame.waitForTimeout(4000) + return await validate() + } + + return await validate() + + + // console.log('type', type) + // if (type === 'list') { + // return await validate() + // } + + await frame.waitForSelector('.ico.sync') await frame.click('.ico.sync') await frame.waitForTimeout(1000) await frame.waitForSelector('ul.inbox-container li') log('查找邮箱') - const $li = await frame.evaluate((emailText) => { - const $li: any = Array.from(document.querySelectorAll('ul.inbox-container li')).find($li => { - let sender = $li.querySelector('.sender')?.textContent || '' - return sender.includes(emailText) - }) - if ($li) $li.click() - return $li - }, emailText) + async function validate() { + const $li = await frame.evaluate((emailText) => { + const $li: any = Array.from(document.querySelectorAll('ul.inbox-container li')).find($li => { + let sender = $li.querySelector('.sender')?.textContent || '' + return sender.includes(emailText) + }) - if (!$li) { - log('未找到邮箱') - return '' - } else { - log('等待出现验证码 iframe') - await page.waitForSelector('#thirdPartyFrame_mail') - log('出现了验证码 iframe,寻找他的 iframe') - $iframe = await page.$('#thirdPartyFrame_mail') - frame = await $iframe?.contentFrame() + if ($li) $li.click() + return $li + }, emailText) - await frame.waitForSelector('iframe#mail-detail') - log('出现验证码 iframe') + if (!$li) { + log('未找到邮箱') + return '' + } else { + log('等待出现验证码 iframe') + await page.waitForSelector('#thirdPartyFrame_mail') + log('出现了验证码 iframe,寻找他的 iframe') + $iframe = await page.$('#thirdPartyFrame_mail') + frame = await $iframe?.contentFrame() - $iframe = await frame.$('iframe#mail-detail') - frame = await $iframe?.contentFrame() + await frame.waitForSelector('iframe#mail-detail') + log('出现验证码 iframe') - log('等待验证码') - await frame.waitForSelector('table table table ') - const code = (await frame.$eval('table table table tr:nth-of-type(5)', el => el.textContent)) || '' - return code.trim() + $iframe = await frame.$('iframe#mail-detail') + frame = await $iframe?.contentFrame() + + log('等待验证码') + await frame.waitForSelector('table table table ') + const code = (await frame.$eval('table table table tr:nth-of-type(5)', el => el.textContent)) || '' + return code.trim() + } } } @@ -286,7 +350,7 @@ const login = { log('已输入密码,开始登录') await Promise.all([ - page.waitForNavigation({ timeout: 10000 }), + page.waitForNavigation({ timeout: 10000, waitUntil: 'domcontentloaded' }), page.keyboard.press('Enter') ]) log('登录成功') diff --git a/electron/main/poe/index.js b/electron/main/poe/index.js index 34d383b..957f307 100644 --- a/electron/main/poe/index.js +++ b/electron/main/poe/index.js @@ -2,11 +2,7 @@ import { getLink } from './getLink' import { validate } from './validate' import { ipcMain } from 'electron' import { link_7day } from './link_7day' - -// import './openBrowser' -// suzzettedeanne2393@gmail.com----zebulonlawayne3013----zebulonlawayne4749@outlook.com -const text = ` -` +import { browserAndPage } from '../tools' export const parseAccount = text => text.split('\n').filter(Boolean).map(v => { v = v.split(/(——|-)+/).filter(v => !['-', '——'].includes(v)) @@ -18,7 +14,7 @@ ipcMain.handle('getLink', async (event, arg) => { const accounts = parseAccount(text) const links = [] - for(let i = 0; i < accounts.length; i++) { + for (let i = 0; i < accounts.length; i++) { const [user, pass, auxiliary] = accounts[i] const link = await getLink({ user, pass, auxiliary, index: i, id: user }) // .catch(err => { @@ -35,13 +31,13 @@ ipcMain.handle('getLink', async (event, arg) => { }) ipcMain.handle('get-poe-link-7day', async (event, arg) => { - const { text } = arg + const { text, liao } = arg const accounts = parseAccount(text) const links = [] - for(let i = 0; i < accounts.length; i++) { + for (let i = 0; i < accounts.length; i++) { const [user, pass, auxiliary] = accounts[i] - const link = await link_7day({ user, pass, auxiliary, index: i, id: user }) + const link = await link_7day({ user, pass, auxiliary, index: i, id: user, liao }) // .catch(err => { // console.log('error ->', err) // }) @@ -61,7 +57,7 @@ ipcMain.handle('poe-result', async (event, arg) => { const accounts = parseAccount(text) const links = [] - for(let i = 0; i < accounts.length; i++) { + for (let i = 0; i < accounts.length; i++) { const [user, pass, auxiliary] = accounts[i] const link = await validate({ user, pass, auxiliary, index: i, id: user }) // .catch(err => { @@ -76,3 +72,7 @@ ipcMain.handle('poe-result', async (event, arg) => { } return links }) + +ipcMain.handle('start-one-chrom', async (event, arg) => { + browserAndPage({ proxy: true }) +}) diff --git a/electron/main/poe/link_7day.ts b/electron/main/poe/link_7day.ts index 138f6bb..8c62a81 100644 --- a/electron/main/poe/link_7day.ts +++ b/electron/main/poe/link_7day.ts @@ -1,40 +1,31 @@ import type { Browser, Page } from 'puppeteer' import puppeteer from 'puppeteer-extra' import StealthPlugin from 'puppeteer-extra-plugin-stealth' -import { browserAndPage, clog, createPromise } from "../tools" +import { browserAndPage, browsers, clog, createPromise, statusCheck } from "../tools" import login from '../login' puppeteer.use(StealthPlugin()) export async function link_7day(options) { + console.log('options', options); const log = clog(options) log('开始', { ident: 'link_7day' }) - let { p, resolve, reject } = createPromise() - login.mail_get_code(options).then(([page, browser, options]) => { - if (options.code) { - resolve(options.code) - browser.close() - } else { - log('未获取验证码,重试一次', { ident: 'link_7day' }) - setTimeout(async () => { - const code = await options.validateCode() - if (code) { - browser.close() - resolve(code) - }else { - setTimeout(async () => { - const code = await options.validateCode() - if (code) { - browser.close() - resolve(code) - }else { - resolve('') - } - }, 3000); - } - }, 3000); - } + let { p, resolve, reject } = createPromise() + + login.mail_get_code({ ...options, changeUS: false }).then(async ([page, browser, options]) => { + const isOk = await statusCheck( + () => options.code, + async () => { + log('未获取验证码,重试一次', { ident: 'link_7day' }) + options.code = await options.validateCode() + return options.code + }, + { interval: 4000 } + ) + resolve(options.code) + browser.close() }) + const [page, browser] = await login.poe_email(options, async () => { const code = await p console.log('获取验证码结果', code) @@ -45,16 +36,102 @@ export async function link_7day(options) { } return code - }) + }).catch(() => '' as any) - await getLink(options, [page, browser]) + // 登录失败了 + if (!page) { + console.log('登录失败了') + browsers.map(b => b.close()) + return + } - browser.close() + const url = await getLink(options, [page, browser]) + + if (url && options.liao) { + await recharge({ ...options, page, browser }) + } + + // browser.close() // await page.waitForTimeout(2000) // browser.close() // const { page } = await login.poe_email(options) } +async function test() { + const url = 'https://checkout.stripe.com/c/pay/cs_live_a1SgJas9blPTFsRxVwdTA6Ox1mQxnfj4uDoF2yKUrO6ZjAnY7dXbo9qVsp#fidkdWxOYHwnPyd1blppbHNgWjxITDJsdEROY3Y1NjZpNTc8Q1RMU3ZTNicpJ2N3amhWYHdzYHcnP3F3cGApJ2lkfGpwcVF8dWAnPyd2bGtiaWBabHFgaCcpJ2BrZGdpYFVpZGZgbWppYWB3dic%2FcXdwYHgl' + const liao = { + "bank": "5445446852620225", + "cvc": "233", + "date": "07/25", + "name": "Miguel", + "address": "5615 E 127th Ave Apt c", + "city": "Tampa", + "postalCode": "33613", + "nation": "US" + } + const user = 'neletegcongder@mail.com' + + const { page, browser } = await browserAndPage() + await page.goto(url) + recharge({ browser, page, user, liao }) +} + +// test() + +async function recharge(options: { + browser: Browser, + page: Page, + user: string, + liao: any, +}) { + const { browser, page, liao, ...args } = options + const log = clog(args) + log('开始充值') + await page.waitForSelector('#cardNumber') + + await page.evaluate(() => { + const btn: HTMLElement = document.querySelector('.AddressAutocomplete-manual-entry .Link') + if (btn) btn.click() + }) + + await page.evaluate((email: string) => { + const el: HTMLInputElement = document.querySelector('#email') + if (el) el.value = email + }, options.user) + + await page.type('#cardNumber', liao.bank) + await page.type('#cardExpiry', liao.date) + await page.type('#cardCvc', liao.cvc) + await page.type('#billingName', liao.name) + await page.select('#billingCountry', liao.nation) + await page.type('#billingAddressLine1', liao.address) + await page.type('#billingLocality', liao.city) + await page.type('#billingPostalCode', liao.postalCode) + await page.waitForTimeout(1000) + await page.click('.SubmitButton-IconContainer') + + // await page.waitForTimeout(9000) + + // await page.waitForSelector('iframe') + // let $frame = await page.$('iframe') + // let frame = await $frame.contentFrame() + + // console.log('$frame', $frame) + // // console.log('frame', frame) + // await $frame.waitForSelector('iframe') + // $frame = await frame.$('iframe') + // frame = await $frame.contentFrame() + // await frame.waitForSelector('iframe') + // $frame = await frame.$('iframe') + // frame = await $frame.contentFrame() + + // await frame.waitForSelector('#checkbox', { timeout: 0 }) + // await frame.click('#checkbox') + // await page.waitForNavigation() + console.log('充值成功') + log('充值成功') +} + function existDialog(page: Page) { return page.evaluate((selector, searchText) => { const elements = Array.from(document.querySelectorAll(selector)); @@ -90,11 +167,29 @@ export async function getLink(options, [page, browser]: [Page, Browser]) { log('已经订阅') return } - await page.waitForSelector('[class*=SettingsSubscriptionSection_subscribeButton]') + await page.waitForSelector('[class*=SettingsSubscriptionSection_subscribeButton]', { timeout: 0 }) page.waitForTimeout(500) log('点击显示订阅套餐按钮') - await page.click('[class*=SettingsSubscriptionSection_subscribeButton]') + // await page.click('[class*=SettingsSubscriptionSection_subscribeButton]') + + const disabled = await page.$eval('[class*=SettingsSubscriptionSection_subscribeButton]', (el: HTMLButtonElement) => el.disabled) + if (disabled) { + log('订阅按钮不可用,地区不可用') + return + } + + await statusCheck( + async () => { + return page.evaluate(() => { + const $el = document.querySelector("[class*=SettingsSubscriptionSection_subscribeButton]") + console.log('$el', $el) + $el.click(); + }) + }, + // async () => page.click('[class*=SettingsSubscriptionSection_subscribeButton]'), + async () => page.$('.Modal_modal__SxITf'), + ) } // log('显示更多套餐') @@ -106,7 +201,7 @@ export async function getLink(options, [page, browser]: [Page, Browser]) { // 点击订阅 log('4, 开始点击订阅') - await page.waitForSelector('[class*=WebSubscriptionPaywall_button]') + await page.waitForSelector('[class*=WebSubscriptionPaywall_button]', { timeout: 0 }) page.click('[class*=WebSubscriptionPaywall_button]') const [response] = await Promise.all([ page.waitForNavigation({ waitUntil: 'domcontentloaded' }), diff --git a/electron/main/tools.ts b/electron/main/tools.ts index 32aaa70..3d8cf7c 100644 --- a/electron/main/tools.ts +++ b/electron/main/tools.ts @@ -1,9 +1,64 @@ import type { Page } from "puppeteer" import puppeteer from 'puppeteer-extra' import StealthPlugin from 'puppeteer-extra-plugin-stealth' +import RecaptchaPlugin from 'puppeteer-extra-plugin-recaptcha' import chromeLauncher from 'chrome-launcher' import { win } from './index' +import fakeUa from 'fake-useragent' +import axios from "axios" puppeteer.use(StealthPlugin()) +puppeteer.use(RecaptchaPlugin({ + provider: { + id: '2captcha', + token: '25bd4a3638f3836b0d119007cbc21954' + }, + visualFeedback: true +})) + + +export function test1() { + // puppeteer-extra is a drop-in replacement for puppeteer, + // it augments the installed puppeteer with plugin functionality + const puppeteer = require('puppeteer-extra') + + // add recaptcha plugin and provide it your 2captcha token (= their apiKey) + // 2captcha is the builtin solution provider but others would work as well. + // Please note: You need to add funds to your 2captcha account for this to work + const RecaptchaPlugin = require('puppeteer-extra-plugin-recaptcha') + puppeteer.use( + RecaptchaPlugin({ + provider: { + id: '2captcha', + token: '25bd4a3638f3836b0d119007cbc21954' // REPLACE THIS WITH YOUR OWN 2CAPTCHA API KEY ⚡ + }, + visualFeedback: true // colorize reCAPTCHAs (violet = detected, green = solved) + }) + ) + + // puppeteer usage as normal + puppeteer.launch({ headless: false }).then(async browser => { + const page = await browser.newPage() + await page.goto('https://www.google.com/recaptcha/api2/demo') + + // That's it, a single line of code to solve reCAPTCHAs 🎉 + const { + captchas, + filtered, + solutions, + solved, + error + } = await page.solveRecaptchas() + + console.log({ captchas, filtered, solutions, solved, error }) + + await Promise.all([ + page.waitForNavigation(), + page.click(`#recaptcha-demo-submit`) + ]) + await page.screenshot({ path: 'response.png', fullPage: true }) + await browser.close() + }) +} //生成从minNum到maxNum的随机数 export function randomNum (min, max) { @@ -31,16 +86,32 @@ export function pageRequest (page: Page) { export const browsers = [] -export async function browserAndPage (options = {}) { - const { request } = options +export async function browserAndPage (options: any = {}) { + const { request, changeUS = true, proxy = false } = options + + async function proxyCommand () { + // const proxy = (await axios.get('http://127.0.0.1:10101/api/get_ip_list?num=1&country=US&state=all&city=all&zip=all&isp=all&t=1&port=40000&ip_time=1')).data + console.log('proxy', proxy); + + // return proxy ? + return `--proxy-server=socks5://127.0.0.1:40000` + } + + const args = [ + '--no-sandbox', + '--disable-setuid-sandbox', + ] + + // proxy ? args.push(await proxyCommand()) : null + console.log(args, proxy); + + // proxy ? args.push(await proxyCommand()) : '' + const browser = await puppeteer.launch({ headless: false, - args: [ - '--no-sandbox', - '--disable-setuid-sandbox', - // `--proxy-server=http:// - ] + args }) + browsers.push(browser) const close = browser.close browser.close = async function () { @@ -50,6 +121,9 @@ export async function browserAndPage (options = {}) { } const page = await browser.newPage() + console.log('fakeUa', fakeUa()); + + changeUS && page.setUserAgent(fakeUa()) await page.setExtraHTTPHeaders({ 'accept-language': 'en-US,en;q=0.9,hy;q=0.8' }) @@ -59,13 +133,26 @@ export async function browserAndPage (options = {}) { return { browser, page } } +function getProxy () { + return axios({ + url: 'http://api.tianqiip.com/getip?secret=loy0r7fpmnlshm8l&num=1&type=json&port=3&time=5&mr=1&sign=5f73ab58ad7ab40346311014bef59b79', + method: 'get', + }).then(res => { + console.log('proxy', res.data.data[0]) + return res.data.data[0] + }).catch(err => { + console.log(err) + }) +} + + /** * 记录日志 */ export function clog(options) { return (info, data = {}) => { if (win) { - win.webContents.send('progress', { ...options, info, ...data }) + win?.webContents?.send?.('progress', { ...options, info, ...data }) } } } @@ -94,15 +181,25 @@ async function findElement (page: Page, selector: string, searchText: string) { /** * 元素检查,被点击或按下按键后,检查是否成功,不成功测重试或其他操作 */ -export async function elCheck(operationsFn: Function, checkFn: Function, tryCount = 1) { +export async function statusCheck( + operationsFn: Function, + checkFn: Function, + options: {interval?: number, tryCount?: number} = {} +) { + options.interval = options.interval ?? 1000 + options.tryCount = options.tryCount ?? 1 + let { interval, tryCount } = options const { p, resolve, reject } = createPromise() await operationsFn() const pass = await checkFn() + console.log('检查状态', !!pass) if (pass) { resolve(true) } else { - if (tryCount > 1) { - return await elCheck(operationsFn, checkFn, tryCount - 1) + if (tryCount <= 5) { + await sleep(interval) + options.tryCount++ + return await statusCheck(operationsFn, checkFn, options) } else { resolve(false) } @@ -110,3 +207,28 @@ export async function elCheck(operationsFn: Function, checkFn: Function, tryCoun return p } + +export function sleep (time = 1000) { + return new Promise((resolve) => { + setTimeout(resolve, time) + }) +} + +/** + * 将方法重试n次 + */ +export function retry(fn: Function, tryCount = 1) { + return async function (...args) { + try { + return await fn(...args) + } catch (error) { + if (tryCount <= 5) { + await sleep(1000) + tryCount++ + return await retry(fn, tryCount)(...args) + } else { + throw error + } + } + } +} diff --git a/package.json b/package.json index 2bb48a9..5024fa0 100644 --- a/package.json +++ b/package.json @@ -43,11 +43,13 @@ "@vueuse/core": "^10.1.2", "axios": "^1.4.0", "chrome-launcher": "^0.15.2", + "fake-useragent": "^1.0.1", "mockjs": "^1.1.0", "naive-ui": "^2.34.4", "proxy-chain": "^2.3.0", "puppeteer": "^13.3.2", "puppeteer-extra": "^3.3.6", + "puppeteer-extra-plugin-recaptcha": "^3.6.8", "puppeteer-extra-plugin-stealth": "^2.11.2", "sass": "^1.62.1", "socks-proxy-agent": "^8.0.1", diff --git a/response.png b/response.png new file mode 100644 index 0000000000000000000000000000000000000000..b7f193d068e294a761723dae973ce7d8aaa7664b GIT binary patch literal 29182 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 literal 0 HcmV?d00001 diff --git a/src/App.vue b/src/App.vue index 1537a05..c68f387 100644 --- a/src/App.vue +++ b/src/App.vue @@ -1,103 +1,31 @@