改造前

This commit is contained in:
yema 2023-06-13 21:39:23 +08:00
parent 7a5dfc0439
commit 87880184b5
17 changed files with 480 additions and 408 deletions

View File

@ -1,8 +1,9 @@
import type { Browser, Page } from 'puppeteer' import type { Browser, Page } from 'puppeteer'
import puppeteer from 'puppeteer-extra' import puppeteer from 'puppeteer-extra'
import StealthPlugin from 'puppeteer-extra-plugin-stealth' import StealthPlugin from 'puppeteer-extra-plugin-stealth'
import { clog } from "../poe/login"; import { clog } from "../tools";
import { awaitWrap, randomNum } from '../tools'; import { awaitWrap, randomNum } from '../tools';
import login from '../login'
import Mock from 'mockjs' import Mock from 'mockjs'
import axios from 'axios' import axios from 'axios'
import { SocksProxyAgent } from 'socks-proxy-agent' import { SocksProxyAgent } from 'socks-proxy-agent'
@ -37,98 +38,6 @@ function getProxy(options = {} as any) {
}) })
} }
// getProxy()//.then(res => console.log(res.data))
export const browsers = new Map<string, Browser>()
// 登录
async function login(options = {} as any): Promise<Page> {
const { user, pass } = options
const log = clog(options)
// const [pErr, proxy] = await awaitWrap(getProxy(options))
// if (pErr) {
// log('获取代理失败')
// return
// }
// // console.log('获取代理成功', proxy)
// // // const proxyUrl = await proxyChain.anonymizeProxy(`socks5://${proxy.ip}:${proxy.port}`);
// const proxyUrl = `socks5://${proxy.ip}:${proxy.port}`
// console.log('proxyUrl', proxyUrl)
// console.log(`curl --socks5 ${proxy.ip}:${proxy.port} https://jd.com`)
// // // const agent = new SocksProxyAgent(`socks5://${proxy.user}:${proxy.pass}@${proxy.ip}:${proxy.port}`);
// // // console.log('proxy', proxy)
log('启动浏览器')
const browser = await puppeteer.launch({
headless: false,
args: [
'--no-sandbox',
'--disable-setuid-sandbox',
// `--proxy-server=${proxyUrl}`,
]
})
log('创建新页面')
const page = await browser.newPage()
// await page.authenticate({
// username: proxy.user,
// password: proxy.pass
// })
browsers.set(user, browser)
// await page.setRequestInterception(true);
// page.on('request', (request) => {
// request.continue({
// agent
// });
// });
await page.setExtraHTTPHeaders({
'accept-language': 'en-US,en;q=0.9,hy;q=0.8'
})
// page.goto('https://ip.900cha.com/')
// return
// 进入
log('准备进入 gpt 登录')
await page.goto('https://platform.openai.com')
// const [err, res] = await awaitWrap(page.waitForNavigation({ timeout: 10000 }))
// if (err) throw err
log('等待出现输入框')
await page.waitForSelector('#username', { visible: true, timeout: 10000 })
// 输入账号
log('输入账号')
await page.type('#username', user)
await Promise.all([
page.waitForNavigation(),
page.keyboard.press('Enter')
])
log('等待出现密码输入框')
await page.waitForSelector('#password', { visible: true })
log('输入密码')
await page.type('#password', pass)
log('准备登录')
await Promise.all([
page.waitForNavigation({ timeout: 10000 }),
page.keyboard.press('Enter')
])
log('登录成功')
return page
}
// 获取组织id // 获取组织id
async function getOrgId(page: Page, options: any) { async function getOrgId(page: Page, options: any) {
const log = clog(options) const log = clog(options)
@ -228,7 +137,7 @@ export async function batchApplication(options) {
const log = clog(options) const log = clog(options)
log('开始', { ident: 'gpt-batch-4.0' }) log('开始', { ident: 'gpt-batch-4.0' })
const [error, page] = await awaitWrap(login(options)) const [error, [page, browser]] = await awaitWrap(login.openai(options))
if (error) return log('登录失败', { error, ident: 'gpt-batch-4.0' }) if (error) return log('登录失败', { error, ident: 'gpt-batch-4.0' })
await page.waitForSelector('.ovr-section') await page.waitForSelector('.ovr-section')
@ -238,4 +147,6 @@ export async function batchApplication(options) {
console.log('orgId', orgId) console.log('orgId', orgId)
await application(page, options) await application(page, options)
browser.close()
} }

View File

@ -1,10 +1,10 @@
import { clog } from "../poe/login"; import { clog } from "../tools";
import { login } from "./login"; import login from "../login";
export async function getLink(options) { export async function getLink(options) {
const log = clog(options) const log = clog(options)
log('开始', { ident: 'gpt-link' }) log('开始', { ident: 'gpt-link' })
const page = await login(options) const [page, browser] = await login.chatgpt(options)
// await page.waitForTimeout(500) // await page.waitForTimeout(500)
@ -36,6 +36,8 @@ export async function getLink(options) {
if (response.ok()) { if (response.ok()) {
const url = response._request._frame._url const url = response._request._frame._url
log('获取链接成功', { result: url, type: 'success' }) log('获取链接成功', { result: url, type: 'success' })
browser.close()
return url return url
} }
browser.close()
} }

View File

@ -1,8 +1,7 @@
import { ipcMain } from 'electron' import { ipcMain } from 'electron'
import { getLink } from './getLink' import { getLink } from './getLink'
import { validate } from './validate' import { validate } from './validate'
import { browser } from './login' import { batchApplication } from './batchApplication'
import { batchApplication, browsers } from './batchApplication'
const parseAccount = text => text.split('\n').filter(Boolean).map(v => { const parseAccount = text => text.split('\n').filter(Boolean).map(v => {
v = v.split(/(——|-)+/).filter(v => !['-', '——'].includes(v)) v = v.split(/(——|-)+/).filter(v => !['-', '——'].includes(v))
@ -24,7 +23,6 @@ ipcMain.handle('gpt-link', async (event, arg) => {
}) })
console.log('process', i, user, link) console.log('process', i, user, link)
} }
browser && browser.close()
}) })
ipcMain.handle('gpt-result', async (event, arg) => { ipcMain.handle('gpt-result', async (event, arg) => {
@ -86,5 +84,4 @@ export async function runActions(action: keyof typeof actions, options: any) {
}) })
console.log('process', i, user, link) console.log('process', i, user, link)
} }
browsers.forEach(browser => browser.close())
} }

