LinkedIn Job Scraper
LinkedIn Scraper

Scrapes LinkedIn job postings using the JobSpy library (python-jobspy). Use this skill whenever the user wants to find jobs on LinkedIn, search for open roles, pull job listings, build a job pipeline, source job targets for GTM…
--- name: linkedin-job-scraper description: > Scrapes LinkedIn job postings using the JobSpy library (python-jobspy). Use this skill whenever the user wants to find jobs on LinkedIn, search for open roles, pull job listings, build a job pipeline, source job targets for GTM research, or monitor hiring signals. Even if the user just says "find me some jobs" or "what roles is [company] hiring for", use this skill. It runs a local Python script that outputs a CSV of job postings with title, company, location, salary, job type, description, and direct URLs. tags: [lead-generation] --- # LinkedIn Scraper ## Overview This skill finds LinkedIn job postings by running `tools/jobspy_scraper.py`, a thin wrapper around the [JobSpy](https://github.com/speedyapply/JobSpy) library. It handles installation,
Overview
This skill finds LinkedIn job postings by running tools/jobspy_scraper.py, a thin wrapper around the JobSpy library. It handles installation, parameter construction, execution, and result interpretation.
Manual install (npx, ZIP)
npx skills add gooseworks-ai/goose-skills --skill linkedin-job-scraper -g -a claude-codemkdir -p ~/.claude/skills && curl -sL https://codeload.github.com/gooseworks-ai/goose-skills/tar.gz/615c685f34f8 \
| tar -xz -C ~/.claude/skills --strip-components=4 goose-skills-615c685f34f8/skills/lead-generation/capabilities/linkedin-job-scraperNew-Item -ItemType Directory -Force "$HOME\.claude\skills" | Out-Null; Invoke-WebRequest "https://m.agentalley.io/zip/c29ea802ee7382101974/linkedin-job-scraper.zip" -OutFile "$env:TEMP\linkedin-job-scraper.zip"; Expand-Archive "$env:TEMP\linkedin-job-scraper.zip" -DestinationPath "$HOME\.claude\skills" -ForceConnects with Agent Alley MCP · agentalley.io/mcp
Files included
SKILL.md5.6 KBskill.meta.json270 Bscripts/1 file · 3.9 KB
Read the files here
Show the full text172 lines
LinkedIn Scraper
Overview
This skill finds LinkedIn job postings by running tools/jobspy_scraper.py, a thin wrapper
around the JobSpy library. It handles installation,
parameter construction, execution, and result interpretation.
Quick Start
Install the dependency once (requires Python 3.10+):
python3.12 -m pip install -U python-jobspy --break-system-packages
Run the scraper:
python3.12 tools/jobspy_scraper.py \
--search "software engineer" \
--location "San Francisco, CA" \
--results 25 \
--output .tmp/jobs.csv
Results are saved as CSV and printed as a summary table.
Workflow
Step 1 — Understand the request
Identify from the user's message:
- Search term — job title, role, or keyword (required)
- Location — city, state, or "Remote" (optional but recommended)
- Results wanted — default to 25 if not specified
- Recency —
hours_oldfilter if user wants recent posts (e.g. "last 48 hours") - Company filter —
linkedin_company_idsif targeting a specific company - Full descriptions — set
--fetch-descriptionsif user needs job description text
If anything is ambiguous (e.g. "find AI jobs"), pick reasonable defaults and tell the user what you used.
Step 2 — Construct the command
Build the tools/jobspy_scraper.py command using the parameters below.
Always save output to .tmp/ so it's disposable and easy to find.
python tools/jobspy_scraper.py \
--search "<term>" \
--location "<location>" \
--results <N> \
[--hours-old <N>] \
[--fetch-descriptions] \
[--company-ids <id1,id2>] \
[--job-type fulltime|parttime|contract|internship] \
[--remote] \
--output .tmp/<descriptive_filename>.csv
Note: --hours-old and --easy-apply cannot be used together (LinkedIn API constraint).
Step 3 — Run the script
Execute the command. The script will print a progress message and a summary of results found.
If the script is not found at tools/jobspy_scraper.py, check whether the file needs to be created
by reading skills/linkedin-job-scraper/scripts/jobspy_scraper.py and copying it to tools/.
Step 4 — Interpret and present results
After the run:
- Report how many jobs were found
- Show a brief table: Title | Company | Location | Salary | Posted
- Note the output file path so the user can open it
- If 0 results: suggest broadening the search term or removing the location filter
Parameters Reference
| Flag | Description | Default |
|---|---|---|
--search |
Job title / keywords | required |
--location |
City, state, or country | none |
--results |
Number of results to fetch | 25 |
--hours-old |
Only jobs posted within N hours | none |
--fetch-descriptions |
Fetch full job descriptions (slower) | false |
--company-ids |
Comma-separated LinkedIn company IDs | none |
--job-type |
fulltime, parttime, contract, internship | any |
--remote |
Filter for remote jobs only | false |
--output |
Path for CSV output | .tmp/jobs.csv |
Output Columns
The CSV output includes:
| Column | Description |
|---|---|
TITLE |
Job title |
COMPANY |
Employer name |
LOCATION |
City / State / Country |
IS_REMOTE |
True/False |
JOB_TYPE |
fulltime, contract, etc. |
DATE_POSTED |
When the listing was posted |
MIN_AMOUNT |
Minimum salary |
MAX_AMOUNT |
Maximum salary |
CURRENCY |
Currency code |
JOB_URL |
Direct link to the LinkedIn posting |
DESCRIPTION |
Full job description (if --fetch-descriptions used) |
JOB_LEVEL |
Seniority level (LinkedIn-specific) |
COMPANY_INDUSTRY |
Industry classification |
Common Use Cases
Find recent engineering roles at a startup:
python tools/jobspy_scraper.py --search "growth engineer" --location "New York" \
--results 50 --hours-old 72 --output .tmp/growth_eng_nyc.csv
Monitor what a specific company is hiring for:
# First find the LinkedIn company ID from the company's LinkedIn URL
python tools/jobspy_scraper.py --search "engineer" --company-ids 1234567 \
--results 100 --fetch-descriptions --output .tmp/company_hiring.csv
Find remote contract roles:
python tools/jobspy_scraper.py --search "data analyst" --remote \
--job-type contract --results 30 --output .tmp/remote_contracts.csv
Error Handling
| Error | Fix |
|---|---|
ModuleNotFoundError: jobspy |
Run pip install -U python-jobspy |
| 0 results returned | Broaden search term, remove location, increase --results |
| Rate limited / blocked | Wait a few minutes; avoid running back-to-back large scrapes |
hours_old and easy_apply cannot both be set |
Remove one of those flags |
Script Location
The scraper script lives at tools/jobspy_scraper.py.
If it doesn't exist, copy it from skills/linkedin-scraper/scripts/jobspy_scraper.py to tools/:
cp skills/linkedin-job-scraper/scripts/jobspy_scraper.py tools/
| 1 | |
| 2 | name linkedin-job-scraper |
| 3 | description > |
| 4 | Scrapes LinkedIn job postings using the JobSpy library (python-jobspy). Use this skill |
| 5 | whenever the user wants to find jobs on LinkedIn, search for open roles, pull job listings, |
| 6 | build a job pipeline, source job targets for GTM research, or monitor hiring signals. |
| 7 | Even if the user just says "find me some jobs" or "what roles is [company] hiring for", |
| 8 | use this skill. It runs a local Python script that outputs a CSV of job postings with |
| 9 | title, company, location, salary, job type, description, and direct URLs. |
| 10 | tags [lead-generation] |
| 11 | |
| 12 | |
| 13 | # LinkedIn Scraper |
| 14 | |
| 15 | ## Overview |
| 16 | |
| 17 | This skill finds LinkedIn job postings by running `tools/jobspy_scraper.py`, a thin wrapper |
| 18 | around the [JobSpy] library. It handles installation, |
| 19 | parameter construction, execution, and result interpretation. |
| 20 | |
| 21 | ## Quick Start |
| 22 | |
| 23 | **Install the dependency once (requires Python 3.10+):** |
| 24 | |
| 25 | python3.12 -m pip install -U python-jobspy --break-system-packages |
| 26 | |
| 27 | |
| 28 | **Run the scraper:** |
| 29 | |
| 30 | python3.12 tools/jobspy_scraper.py \ |
| 31 | --search "software engineer" \ |
| 32 | --location "San Francisco, CA" \ |
| 33 | --results 25 \ |
| 34 | --output .tmp/jobs.csv |
| 35 | |
| 36 | |
| 37 | Results are saved as CSV and printed as a summary table. |
| 38 | |
| 39 | |
| 40 | |
| 41 | ## Workflow |
| 42 | |
| 43 | ### Step 1 — Understand the request |
| 44 | |
| 45 | Identify from the user's message: |
| 46 | **Search term** — job title, role, or keyword (required) |
| 47 | **Location** — city, state, or "Remote" (optional but recommended) |
| 48 | **Results wanted** — default to 25 if not specified |
| 49 | **Recency** — `hours_old` filter if user wants recent posts (e.g. "last 48 hours") |
| 50 | **Company filter** — `linkedin_company_ids` if targeting a specific company |
| 51 | **Full descriptions** — set `--fetch-descriptions` if user needs job description text |
| 52 | |
| 53 | If anything is ambiguous (e.g. "find AI jobs"), pick reasonable defaults and tell the user what you used. |
| 54 | |
| 55 | ### Step 2 — Construct the command |
| 56 | |
| 57 | Build the `tools/jobspy_scraper.py` command using the parameters below. |
| 58 | Always save output to `.tmp/` so it's disposable and easy to find. |
| 59 | |
| 60 | |
| 61 | python tools/jobspy_scraper.py \ |
| 62 | --search "<term>" \ |
| 63 | --location "<location>" \ |
| 64 | --results <N> \ |
| 65 | [--hours-old <N>] \ |
| 66 | [--fetch-descriptions] \ |
| 67 | [--company-ids <id1,id2>] \ |
| 68 | [--job-type fulltime|parttime|contract|internship] \ |
| 69 | [--remote] \ |
| 70 | --output .tmp/<descriptive_filename>.csv |
| 71 | |
| 72 | |
| 73 | **Note:** `--hours-old` and `--easy-apply` cannot be used together (LinkedIn API constraint). |
| 74 | |
| 75 | ### Step 3 — Run the script |
| 76 | |
| 77 | Execute the command. The script will print a progress message and a summary of results found. |
| 78 | |
| 79 | If the script is not found at `tools/jobspy_scraper.py`, check whether the file needs to be created |
| 80 | by reading `skills/linkedin-job-scraper/scripts/jobspy_scraper.py` and copying it to `tools/`. |
| 81 | |
| 82 | ### Step 4 — Interpret and present results |
| 83 | |
| 84 | After the run: |
| 85 | Report how many jobs were found |
| 86 | Show a brief table: Title | Company | Location | Salary | Posted |
| 87 | Note the output file path so the user can open it |
| 88 | If 0 results: suggest broadening the search term or removing the location filter |
| 89 | |
| 90 | |
| 91 | |
| 92 | ## Parameters Reference |
| 93 | |
| 94 | | Flag | Description | Default | |
| 95 | |------|-------------|---------| |
| 96 | | `--search` | Job title / keywords | required | |
| 97 | | `--location` | City, state, or country | none | |
| 98 | | `--results` | Number of results to fetch | 25 | |
| 99 | | `--hours-old` | Only jobs posted within N hours | none | |
| 100 | | `--fetch-descriptions` | Fetch full job descriptions (slower) | false | |
| 101 | | `--company-ids` | Comma-separated LinkedIn company IDs | none | |
| 102 | | `--job-type` | fulltime, parttime, contract, internship | any | |
| 103 | | `--remote` | Filter for remote jobs only | false | |
| 104 | | `--output` | Path for CSV output | .tmp/jobs.csv | |
| 105 | |
| 106 | |
| 107 | |
| 108 | ## Output Columns |
| 109 | |
| 110 | The CSV output includes: |
| 111 | |
| 112 | | Column | Description | |
| 113 | |--------|-------------| |
| 114 | | `TITLE` | Job title | |
| 115 | | `COMPANY` | Employer name | |
| 116 | | `LOCATION` | City / State / Country | |
| 117 | | `IS_REMOTE` | True/False | |
| 118 | | `JOB_TYPE` | fulltime, contract, etc. | |
| 119 | | `DATE_POSTED` | When the listing was posted | |
| 120 | | `MIN_AMOUNT` | Minimum salary | |
| 121 | | `MAX_AMOUNT` | Maximum salary | |
| 122 | | `CURRENCY` | Currency code | |
| 123 | | `JOB_URL` | Direct link to the LinkedIn posting | |
| 124 | | `DESCRIPTION` | Full job description (if --fetch-descriptions used) | |
| 125 | | `JOB_LEVEL` | Seniority level (LinkedIn-specific) | |
| 126 | | `COMPANY_INDUSTRY` | Industry classification | |
| 127 | |
| 128 | |
| 129 | |
| 130 | ## Common Use Cases |
| 131 | |
| 132 | **Find recent engineering roles at a startup:** |
| 133 | |
| 134 | python tools/jobspy_scraper.py --search "growth engineer" --location "New York" \ |
| 135 | --results 50 --hours-old 72 --output .tmp/growth_eng_nyc.csv |
| 136 | |
| 137 | |
| 138 | **Monitor what a specific company is hiring for:** |
| 139 | |
| 140 | # First find the LinkedIn company ID from the company's LinkedIn URL |
| 141 | python tools/jobspy_scraper.py --search "engineer" --company-ids 1234567 \ |
| 142 | --results 100 --fetch-descriptions --output .tmp/company_hiring.csv |
| 143 | |
| 144 | |
| 145 | **Find remote contract roles:** |
| 146 | |
| 147 | python tools/jobspy_scraper.py --search "data analyst" --remote \ |
| 148 | --job-type contract --results 30 --output .tmp/remote_contracts.csv |
| 149 | |
| 150 | |
| 151 | |
| 152 | |
| 153 | ## Error Handling |
| 154 | |
| 155 | | Error | Fix | |
| 156 | |-------|-----| |
| 157 | | `ModuleNotFoundError: jobspy` | Run `pip install -U python-jobspy` | |
| 158 | | 0 results returned | Broaden search term, remove location, increase `--results` | |
| 159 | | Rate limited / blocked | Wait a few minutes; avoid running back-to-back large scrapes | |
| 160 | | `hours_old and easy_apply cannot both be set` | Remove one of those flags | |
| 161 | |
| 162 | |
| 163 | |
| 164 | ## Script Location |
| 165 | |
| 166 | The scraper script lives at `tools/jobspy_scraper.py`. |
| 167 | |
| 168 | If it doesn't exist, copy it from `skills/linkedin-scraper/scripts/jobspy_scraper.py` to `tools/`: |
| 169 | |
| 170 | cp skills/linkedin-job-scraper/scripts/jobspy_scraper.py tools/ |
| 171 | |
| 172 |
Details
- Updated
- Sep 21, 2026
- License
- MIT
- Stars on the repo
- ★ 1,220
- Checked
- Source
- gooseworks-ai/goose-skills ↗
- Creator
- gooseworks-ai · 205 listings
Similar skills
See all →
SkillXberg Document Extractor
SkillCode Migration Validator
SkillAhrefs API Manager
AgentDocx to Markdown Translator
SkillAmazon White-Background Creator
AgentSendmux SDKMore from gooseworks-ai
SkillAd Angle Miner
SkillAd Campaign Analyzer
SkillLead Quality Analyzer
SkillMessage Match Auditor
SkillAI Search Visibility
SkillAmazon Product Search