diff --git a/main/index.mjs b/main/index.mjs index ab24f6f..177da42 100644 --- a/main/index.mjs +++ b/main/index.mjs @@ -50,7 +50,7 @@ async function mainLoop () { const recommendJobLink = (await page.$('[ka=header-job-recommend]')) await recommendJobLink.click() - while (true) { + afterPageLoad: while (true) { await sleepWithRandomDelay(3000) const expectJobList = (await page.evaluate(` @@ -75,134 +75,146 @@ async function mainLoop () { ); await sleepWithRandomDelay(2000) - const { targetJobElProxy, targetJobIndex } = await new Promise(async (resolve, reject) => { - // job list - const recommendJobListElProxy = await page.$('.job-list-container .rec-job-list') - - let jobListData = await page.evaluate( - ` - document.querySelector('.job-recommend-main')?.__vue__?.jobList - ` - ) - let targetJobIndex = jobListData.findIndex(it => [...expectCompanySet].find(name => it.brandName.includes(name))) - let hasReachLastPage = false - - while (targetJobIndex < 0 && !hasReachLastPage) { - // fetch new - const recommendJobListElBBox = await recommendJobListElProxy.boundingBox() - const windowInnerHeight = await page.evaluate('window.innerHeight') - await page.mouse.move( - recommendJobListElBBox.x + recommendJobListElBBox.width / 2, - windowInnerHeight / 2 - ) - let scrolledHeight = 0 - const targetHeight = 3000 - const increase = 40 + Math.floor(30 * Math.random()) - while (scrolledHeight < targetHeight) { - scrolledHeight += increase - await page.mouse.wheel({deltaY: increase}); - await sleep(1) - } - hasReachLastPage = await page.evaluate(` - !(document.querySelector('.job-recommend-main')?.__vue__?.hasMore) - `) - if (hasReachLastPage) { - console.log(`Arrive the terminal of the job list.`) - } - - await sleep(3000) - jobListData = await page.evaluate( + try { + const { targetJobElProxy, targetJobIndex } = await new Promise(async (resolve, reject) => { + // job list + const recommendJobListElProxy = await page.$('.job-list-container .rec-job-list') + + let jobListData = await page.evaluate( ` document.querySelector('.job-recommend-main')?.__vue__?.jobList ` ) - targetJobIndex = targetJobIndex = jobListData.findIndex(it => [...expectCompanySet].find(name => it.brandName.includes(name))) - } - - if (targetJobIndex < 0 && hasReachLastPage) { - // has reach last page and not find target job - reject(new Error('CANNOT_FIND_EXCEPT_JOB')) - return - } - - const recommendJobItemList = await recommendJobListElProxy.$$('ul.rec-job-list > li') - resolve( - { - targetJobElProxy: recommendJobItemList[targetJobIndex], - targetJobIndex - } - ) - }) - if (targetJobIndex > 0) { - // scroll that target element into view - await page.evaluate(` - const targetEl = document.querySelector("ul.rec-job-list").children[${targetJobIndex}] - targetEl.scrollIntoView({ - behavior: 'smooth', - block: ${Math.random() > 0.5 ? '\'center\'' : '\'end\''} - }) - `) + let targetJobIndex = jobListData.findIndex(it => [...expectCompanySet].find(name => it.brandName.includes(name))) + let hasReachLastPage = false - await sleepWithRandomDelay(200) - - // click that element - await targetJobElProxy.click() - await page.waitForResponse( - response => { - if ( - response.url().startsWith('https://www.zhipin.com/wapi/zpgeek/job/detail.json') - ) { - return true + while (targetJobIndex < 0 && !hasReachLastPage) { + // fetch new + const recommendJobListElBBox = await recommendJobListElProxy.boundingBox() + const windowInnerHeight = await page.evaluate('window.innerHeight') + await page.mouse.move( + recommendJobListElBBox.x + recommendJobListElBBox.width / 2, + windowInnerHeight / 2 + ) + let scrolledHeight = 0 + const targetHeight = 3000 + const increase = 40 + Math.floor(30 * Math.random()) + while (scrolledHeight < targetHeight) { + scrolledHeight += increase + await page.mouse.wheel({deltaY: increase}); + await sleep(1) } - return false + hasReachLastPage = await page.evaluate(` + !(document.querySelector('.job-recommend-main')?.__vue__?.hasMore) + `) + if (hasReachLastPage) { + console.log(`Arrive the terminal of the job list.`) + } + + await sleep(3000) + jobListData = await page.evaluate( + ` + document.querySelector('.job-recommend-main')?.__vue__?.jobList + ` + ) + targetJobIndex = targetJobIndex = jobListData.findIndex(it => [...expectCompanySet].find(name => it.brandName.includes(name))) } - ); - await sleepWithRandomDelay(2000) - const jobData = await page.evaluate('document.querySelector(".job-detail-box").__vue__.data') + + if (targetJobIndex < 0 && hasReachLastPage) { + // has reach last page and not find target job + reject(new Error('CANNOT_FIND_EXCEPT_JOB')) + return + } + + const recommendJobItemList = await recommendJobListElProxy.$$('ul.rec-job-list > li') + resolve( + { + targetJobElProxy: recommendJobItemList[targetJobIndex], + targetJobIndex + } + ) + }) + if (targetJobIndex > 0) { + // scroll that target element into view + await page.evaluate(` + const targetEl = document.querySelector("ul.rec-job-list").children[${targetJobIndex}] + targetEl.scrollIntoView({ + behavior: 'smooth', + block: ${Math.random() > 0.5 ? '\'center\'' : '\'end\''} + }) + `) - const startChatButtonInnerHTML = await page.evaluate('document.querySelector(".job-detail-box .op-btn.op-btn-chat")?.innerHTML.trim()') - if (startChatButtonInnerHTML === '立即沟通') { - const startChatButtonProxy = await page.$('.job-detail-box .op-btn.op-btn-chat') - await startChatButtonProxy.click() - - const addFriendResponse = await page.waitForResponse( + await sleepWithRandomDelay(200) + + // click that element + await targetJobElProxy.click() + await page.waitForResponse( response => { if ( - response.url().startsWith('https://www.zhipin.com/wapi/zpgeek/friend/add.json') && response.url().includes(`jobId=${jobData.jobInfo.encryptId}`) + response.url().startsWith('https://www.zhipin.com/wapi/zpgeek/job/detail.json') ) { return true } return false } ); - try { - const res = await addFriendResponse.json() - - if (res.code !== 0) { - console.err(res) - break - } - } catch(err) { - // console.warn(err) - } finally { - //#region TODO: temporary work with legacy logic - await sleep(500) - const continueChatButtonProxy = await page.$('.greet-boss-dialog .greet-boss-footer .sure-btn') - - await continueChatButtonProxy.click() - //#endregion - await sleepWithRandomDelay(2500) - if (page.url().startsWith('https://www.zhipin.com/web/geek/chat')) { - await sleepWithRandomDelay(3000) - - await Promise.all([ - page.waitForNavigation(), - page.goBack(), - ]) - await sleepWithRandomDelay(1000) + await sleepWithRandomDelay(2000) + const jobData = await page.evaluate('document.querySelector(".job-detail-box").__vue__.data') + + const startChatButtonInnerHTML = await page.evaluate('document.querySelector(".job-detail-box .op-btn.op-btn-chat")?.innerHTML.trim()') + if (startChatButtonInnerHTML === '立即沟通') { + const startChatButtonProxy = await page.$('.job-detail-box .op-btn.op-btn-chat') + await startChatButtonProxy.click() + + const addFriendResponse = await page.waitForResponse( + response => { + if ( + response.url().startsWith('https://www.zhipin.com/wapi/zpgeek/friend/add.json') && response.url().includes(`jobId=${jobData.jobInfo.encryptId}`) + ) { + return true + } + return false + } + ); + try { + const res = await addFriendResponse.json() + + if (res.code !== 0) { + console.err(res) + break + } + } catch(err) { + // console.warn(err) + } finally { + //#region TODO: temporary work with legacy logic + await sleep(500) + const continueChatButtonProxy = await page.$('.greet-boss-dialog .greet-boss-footer .sure-btn') + + await continueChatButtonProxy.click() + //#endregion + await sleepWithRandomDelay(2500) + if (page.url().startsWith('https://www.zhipin.com/web/geek/chat')) { + await sleepWithRandomDelay(3000) + + await Promise.all([ + page.waitForNavigation(), + page.goBack(), + ]) + await sleepWithRandomDelay(1000) + } } + } else { } + } + } catch (err) { + if (err instanceof Error && err.message === 'CANNOT_FIND_EXCEPT_JOB') { + await Promise.all([ + page.reload(), + page.waitForNavigation() + ]) + continue afterPageLoad; } else { + throw err } } }