View File

@ -1,100 +0,0 @@
import type { Browser, Page } from 'puppeteer'
import puppeteer from 'puppeteer-extra'
import StealthPlugin from 'puppeteer-extra-plugin-stealth'
import { randomNum } from '../tools'
import { win } from '../index'
import { clog } from '../poe/login'
puppeteer.use(StealthPlugin())
let id
export let browser: Browser | undefined
/**
* google
*/
export async function login(options, tryCount = 1): Promise<Page> {
let resolve, reject
const log = clog(options)
const p = new Promise((res, rej) => {
resolve = res
reject = rej
})
id = options.id
const env = {
GUSER: options.user,
GPASS: options.pass
}
if (browser) await browser.close()
browser = await puppeteer.launch({ headless: false })
const page = await browser.newPage()
await page.setExtraHTTPHeaders({
'accept-language': 'en-US,en;q=0.9,hy;q=0.8'
})
log('开始访问 gpt')
await page.goto('https://chat.openai.com/auth/login')
await page.waitForSelector('button')
// log('准备进入 google 登录页')
const [response] = await Promise.all([
page.waitForNavigation({ timeout: 10000 }),
page.click('button')
])
// log('已进入 google 登录页')
if (!response.ok()) return log('进入 google 登录页失败')
log('准备输入账号')
await page.type('#username', env.GUSER)
await Promise.all([
page.waitForNavigation(),
page.keyboard.press('Enter')
])
log('已输入账号,准备输入密码')
await page.waitForSelector('#password', { visible: true })
await page.type('#password', env.GPASS)
log('已输入密码,开始登录')
await Promise.all([
page.waitForNavigation({ timeout: 10000 }),
page.keyboard.press('Enter')
])
log('登录成功')
resolve(page)
// if (response.ok()) {
// await page.waitForSelector('input[type="email"]')
// log('准备输入账号')
// await page.type('input[type="email"]', env.GUSER)
// await Promise.all([
// page.waitForNavigation(),
// await page.keyboard.press('Enter')
// ])
// log('已输入账号,准备输入密码')
// await page.waitForSelector('input[type="password"]', { visible: true })
// await page.type('input[type="password"]', env.GPASS)
// log('已输入密码,开始登录')
// await Promise.all([
// page.waitForFunction(() => location.href === 'https://poe.com/'),
// await page.keyboard.press('Enter')
// ])
// log('登录成功,准备进入 poe')
// return page
// }
// if (tryCount < 4) {
// log(`google 登录失败,准备 ${tryCount} 次重试`)
// await page.close()
// return await loginGoogle(options, tryCount + 1)
// } else {
// log('google 登录失败,重试次数已达上限')
// reject('google 登录失败')
// }
return p
// return Promise.reject('google 登录失败')
}

