我想使用puppeteer从ZipRecruiter抓取工作数据,用于我的个人项目。我当前的方法是使用puppeteer转到ziprecruiter URL(例如https://www.ziprecruiter.com/candidate/search?search=React&location=San+Francisco
)并获取所有可单击的作业名称。由于这些项目实际上不是<a>
标记,因此我不能简单地获取它们的href属性并使用puppeteer转到该页面,然后将页面的HTML传递给cheerio来擦除我需要的数据。
相反,我试图将所有职位(类为('.just_job_title')
)保存在变量中,然后使用puppeteer单击每个职位,打开新页面,如果该页面属于ZipRecruiter ,抓取我需要的信息。然后使用page.goBack()
返回到原始URL。但是,我当前的方法引起了错误:UnhandledPromiseRejectionWarning: Error: Protocol error (Runtime.callFunctionOn): Target closed.
,而且我不确定如何实现上面概述的理想方案。
这是我的代码:
export async function getJobsZipRecruiter(params) {
const ZIPRECRUITER_URL = `https://www.ziprecruiter.com/candidate/search?search=React&location=San+Francisco`;
try {
console.log('Trying to scrape *************');
const browser = await puppeteer.launch({ headless: false });
const page = await browser.newPage();
await page.goto(ZIPRECRUITER_URL);
await page.waitForSelector('#createAlertPop');
const jobs = await page.$$('.just_job_title');
jobs.forEach(async (job) => {
await page.waitForSelector('.just_job_title');
await job.click();
console.log('Yes it worked');
// Get the data you want here and push it into the data array
await page.goBack();
});
console.log(jobs)
await browser.close();
return zipRecruiterJobs;
} catch (err) {
console.log(err);
}
}
答案 0 :(得分:1)
.forEach()
不太适合异步任务:它会立即启动所有callbac,因此,在您的情况下,所有功能都是混合在一起的,只能处理一页混乱的标题。通常for..of循环会更好。
'.just_job_title'
元素是链接的子元素,因此您可以收集所有href并逐一处理它们。
尝试这样的事情:
const puppeteer = require('puppeteer');
async function getJobsZipRecruiter(params) {
const ZIPRECRUITER_URL = `https://www.ziprecruiter.com/candidate/search?search=React&location=San+Francisco`;
try {
console.log('Trying to scrape *************');
const browser = await puppeteer.launch({ headless: false });
const [page] = await browser.pages();
await page.goto(ZIPRECRUITER_URL);
await page.waitForSelector('#createAlertPop');
const urls = await page.evaluate(() => Array.from(
document.querySelectorAll('a[href][data-tracking="job_title"].job_link.t_job_link'),
link => link.href,
));
console.log(urls);
const zipRecruiterJobs = [];
for (const url of urls) {
await page.goto(url);
if (!page.url().startsWith('https://www.ziprecruiter.com/')) continue;
await page.waitForSelector('h1.job_title');
// Get the data you want here and push it into the data array
zipRecruiterJobs.push(
await page.evaluate(() => document.querySelector('h1.job_title').innerText)
);
}
await browser.close();
console.log(zipRecruiterJobs);
return zipRecruiterJobs;
} catch (err) {
console.log(err);
}
}
getJobsZipRecruiter();