A Playwright script that extracts LinkedIn saved jobs from the past 30 days using cookies from an existing Chrome browser and saves them to your Obsidian vault with dataview integration.
- Uses your existing Chrome login cookies (no password required)
- Extracts all saved jobs from LinkedIn
- Filters jobs by date saved (default: last 30 days)
- Exports to multiple formats:
- JSON: Complete structured data
- CSV: Tabular format for spreadsheet analysis
- Markdown: Human-readable format
- Obsidian integration:
- Saves jobs directly to your Obsidian vault
- Adds YAML frontmatter for dataview plugin integration
- Prevents duplicate job entries in your vault
- Formats filenames for Obsidian compatibility
- CLI support for easy on-demand execution
- Automated daily extraction via cron
- Node.js 16+ installed
- Google Chrome with active LinkedIn session
- macOS (default cookie path is set for macOS; see Configuration for other platforms)
- Optional: Obsidian with the Dataview plugin for enhanced job tracking
- Clone or download this repository
- Navigate to the project directory
- Install dependencies:
npm installThis will install:
playwright: For browser automationsqlite3andsqlite: For reading Chrome cookiescommander: For CLI functionality
Before running, you may want to adjust settings in config.js:
module.exports = {
// Chrome cookie settings
chromeProfilePath: '~/Library/Application Support/Google/Chrome/Default', // MacOS default path
// Alternative Chrome profiles (uncomment if needed)
// chromeProfilePath: '~/Library/Application Support/Google/Chrome/Profile 1', // Chrome Profile 1
// chromeProfilePath: '~/Library/Application Support/Google/Chrome', // Chrome root dir (searches all profiles)
// Browser settings
headless: false, // Set to true to run browser in headless mode
slowMo: 500, // Slow down browser actions in non-headless mode (ms)
// Job extraction settings
daysThreshold: 30, // Only extract jobs saved within the last X days
filterDuplicates: true, // Remove duplicate job entries
filterOptions: {
keywords: [], // Filter jobs by these keywords (title or description)
companies: [], // Filter jobs from these companies
locations: [], // Filter jobs in these locations
excludeKeywords: [] // Exclude jobs with these keywords
},
// Output settings
outputPath: './output', // Directory to save extracted job data
obsidianPath: '/Users/yourname/Obsidian/vault/Jobs', // Path to Obsidian vault Jobs directory
saveToObsidian: true, // Save jobs to Obsidian vault
outputFormats: ['json', 'csv', 'markdown'], // Available formats: json, csv, markdown, html
// LinkedIn credentials (optional fallback)
linkedinCredentials: {
username: 'your-email@example.com', // Your LinkedIn email/username
password: 'your-password' // Your LinkedIn password
},
// Retry settings
maxRetries: 3,
retryDelay: 1000 // ms
};All configuration options can also be set using environment variables:
# Chrome and browser settings
export LINKEDIN_CHROME_PROFILE="~/Library/Application Support/Google/Chrome/Default"
export LINKEDIN_HEADLESS="true"
export LINKEDIN_SLOW_MO="500"
# Job extraction settings
export LINKEDIN_DAYS_THRESHOLD="30"
# Output settings
export LINKEDIN_OUTPUT_PATH="./output"
export LINKEDIN_OBSIDIAN_PATH="/path/to/obsidian/vault/Jobs"
export LINKEDIN_SAVE_TO_OBSIDIAN="true"
export LINKEDIN_OUTPUT_FORMATS="json,csv,markdown"
# LinkedIn credentials (optional)
export LINKEDIN_USERNAME="your-email@example.com"
export LINKEDIN_PASSWORD="your-password"
# Retry settings
export LINKEDIN_MAX_RETRIES="3"
export LINKEDIN_RETRY_DELAY="1000"Environment variables take precedence over settings in the config.js file, making it easy to override settings for specific runs or in CI/CD environments.
- macOS:
~/Library/Application Support/Google/Chrome/Default - Windows:
%LOCALAPPDATA%\\Google\\Chrome\\User Data\\Default - Linux:
~/.config/google-chrome/Default
For Chrome profiles other than "Default", adjust the path accordingly.
You can run the script in several ways:
# Basic execution
npm start
# Using the CLI
npm run extract
# Using the CLI with options
node cli.js extract --days 14 --headless
# Directly from CLI if globally installed
linkedin-jobs extract --days 14 --headlessThe script will:
- Extract cookies from your Chrome browser
- Launch a Playwright browser instance
- Authenticate with LinkedIn using your cookies (or credentials if cookies fail)
- Navigate to your saved jobs
- Extract job details for each saved job (within the date threshold)
- Save the extracted jobs to the specified output formats
- Save the jobs to your Obsidian vault with proper frontmatter for dataview
Extracted jobs will be saved to:
- The
outputdirectory (as JSON, CSV, and Markdown) - Your Obsidian vault's Jobs directory (as individual Markdown files with frontmatter)
The CLI tool provides several commands and options for managing the extraction:
Usage: linkedin-jobs [command] [options]
Commands:
extract Extract saved jobs from LinkedIn
status Check the status of the last extraction run
update Check for updates to the LinkedIn Saved Jobs Extractor
config Show or update configuration
Extract command options:
-d, --days <number> Number of days to look back for saved jobs (default: 30)
-o, --output <path> Output directory for extracted jobs (default: ./output)
--obsidian <path> Obsidian vault path for job files
--no-obsidian Disable saving to Obsidian vault
--profile <path> Chrome profile path for cookies
--headless Run browser in headless mode
--formats <formats> Output formats (comma-separated) (default: json,csv,markdown)
Update command options:
--check-only Only check for updates without updating
Config command options:
-l, --list List current configuration
-e, --edit Open configuration file in default editor
Global options:
-h, --help Display help for command
-V, --version Display version number
# Extract jobs from the last 14 days
linkedin-jobs extract --days 14
# Extract jobs with custom output formats
linkedin-jobs extract --formats json,markdown
# Check the status of the last extraction run
linkedin-jobs status
# Check for updates
linkedin-jobs update --check-only
# Apply available updates
linkedin-jobs update
# View current configuration
linkedin-jobs config --list
# Edit configuration file
linkedin-jobs config --editTo set up automated daily execution:
-
Make the script executable:
chmod +x setup-cron.sh
-
Run the setup script:
./setup-cron.sh
-
Follow the prompts to:
- Set the time for daily execution
- Configure email notifications (optional)
The script will set up a cron job to run the LinkedIn Jobs Extractor daily at your specified time. Logs will be saved to the logs directory.
The script supports email notifications for:
- Successful extractions
- Failed extractions
- When new jobs are found
To configure email notifications:
- During the
setup-cron.shscript, answer "y" when asked about email notifications - Provide your email address and select notification preferences
- Make sure the
mailcommand is available on your system:- macOS:
brew install mailutils - Ubuntu/Debian:
sudo apt-get install mailutils - CentOS/RHEL:
sudo yum install mailx
- macOS:
Alternatively, you can manually edit the .extract_config file to adjust notification settings after setup.
The script integrates with the Dataview plugin for Obsidian, allowing you to:
- Filter and query your saved jobs using dataview queries
- Build job application dashboards
- Track your application status for each job
- Sort and filter jobs by company, location, date posted, etc.
The job files include YAML frontmatter with fields like:
---
title: "Job Title"
company: "Company Name"
location: "Location (Remote/Hybrid/On-site)"
date_posted: "YYYY-MM-DD"
date_extracted: "YYYY-MM-DD"
url: "LinkedIn Job URL"
status: "To Apply"
---You can update the status field manually to track your progress:
- "To Apply"
- "Applied"
- "Interview Scheduled"
- "Rejected"
- "Offer Received"
- Cookie Extraction: The script extracts LinkedIn cookies from your Chrome browser's cookie database. It can search in multiple profiles if configured to do so.
- Authentication: These cookies are added to a Playwright browser context to authenticate with LinkedIn, with fallback to credential-based login if needed.
- Job Extraction: The script navigates to your saved jobs page and extracts basic information for each job listing.
- Detailed Extraction: For each job, the script visits the job listing page to get complete details.
- Data Export: The extracted job data is saved in the standard formats (JSON, CSV, Markdown).
- Obsidian Export: Jobs are also saved to your Obsidian vault with proper frontmatter for dataview integration, ensuring no duplicates are created.
- Make sure you are logged into LinkedIn in your Chrome browser
- Check that the Chrome profile path in
config.jsmatches your system - If using a non-default Chrome profile, adjust the path accordingly
- Try running with
headless: falseto see what's happening - Add your LinkedIn credentials in
config.jsas a fallback
- LinkedIn occasionally changes its UI, which may break selectors
- Check for console errors when running the script
- If job listings aren't found, try adjusting the selectors in
jobScraper.js
- Make sure Chrome is closed before running the script (to avoid cookie database lock)
- If Chrome is encrypting cookies with your system password, try logging into LinkedIn in an incognito window first
- Check the logs in the
logsdirectory for error messages - Make sure the paths in the cron job are absolute paths
- Ensure cron has permission to access the required directories
- LinkedIn may detect automated access and temporarily limit your account
- LinkedIn UI changes may require updating the selectors used
- The script currently only works with Chrome; other browsers are not supported
- Very large numbers of saved jobs may take time to process
MIT