javascript
function scrapeJobListings() {
  const spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
  const allJobsSheet = spreadsheet.getSheetByName('All Jobs');
  const changesSheet = spreadsheet.getSheetByName('Changes');

  // Clear existing data in sheets
  allJobsSheet.clearContents();
  changesSheet.clearContents();

  // Get the number of open jobs and calculate pages
  const baseUrl = 'https://www.workinfinland.com/en/open-jobs/';
  const mainPage = UrlFetchApp.fetch(baseUrl).getContentText();
  const numJobsElement = mainPage.match(/<h2 class="heading__section section-header__heading" data-testid="section-header">There are (\d+) open jobs right now<\/h2>/);
  let numJobs;
  if (numJobsElement && numJobsElement[1]) {
    numJobs = parseInt(numJobsElement[1], 10);
  } else {
    // If no match is found, log an error and exit the function
    Logger.log('No job count found on the page.');
    return; // Exit the function early
  }
  const numPages = Math.ceil(numJobs / 12); // Assuming 12 jobs per page

  // Scrape job data from each page
  let allJobs = [];
  for (let page = 1; page <= numPages; page++) {
    const url = `${baseUrl}?page=${page}`;
    const pageContent = UrlFetchApp.fetch(url).getContentText();
    const jobCards = pageContent.match(/<a class="job-card".*?<\/a>/g);

    if (jobCards) {
      for (const jobCard of jobCards) {
        const titleMatch = jobCard.match(/<p class="job-card__title.*?>(.*?)<\/p>/);
        const employerMatch = jobCard.match(/<p class="job-card__employerName.*?>(.*?)<\/p>/);
        const locationMatch = jobCard.match(/<p class="job-card__location.*?>(.*?)<\/p>/);
        const jobLinkMatch = jobCard.match(/href="(.*?)"/);

        const jobData = {
          title: titleMatch ? titleMatch[1].trim() : '',
          employer: employerMatch ? employerMatch[1].trim() : '',
          location: locationMatch ? locationMatch[1].trim() : '',
          link: jobLinkMatch ? jobLinkMatch[1].trim() : '',
        };
        allJobs.push(jobData);
      }
    }

    // Delay between requests to avoid getting blocked
    Utilities.sleep(1000); // 1 second delay
  }

  // Paste all jobs to the "All Jobs" sheet
  allJobsSheet.appendRow(['Title', 'Employer', 'Location', 'Link']);
  for (const job of allJobs) {
    allJobsSheet.appendRow([job.title, job.employer, job.location, job.link]);
  }

  // Find and paste changes compared to previous day
  const yesterdayJobs = allJobsSheet.getRange(2, 1, allJobsSheet.getLastRow() - 1, 4).getValues();
  const newJobs = allJobs.filter(job => !yesterdayJobs.some(yJob => yJob[3] === job.link));
  const removedJobs = yesterdayJobs.filter(yJob => !allJobs.some(job => job.link === yJob[3]));

  changesSheet.appendRow(['New Jobs:', '', '', '']);
  for (const job of newJobs) {
    changesSheet.appendRow([job.title, job.employer, job.location, job.link]);
  }

  changesSheet.appendRow(['', '', '', '']);
  changesSheet.appendRow(['Removed Jobs:', '', '', '']);
  for (const job of removedJobs) {
    changesSheet.appendRow([job[0], job[1], job[2], job[3]]);
  }
}
Edit

Pub: 15 May 2024 18:24 UTC

Views: 180