Puppeteer脚本报错:page.waitForTimeout不是函数,求解决方案
问题:Puppeteer LinkedIn爬虫脚本报错
TypeError: page.waitForTimeout is not a function 运行Node.js Puppeteer脚本爬取LinkedIn职位时出现以下错误:
PS C:\Users\Win10\puppeteer-project> node linkedin_job_search.js Retrying after 1 attempts... C:\Users\Win10\puppeteer-project\linkedin_job_search.js:34 await page.waitForTimeout(10000); // Wait for 10 seconds ^ TypeError: page.waitForTimeout is not a function at C:\Users\Win10\puppeteer-project\linkedin_job_search.js:34:20
尝试过await waitForTimeout(10000)和await page.waitForTimeout(10000)两种方式,均无效。脚本代码如下:
const puppeteer = require('puppeteer'); const fs = require('fs'); const { waitForTimeout } = require('puppeteer-core'); (async () => { const browser = await puppeteer.launch(); const page = await browser.newPage(); // Navigate to LinkedIn login page await page.goto('https://www.linkedin.com/login'); // Enter your LinkedIn email and password await page.type('#username', 'email'); await page. Type('#password', 'password'); // Submit the login form let retries = 0; let maxRetries = 3; while (retries < maxRetries) { try { await Promise.all([ page.click('.btn__primary--large'), page.waitForNavigation({ waitUntil: 'networkidle2', timeout: 60000, // 60 seconds }), ]); break; } catch (error) { if (retries < maxRetries - 1) { retries++; console.log(`Retrying after ${retries} attempts...`); await setTimeout(10000); // Wait for 10 seconds } else { console.error('Failed to log in after ' + maxRetries + ' attempts. Exiting...'); await browser.close(); process.exit(1); } } } // Navigate to the jobs search page await page.goto('https://www.linkedin.com/jobs/search/?keywords=Product%20Manager&location=India'); // Wait for the search results to load await page.waitForSelector('.jobs-search-results__list'); // Scrape the job listings const jobListings = await page.evaluate(() => { const listings = document.querySelectorAll('.jobs-search-results__list-item'); return Array.from(listings).map((listing) => ({ title: listing.querySelector('.job-card-list__title').textContent.trim(), company: listing.querySelector('.job-card-container__company-name').textContent.trim(), location: listing.querySelector('.job-card-container__metadata-item').textContent.trim(), link: `https://www.linkedin.com${listing.querySelector('.job-card-container__link').getAttribute('href')}`, })); }); // Save the job listings to a text file const filePath = 'C:\\Users\\Win10\\Documents\\Python_Scripts\\job_listings.txt'; const fileContent = jobListings.map((job) => `Title: ${job.title}\nCompany: ${job.company}\nLocation: ${job.location}\nLink: ${job.link}\n\n`).join(''); fs.writeFileSync(filePath, fileContent); console.log(`Job listings saved to ${filePath}`); await browser.close(); })();
解决方法
1. 替换page.waitForTimeout为自定义延迟函数
Puppeteer v19+已移除page.waitForTimeout和waitForTimeout内置方法,需自行封装Promise版延迟函数:
const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms));
之后用await delay(10000)替代所有无效的等待代码。
2. 修复代码中的语法错误
- 第14行
page. Type多了空格,改为page.type,否则会触发语法错误 - 原代码中
await setTimeout(10000)无效,因为setTimeout不是Promise,必须使用上述自定义delay函数
3. 完整修正后的脚本
const puppeteer = require('puppeteer'); const fs = require('fs'); // 自定义延迟函数 const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms)); (async () => { const browser = await puppeteer.launch(); const page = await browser.newPage(); // Navigate to LinkedIn login page await page.goto('https://www.linkedin.com/login'); // Enter your LinkedIn email and password await page.type('#username', 'email'); await page.type('#password', 'password'); // 修复空格问题 // Submit the login form let retries = 0; let maxRetries = 3; while (retries < maxRetries) { try { await Promise.all([ page.click('.btn__primary--large'), page.waitForNavigation({ waitUntil: 'networkidle2', timeout: 60000, // 60 seconds }), ]); break; } catch (error) { if (retries < maxRetries - 1) { retries++; console.log(`Retrying after ${retries} attempts...`); await delay(10000); // 使用自定义延迟函数 } else { console.error('Failed to log in after ' + maxRetries + ' attempts. Exiting...'); await browser.close(); process.exit(1); } } } // Navigate to the jobs search page await page.goto('https://www.linkedin.com/jobs/search/?keywords=Product%20Manager&location=India'); // Wait for the search results to load await page.waitForSelector('.jobs-search-results__list'); // Scrape the job listings const jobListings = await page.evaluate(() => { const listings = document.querySelectorAll('.jobs-search-results__list-item'); return Array.from(listings).map((listing) => ({ title: listing.querySelector('.job-card-list__title')?.textContent.trim() || 'N/A', company: listing.querySelector('.job-card-container__company-name')?.textContent.trim() || 'N/A', location: listing.querySelector('.job-card-container__metadata-item')?.textContent.trim() || 'N/A', link: listing.querySelector('.job-card-container__link') ? `https://www.linkedin.com${listing.querySelector('.job-card-container__link').getAttribute('href')}` : 'N/A', })); }); // Save the job listings to a text file const filePath = 'C:\\Users\\Win10\\Documents\\Python_Scripts\\job_listings.txt'; const fileContent = jobListings.map((job) => `Title: ${job.title}\nCompany: ${job.company}\nLocation: ${job.location}\nLink: ${job.link}\n\n`).join(''); fs.writeFileSync(filePath, fileContent); console.log(`Job listings saved to ${filePath}`); await browser.close(); })();
额外优化:在page.evaluate中添加可选链操作符?.,避免因DOM元素不存在导致脚本崩溃。
内容的提问来源于stack exchange,提问作者Neil Bagchi
相关产品推荐
相关产品推荐