View File

@ -1,10 +1,10 @@
import { clog } from "../poe/login"; import { clog } from "../tools";
import { login } from "./login"; import login from "../login";
export async function validate(options) { export async function validate(options) {
const log = clog(options) const log = clog(options)
log('开始', { ident: 'gpt-validate' }) log('开始', { ident: 'gpt-validate' })
const page = await login(options) const [page, browser] = await login.chatgpt(options)
await page.waitForSelector('body > div.absolute.inset-0') await page.waitForSelector('body > div.absolute.inset-0')
await page.evaluate(() => { await page.evaluate(() => {
@ -24,4 +24,5 @@ export async function validate(options) {
log('获取链接成功', { result: isSuccess ? '充值成功😘' : '充值失败😭', type: isSuccess ? 'success' : 'fail' }) log('获取链接成功', { result: isSuccess ? '充值成功😘' : '充值失败😭', type: isSuccess ? 'success' : 'fail' })
console.log(isSuccess) console.log(isSuccess)
browser.close()
} }

View File

@ -3,9 +3,7 @@ import { release } from 'node:os'
import { join } from 'node:path' import { join } from 'node:path'
import './poe/index' import './poe/index'
import './gpt/index' import './gpt/index'
import { browser as poeBrowser } from './poe/login' import { browsers } from './tools'
import { browser as gptBrowser } from './gpt/login'
import { browsers } from './gpt/batchApplication'
// The built directory structure // The built directory structure
// //
@ -126,8 +124,6 @@ ipcMain.handle('open-win', (_, arg) => {
}) })
ipcMain.handle('stop', async (event, arg) => { ipcMain.handle('stop', async (event, arg) => {
poeBrowser && poeBrowser.close()
gptBrowser && gptBrowser.close()
browsers.forEach(browser => browser.close()) browsers.forEach(browser => browser.close())
return true return true
}) })

View File

@ -1,14 +1,16 @@
import { clog } from './poe/login' import { Page } from 'puppeteer'
import { browserAndPage } from './tools' import { browsers, clog, elCheck } from './tools'
import { awaitWrap, browserAndPage, randomNum } from './tools'
import { Browser } from 'puppeteer'
const login = { const login = {
// poe 邮箱登录 // poe 邮箱登录
async poe_email(options) { async poe_email(options, getCodeFn: Function): Promise<[Page, Browser]> {
const log = clog(options) const log = clog(options)
log('启动浏览器') log('启动浏览器')
const { page } = await browserAndPage(options) const { browser, page } = await browserAndPage(options)
log('正在进入登录页面') log('正在进入登录页面')
await page.goto('https://poe.com/login') await page.goto('https://poe.com/login')
@ -27,9 +29,281 @@ const login = {
log('开始输入邮箱') log('开始输入邮箱')
await page.waitForSelector('input[type="email"]') await page.waitForSelector('input[type="email"]')
await page.type('input[type="email"]', options.user) await page.type('input[type="email"]', options.user)
await page.waitForTimeout(1000)
// elCheck()
await page.keyboard.press('Enter') await page.keyboard.press('Enter')
log('开始输入密码') log('开始输入密码')
await page.waitForSelector('input[class^="VerificationCodeInput_verificationCodeInput"]')
const code = await getCodeFn(options, { page, browser })
await page.type('input[class^=VerificationCodeInput_verificationCodeInput]', code)
await page.keyboard.press('Enter')
await page.waitForNavigation()
return [page, browser]
},
async poe_google(options, tryCount = 1): Promise<[Page, Browser]> {
let resolve: (value: [Page, Browser] | PromiseLike<[Page, Browser]>) => void,
reject
const log = clog(options)
const p = new Promise<[Page, Browser]>((res, rej) => {
resolve = res
reject = rej
})
const env = {
GUSER: options.user,
GPASS: options.pass
}
const { browser, page } = await browserAndPage(options)
log('开始访问 poe')
await page.goto('https://poe.com')
log('已进入 poe')
await page.waitForTimeout(randomNum(1000, 2600))
log('准备进入 google 登录页')
page.click('.ContinueWithGoogleButton_buttonContentWrapper__Mrp0W')
const [err, response] = await awaitWrap(page.waitForNavigation({ timeout: 10000 }))
if (err) {
reject({ text: '登录报错', try: true })
return p
}
log('已进入 google 登录页')
if (response.ok()) {
await page.waitForSelector('input[type="email"]')
log('准备输入账号')
await page.type('input[type="email"]', env.GUSER)
await Promise.all([
page.waitForNavigation(),
await page.keyboard.press('Enter')
])
log('已输入账号,准备输入密码')
if (await isError(page)) {
reject({ text: '登录报错', try: true })
return p
}
await page.waitForSelector('input[type="password"]', { visible: true })
await page.type('input[type="password"]', env.GPASS)
log('已输入密码,开始登录')
await Promise.all([
page.waitForFunction(() => location.href === 'https://poe.com/'),
await page.keyboard.press('Enter')
])
if (await isError(page)) {
reject({ text: '登录报错', try: true })
return p
}
log('登录成功,准备进入 poe')
resolve([page, browser])
return p
}
if (tryCount < 4) {
log(`google 登录失败,准备 ${tryCount} 次重试`)
await page.close()
return await login.poe_google(options, tryCount + 1)
} else {
log('google 登录失败,重试次数已达上限')
reject('google 登录失败')
}
return p
},
async openai(options): Promise<[Page, Browser]> {
const { user, pass } = options
const log = clog(options)
log('启动浏览器')
const { browser, page } = await browserAndPage(options)
log('准备进入 gpt 登录')
await page.goto('https://platform.openai.com')
log('等待出现输入框')
await page.waitForSelector('#username', { visible: true, timeout: 10000 })
// 输入账号
log('输入账号')
await page.type('#username', user)
await Promise.all([
page.waitForNavigation(),
page.keyboard.press('Enter')
])
log('等待出现密码输入框')
await page.waitForSelector('#password', { visible: true })
log('输入密码')
await page.type('#password', pass)
log('准备登录')
await Promise.all([
page.waitForNavigation({ timeout: 10000 }),
page.keyboard.press('Enter')
])
log('登录成功')
return [page, browser]
},
/**
*
*/
async mail_get_code(options): Promise<[Page, Browser, {
code?: string,
validateCode: () => Promise<string>
}]> {
const { emailText = 'Poe' } = options
const log = clog(options)
const { browser, page } = await browserAndPage({ ...options })
log('准备进入邮箱登录页')
const [error] = await awaitWrap(page.goto('https://www.mail.com/', { waitUntil: 'domcontentloaded' }))
await page.waitForSelector('.header-bar .button-login')
await page.click('.header-bar .button-login')
log('输入帐密')
await page.waitForTimeout(500)
await page.waitForSelector('input#login-email')
await page.waitForTimeout(500)
await page.type('input#login-email', options.user)
await page.type('input#login-password', options.pass)
await page.keyboard.press('Enter')
log('开始登录')
async function validateCode() {
log('开始获取code')
let $iframe = await page.$('#thirdPartyFrame_home')
let frame = await $iframe?.contentFrame()
if (!frame) {
await page.reload()
return await validateCode()
}
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)
if (!$li) {
log('未找到邮箱')
return ''
} else {
log('等待出现验证码 iframe')
await page.waitForSelector('#thirdPartyFrame_mail')
log('出现了验证码 iframe,寻找他的 iframe')
$iframe = await page.$('#thirdPartyFrame_mail')
frame = await $iframe?.contentFrame()
await frame.waitForSelector('iframe#mail-detail')
log('出现验证码 iframe')
$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()
}
}
await awaitWrap(page.waitForNavigation({ waitUntil: 'load' }))
const code = await validateCode()
log(`邮箱验证码 ${code}`)
return [page, browser, { code, validateCode }]
},
async chatgpt(options, tryCount = 1): Promise<[Page, Browser]> {
let resolve: (value: [Page, Browser] | PromiseLike<[Page, Browser]>) => void,
reject
const log = clog(options)
const p = new Promise<[Page, Browser]>((res, rej) => {
resolve = res
reject = rej
})
const env = {
GUSER: options.user,
GPASS: options.pass
}
const { browser, page } = await browserAndPage(options)
log('开始访问 gpt')
await page.goto('https://chat.openai.com/auth/login')
await page.waitForSelector('button')
// log('准备进入 google 登录页')
const [response] = await Promise.all([
page.waitForNavigation({ timeout: 10000 }),
page.click('button')
])
// log('已进入 google 登录页')
if (!response.ok()) {
log('进入 google 登录页失败')
reject('进入 google 登录页失败')
return p
}
log('准备输入账号')
await page.type('#username', env.GUSER)
await Promise.all([
page.waitForNavigation(),
page.keyboard.press('Enter')
])
log('已输入账号,准备输入密码')
await page.waitForSelector('#password', { visible: true })
await page.type('#password', env.GPASS)
log('已输入密码,开始登录')
await Promise.all([
page.waitForNavigation({ timeout: 10000 }),
page.keyboard.press('Enter')
])
log('登录成功')
resolve([page, browser])
return p
},
closeAll() {
browsers.map(b => b.close())
} }
} }
export default login export default login
async function isError(page: Page) {
const text = await page.evaluate(() => (document.querySelector('p')?.textContent || ''));
// const text = await page.evaluate('p', element => element.textContent);
return text && text.includes('error')
}

View File

@ -1,8 +1,7 @@
import { clog, loginGoogle } from './login' import { clog } from '../tools'
import type { Browser, Page } from 'puppeteer' import type { Page } from 'puppeteer'
import { readFileSync, writeFileSync } from 'fs'
import path from 'path' import path from 'path'
import { EOL } from 'os' import login from '../login'
function existDialog(page: Page) { function existDialog(page: Page) {
return page.evaluate((selector, searchText) => { return page.evaluate((selector, searchText) => {
@ -17,7 +16,7 @@ function existDialog(page: Page) {
export async function getLink(options) { export async function getLink(options) {
const log = clog(options) const log = clog(options)
log('开始', { ident: 'poe-link' }) log('开始', { ident: 'poe-link' })
return loginGoogle(options).then(async (page: Page) => { return login.poe_google(options).then(async ([page, browser]) => {
await page.waitForTimeout(1000) await page.waitForTimeout(1000)
const isExistDialog = await existDialog(page) const isExistDialog = await existDialog(page)
@ -51,14 +50,10 @@ export async function getLink(options) {
if (response.ok()) { if (response.ok()) {
const url = response._request._frame._url const url = response._request._frame._url
log('获取链接成功', { result: url, type: 'success' }) log('获取链接成功', { result: url, type: 'success' })
browser.close()
return url return url
// if (options.index === 0) {
// writeFileSync(resolve('./hao.txt'), '', 'utf8')
// }
// const fileContent = readFileSync(resolve('./hao.txt'), 'utf8')
// writeFileSync(resolve('./hao.txt'), fileContent + `${EOL}${options.index + 1} ${options.user}${EOL}${url}`, 'utf8')
} }
browser.close()
}).catch(error => { }).catch(error => {
console.log('error ->', error.try, error.text, error) console.log('error ->', error.try, error.text, error)
if (error?.try) { if (error?.try) {

View File

@ -1,7 +1,6 @@
import { getLink } from './getLink' import { getLink } from './getLink'
import { validate } from './validate' import { validate } from './validate'
import { ipcMain } from 'electron' import { ipcMain } from 'electron'
import { browser } from './login'
import { link_7day } from './link_7day' import { link_7day } from './link_7day'
// import './openBrowser' // import './openBrowser'
@ -32,7 +31,6 @@ ipcMain.handle('getLink', async (event, arg) => {
}) })
console.log('process', i, user, link) console.log('process', i, user, link)
} }
browser && browser.close()
return links return links
}) })
@ -54,7 +52,6 @@ ipcMain.handle('get-poe-link-7day', async (event, arg) => {
}) })
console.log('process', i, user, link) console.log('process', i, user, link)
} }
// browser && browser.close()
return links return links
}) })
@ -77,6 +74,5 @@ ipcMain.handle('poe-result', async (event, arg) => {
}) })
console.log('process', i, user, link) console.log('process', i, user, link)
} }
browser && browser.close()
return links return links
}) })

