mirror of
https://github.com/electron-vite/electron-vite-vue
synced 2025-04-25 14:12:43 +08:00
374 lines
11 KiB
TypeScript
374 lines
11 KiB
TypeScript
import type { Page, Browser } from 'puppeteer'
|
|
import { browsers, clog, statusCheck } from './tools'
|
|
import { awaitWrap, browserAndPage, randomNum } from './tools'
|
|
|
|
const login = {
|
|
// poe 邮箱登录
|
|
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, proxy: true })
|
|
|
|
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')
|
|
|
|
log('开始输入邮箱')
|
|
await page.waitForSelector('input[type="email"]')
|
|
await page.type('input[type="email"]', options.user)
|
|
await page.waitForTimeout(1000)
|
|
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('开始输入密码')
|
|
|
|
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, changeUS: false })
|
|
|
|
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('开始登录')
|
|
|
|
/**
|
|
*
|
|
* @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('查找邮箱')
|
|
|
|
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) $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, changeUS: false })
|
|
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: 0 }),
|
|
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({ timeout: 0 }),
|
|
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, waitUntil: 'domcontentloaded' }),
|
|
page.keyboard.press('Enter')
|
|
])
|
|
log('登录成功')
|
|
resolve([page, browser])
|
|
|
|
return p
|
|
},
|
|
|
|
closeAll() {
|
|
browsers.map(b => b.close())
|
|
}
|
|
}
|
|
|
|
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')
|
|
}
|