mirror of
https://github.com/hempyhemp/hh-auto-reply.git
synced 2026-06-08 18:04:57 +00:00
✨ feat(file): Добавлена функция collectPageVacancies для сбора информации о вакансиях на странице.
All checks were successful
Deploy / deploy (push) Successful in 50s
All checks were successful
Deploy / deploy (push) Successful in 50s
This commit is contained in:
@@ -216,6 +216,24 @@ export async function saveResume(chatId: number, resumeItem: ResumeListItem): Pr
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function collectPageVacancies(page: Page) {
|
||||||
|
return page.$$eval(
|
||||||
|
'[data-qa="vacancy-serp__vacancy"]',
|
||||||
|
(cards) => {
|
||||||
|
return cards
|
||||||
|
.filter(card => card.querySelector('[data-qa="vacancy-serp__vacancy_response"]') !== null)
|
||||||
|
.map((card) => {
|
||||||
|
const titleEl = card.querySelector('[data-qa="serp-item__title"]') as HTMLAnchorElement | null
|
||||||
|
return {
|
||||||
|
href: titleEl?.href ?? '',
|
||||||
|
title: titleEl?.textContent?.trim() ?? '',
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.filter(v => v.href)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
export async function applyToJobs(
|
export async function applyToJobs(
|
||||||
{ query, area = 1, maxApplies = 10 }: ApplyOptions,
|
{ query, area = 1, maxApplies = 10 }: ApplyOptions,
|
||||||
{ chatId, reporter }: { chatId: number, reporter: StatusReporter },
|
{ chatId, reporter }: { chatId: number, reporter: StatusReporter },
|
||||||
@@ -228,23 +246,36 @@ export async function applyToJobs(
|
|||||||
|
|
||||||
await loadSession(page, chatId)
|
await loadSession(page, chatId)
|
||||||
|
|
||||||
const url = `https://hh.ru/search/vacancy?text=${encodeURIComponent(query)}&area=${area}`
|
const url = `https://hh.ru/search/vacancy?text=${encodeURIComponent(query)}&items_on_page=50&page=0` // &area=${area}
|
||||||
await page.goto(url, { waitUntil: 'domcontentloaded' })
|
await page.goto(url, { waitUntil: 'domcontentloaded' })
|
||||||
await page.waitForSelector('[data-qa="serp-item__title"]', { timeout: 10000 }).catch(() => null)
|
await page.waitForSelector('[data-qa="serp-item__title"]', { timeout: 10000 }).catch(() => null)
|
||||||
|
await page.pause()
|
||||||
if (!await page.$('[data-qa="profileAndResumes-button"]')) {
|
if (!await page.$('[data-qa="profileAndResumes-button"]')) {
|
||||||
return { ...results, error: 'Не авторизован. Выполните login' }
|
return { ...results, error: 'Не авторизован. Выполните login' }
|
||||||
}
|
}
|
||||||
|
|
||||||
await status('✅ Авторизация выполнена')
|
await status('✅ Авторизация выполнена')
|
||||||
|
|
||||||
const vacancies = await page.$$eval(
|
const vacancies = await collectPageVacancies(page)
|
||||||
'[data-qa="serp-item__title"]',
|
|
||||||
links => links.map(a => ({
|
const pagerBlock = await page.$('[data-qa="pager-block"]')
|
||||||
href: (a as HTMLAnchorElement).href,
|
if (pagerBlock) {
|
||||||
title: a.textContent?.trim() ?? '',
|
const maxPage = await page.$$eval(
|
||||||
|
'[data-qa="pager-block"] [data-qa="pager-page"]',
|
||||||
|
links => Math.max(...links.map((a) => {
|
||||||
|
const pageParam = new URL((a as HTMLAnchorElement).href).searchParams.get('page')
|
||||||
|
return Number(pageParam ?? 0)
|
||||||
})),
|
})),
|
||||||
)
|
)
|
||||||
|
console.log('[applyToJobs] Max page:', maxPage)
|
||||||
|
for (let p = 1; p <= maxPage; p++) {
|
||||||
|
const pageUrl = `https://hh.ru/search/vacancy?text=${encodeURIComponent(query)}&items_on_page=50&page=${p}`
|
||||||
|
await page.goto(pageUrl, { waitUntil: 'domcontentloaded' })
|
||||||
|
await page.waitForSelector('[data-qa="vacancy-serp__vacancy"]', { timeout: 10000 }).catch(() => null)
|
||||||
|
const more = await collectPageVacancies(page)
|
||||||
|
vacancies.push(...more)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
await keep(`✅ Вакансий найдено: ${vacancies.length}`)
|
await keep(`✅ Вакансий найдено: ${vacancies.length}`)
|
||||||
|
|
||||||
@@ -298,6 +329,10 @@ export async function applyToJobs(
|
|||||||
|
|
||||||
await applyBtn.click()
|
await applyBtn.click()
|
||||||
|
|
||||||
|
const relocationConfirm = await page.waitForSelector('[data-qa="relocation-warning-confirm"]', { timeout: 2000 }).catch(() => null)
|
||||||
|
if (relocationConfirm)
|
||||||
|
await relocationConfirm.click()
|
||||||
|
|
||||||
if (await skipIfQuestionnaire(page, vacancy, ref, chatId, status, results))
|
if (await skipIfQuestionnaire(page, vacancy, ref, chatId, status, results))
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user