View File

@ -1,50 +1,120 @@
import type { Browser, Page } from 'puppeteer' import type { Browser, Page } from 'puppeteer'
import puppeteer from 'puppeteer-extra' import puppeteer from 'puppeteer-extra'
import StealthPlugin from 'puppeteer-extra-plugin-stealth' import StealthPlugin from 'puppeteer-extra-plugin-stealth'
import { clog } from "./login" import { browserAndPage, clog, createPromise } from "../tools"
import login from '../login'
puppeteer.use(StealthPlugin()) puppeteer.use(StealthPlugin())
async function login (options) { export async function link_7day(options) {
const log = clog(options)
log('启动浏览器')
const browser = await puppeteer.launch({
headless: false,
args: [
'--no-sandbox',
'--disable-setuid-sandbox',
// `--proxy-server=http://192.168.1.80:7890`,
]
})
const page = await browser.newPage()
await page.setExtraHTTPHeaders({
'accept-language': 'en-US,en;q=0.9,hy;q=0.8'
})
log('正在进入登录页面')
await page.goto('https://poe.com/login')
log('设置登录方式')
await page.evaluate((selector, searchText) => {
const elements = Array.from(document.querySelectorAll(selector));
const target = elements.find(el => el.textContent.trim() === searchText);
if (!target) return false
const text = target.nextElementSibling?.textContent || ''
if (text.includes('email')) target.nextElementSibling.click()
}, 'button', 'Go')
await page.waitForSelector('input[type="email"]')
await page.type('input[type="email"]', options.user)
await page.keyboard.press('Enter')
}
export async function link_7day (options) {
const log = clog(options) const log = clog(options)
log('开始', { ident: 'link_7day' }) log('开始', { ident: 'link_7day' })
await login(options)
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);
}
})
const [page, browser] = await login.poe_email(options, async () => {
const code = await p
console.log('获取验证码结果', code)
if (!code) {
log('获取验证码失败', { ident: 'link_7day' })
reject('获取验证码失败')
throw '获取验证码失败'
}
return code
})
await getLink(options, [page, browser])
browser.close()
// await page.waitForTimeout(2000)
// browser.close()
// const { page } = await login.poe_email(options)
}
function existDialog(page: Page) {
return page.evaluate((selector, searchText) => {
const elements = Array.from(document.querySelectorAll(selector));
const target = elements.find(el => el.textContent.trim() === searchText);
target && target.click()
return !!target
}, 'button', 'Start free trial')
}
export async function getLink(options, [page, browser]: [Page, Browser]) {
const log = clog(options)
log('开始', { ident: 'poe-link' })
await page.waitForTimeout(1000)
const isExistDialog = await existDialog(page)
isExistDialog && log('检测到充值弹窗,无需前往设置页')
if (!isExistDialog) {
await Promise.all([
page.waitForNavigation(),
page.goto('https://poe.com/settings')
])
log('已进入设置页面, 检查中')
const existMange = await page.evaluate(() => {
const mange = document.querySelector('[class*="SettingsSubscriptionSection_manageSubscription"]')
if (mange) return true
return false
})
if (existMange) {
log('已经订阅')
return
}
await page.waitForSelector('[class*=SettingsSubscriptionSection_subscribeButton]')
page.waitForTimeout(500)
log('点击显示订阅套餐按钮')
await page.click('[class*=SettingsSubscriptionSection_subscribeButton]')
}
// log('显示更多套餐')
// await page.waitForSelector('[class*=WebSubscriptionFreeTrial_viewAllPlansButton]')
// await page.click('[class*=WebSubscriptionFreeTrial_viewAllPlansButton]')
// log('点击最后一个套餐')
// await page.waitForSelector('[class*=WebSubscriptionPaywall_plans]')
// await page.click('[class*=WebSubscriptionPaywall_plans] > button:last-child')
// 点击订阅
log('4, 开始点击订阅')
await page.waitForSelector('[class*=WebSubscriptionPaywall_button]')
page.click('[class*=WebSubscriptionPaywall_button]')
const [response] = await Promise.all([
page.waitForNavigation({ waitUntil: 'domcontentloaded' }),
])
if (response.ok()) {
const url = response._request._frame._url
log('获取链接成功', { result: url, type: 'success' })
return url
}
} }

View File

@ -1,107 +0,0 @@
import type { Browser, Page } from 'puppeteer'
import puppeteer from 'puppeteer-extra'
import StealthPlugin from 'puppeteer-extra-plugin-stealth'
import { randomNum, awaitWrap } from '../tools'
import { win } from '../index'
puppeteer.use(StealthPlugin())
let id
export let browser: Browser
/**
* google
*/
export async function loginGoogle(options, tryCount = 1) {
let resolve, reject
const log = clog(options)
const p = new Promise((res, rej) => {
resolve = res
reject = rej
})
id = options.id
const env = {
GUSER: options.user,
GPASS: options.pass
}
if (browser) await browser.close()
browser = await puppeteer.launch({ headless: false })
const page = await browser.newPage()
await page.setExtraHTTPHeaders({
'accept-language': 'en-US,en;q=0.9,hy;q=0.8'
})
log('开始访问 poe')
await page.goto('https://poe.com')
log('已进入 poe')
await page.waitForTimeout(randomNum(1000, 2600))
log('准备进入 google 登录页')
page.click('.ContinueWithGoogleButton_buttonContentWrapper__Mrp0W')
const [err, response] = await awaitWrap(page.waitForNavigation({ timeout: 10000 }))
if (err) {
reject({ text: '登录报错', try: true })
return p
}
log('已进入 google 登录页')
if (response.ok()) {
await page.waitForSelector('input[type="email"]')
log('准备输入账号')
await page.type('input[type="email"]', env.GUSER)
await Promise.all([
page.waitForNavigation(),
await page.keyboard.press('Enter')
])
log('已输入账号,准备输入密码')
if (await isError(page)) {
reject({ text: '登录报错', try: true })
return p
}
await page.waitForSelector('input[type="password"]', { visible: true })
await page.type('input[type="password"]', env.GPASS)
log('已输入密码,开始登录')
await Promise.all([
page.waitForFunction(() => location.href === 'https://poe.com/'),
await page.keyboard.press('Enter')
])
if (await isError(page)) {
reject({ text: '登录报错', try: true })
return p
}
log('登录成功,准备进入 poe')
return page
}
if (tryCount < 4) {
log(`google 登录失败,准备 ${tryCount} 次重试`)
await page.close()
return await loginGoogle(options, tryCount + 1)
} else {
log('google 登录失败,重试次数已达上限')
reject('google 登录失败')
}
return p
// return Promise.reject('google 登录失败')
}
async function isError(page: Page) {
const text = await page.evaluate(() => (document.querySelector('p')?.textContent || ''));
// const text = await page.evaluate('p', element => element.textContent);
return text && text.includes('error')
}
export function clog(options) {
return (info, data = {}) => {
if (win) {
win.webContents.send('progress', { ...options, info, ...data })
}
}
}

View File

@ -1,8 +0,0 @@
import puppeteer from 'puppeteer-extra'
import StealthPlugin from 'puppeteer-extra-plugin-stealth'
puppeteer.use(StealthPlugin())
;(async () => {
const browser = await puppeteer.launch({ headless: false })
browser.newPage()
})()

View File

@ -1,12 +1,11 @@
import { clog, loginGoogle } from './login' import login from '../login'
import { readFileSync, writeFileSync } from 'fs'
import path from 'path' import path from 'path'
import { EOL } from 'os' import { clog } from '../tools'
export async function validate (options) { export async function validate (options) {
const log = clog(options) const log = clog(options)
log('开始', { ident: 'poe-validate' }) log('开始', { ident: 'poe-validate' })
const page = await loginGoogle(options) const [page, browser] = await login.poe_google(options)
await Promise.all([ await Promise.all([
page.waitForNavigation(), page.waitForNavigation(),
@ -16,22 +15,10 @@ export async function validate (options) {
log('已进入设置页面, 检查中', { ident: 'poe-validate' }) log('已进入设置页面, 检查中', { ident: 'poe-validate' })
const length = await page.$$eval('.SettingsSubscriptionSection_botLimitSection__j4mSO > div:first-child > div', (doms) => doms.length) const length = await page.$$eval('.SettingsSubscriptionSection_botLimitSection__j4mSO > div:first-child > div', (doms) => doms.length)
// page.close()
// if (options.index === 0) {
// writeFileSync(resolve('./validate.txt'), '', 'utf8')
// }
// const fileContent = readFileSync(resolve('./validate.txt'), 'utf8')
const resultTxt = length === 1 ? '失败😭' : '成功😘' const resultTxt = length === 1 ? '失败😭' : '成功😘'
// writeFileSync(resolve('./validate.txt'), fileContent + `${options.index + 1} ${options.user}----${resultTxt}${EOL}`, 'utf8')
log(resultTxt, { type: length === 1 ? 'fail' : 'success', result: length === 1 ? '失败😭' : '成功😘' }) log(resultTxt, { type: length === 1 ? 'fail' : 'success', result: length === 1 ? '失败😭' : '成功😘' })
// // 不成功
// if (length === 1) {
// } else { browser.close()
// log('充值成功😘')
// }
} }
function resolve (url) { function resolve (url) {

View File

@ -1,6 +1,8 @@
import type { Page } from "puppeteer" import type { Page } from "puppeteer"
import puppeteer from 'puppeteer-extra' import puppeteer from 'puppeteer-extra'
import StealthPlugin from 'puppeteer-extra-plugin-stealth' import StealthPlugin from 'puppeteer-extra-plugin-stealth'
import chromeLauncher from 'chrome-launcher'
import { win } from './index'
puppeteer.use(StealthPlugin()) puppeteer.use(StealthPlugin())
//生成从minNum到maxNum的随机数 //生成从minNum到maxNum的随机数
@ -17,6 +19,7 @@ export function awaitWrap<T, U = any>(promise: Promise<T>): Promise<[U | null, T
// 设置页面请求 // 设置页面请求
export function pageRequest (page: Page) { export function pageRequest (page: Page) {
page.setRequestInterception(true)
page.on('request', (request) => { page.on('request', (request) => {
if (['stylesheet', 'font'].indexOf(request.resourceType()) !== -1) { if (['stylesheet', 'font'].indexOf(request.resourceType()) !== -1) {
request.abort() request.abort()
@ -26,9 +29,10 @@ export function pageRequest (page: Page) {
}) })
} }
const browsers = [] export const browsers = []
export async function browserAndPage (options) { export async function browserAndPage (options = {}) {
const { request } = options
const browser = await puppeteer.launch({ const browser = await puppeteer.launch({
headless: false, headless: false,
args: [ args: [
@ -37,10 +41,11 @@ export async function browserAndPage (options) {
// `--proxy-server=http:// // `--proxy-server=http://
] ]
}) })
browsers.push(browser)
const close = browser.close const close = browser.close
browser.close = async () => { browser.close = async function () {
let i = browsers.find(b => b === browser) let i = browsers.find(b => b === browser)
await close() await close.call(this)
if (i !== -1) browsers.slice(i, 1) if (i !== -1) browsers.slice(i, 1)
} }
@ -49,7 +54,59 @@ export async function browserAndPage (options) {
'accept-language': 'en-US,en;q=0.9,hy;q=0.8' 'accept-language': 'en-US,en;q=0.9,hy;q=0.8'
}) })
pageRequest(page) if (request) pageRequest(page)
return { browser, page } return { browser, page }
} }
/**
*
*/
export function clog(options) {
return (info, data = {}) => {
if (win) {
win.webContents.send('progress', { ...options, info, ...data })
}
}
}
/**
* promise
*/
export function createPromise<T> () {
let resolve: (value: T | PromiseLike<T>) => void,
reject
const p = new Promise<T>((res, rej) => {
resolve = res
reject = rej
})
return { resolve, reject, p }
}
async function findElement (page: Page, selector: string, searchText: string) {
return page.evaluate((selector, searchText) => {
const elements = Array.from(document.querySelectorAll(selector));
const target = elements.find(el => el.textContent.trim() === searchText);
return target
}, selector, searchText)
}
/**
*
*/
export async function elCheck(operationsFn: Function, checkFn: Function, tryCount = 1) {
const { p, resolve, reject } = createPromise<boolean>()
await operationsFn()
const pass = await checkFn()
if (pass) {
resolve(true)
} else {
if (tryCount > 1) {
return await elCheck(operationsFn, checkFn, tryCount - 1)
} else {
resolve(false)
}
}
return p
}

View File

@ -42,6 +42,7 @@
"dependencies": { "dependencies": {
"@vueuse/core": "^10.1.2", "@vueuse/core": "^10.1.2",
"axios": "^1.4.0", "axios": "^1.4.0",
"chrome-launcher": "^0.15.2",
"mockjs": "^1.1.0", "mockjs": "^1.1.0",
"naive-ui": "^2.34.4", "naive-ui": "^2.34.4",
"proxy-chain": "^2.3.0", "proxy-chain": "^2.3.0",

View File

@ -2,7 +2,7 @@
import { ipcRenderer } from 'electron' import { ipcRenderer } from 'electron'
import { NButton } from 'naive-ui' import { NButton } from 'naive-ui'
import { useClipboard } from '@vueuse/core' import { useClipboard } from '@vueuse/core'
const input = ref('r0tg74y71ophdadi2r@newgmail.icu----7rtupH27r') const input = ref('pollcribracacom@mail.com-----XAxeEgy34j')
// const input = ref('126vdsjmgyanpgqrvb@ddmvp.icu----EOJ2NgPfS') // const input = ref('126vdsjmgyanpgqrvb@ddmvp.icu----EOJ2NgPfS')
// const input = ref('traceetakashi6274@gmail.com----kedaraditi0214----kedaraditi4760@hotmail.com') // const input = ref('traceetakashi6274@gmail.com----kedaraditi0214----kedaraditi4760@hotmail.com')