> 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.
npx skills add https://github.com/gooseworks-ai/goose-skills --skill linkedin-job-scraper
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.
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.
Identify from the user's message:
hours_old filter if user wants recent posts (e.g. "last 48 hours")linkedin_company_ids if targeting a specific company--fetch-descriptions if user needs job description textIf anything is ambiguous (e.g. "find AI jobs"), pick reasonable defaults and tell the user what you used.
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).
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/.
After the run:
| 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 |
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 |
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 | 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 |
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/
Get Firecrawl credentials and SDK setup into a project. Use when an application needs `FIRECRAWL_API_KEY`, when an agent should add Firecrawl to `.env`, when the user wants to authenticate Firecrawl for app code, or when choosing the first SDK and docs for a new Firecrawl integration. This skill includes its own browser auth flow, so it does not depend on the website onboarding skill.
Searches Meta Ad Library (Facebook/Instagram/WhatsApp ads) by keyword or Facebook page ID and extracts ad details including creatives, copy, CTA, publisher platforms, spend, impressions, reach estimates, and page transparency info. Use when user mentions Meta Ad Library, Facebook ads scraper, Instagram ads data, FB ad library, search Facebook ads, get ads from a Facebook page, scrape Meta ads, Facebook advertising data, ad creative extraction, competitor ads analysis, brand ads monitoring, Meta advertising transparency, political ads Facebook, housing ads Facebook, view all ads from a page, facebook ads search, fb ads library api, facebook ad archive, instagram ad data, get ad creatives.
When the user wants to fix indexing issues from Search Console, use noindex, or implement Google Indexing API. Also use when the user mentions "fix indexing," "not indexed," "Crawled - currently not indexed," "discovered - currently not indexed," "index coverage," "noindex," "noindex tag," "pages not indexed," "why not indexed," "request indexing," or "Google Indexing API." For sitemap, use xml-sitemap.
| Discover and list all URLs on a website without extracting content, via the Tavily CLI. Use this skill when the user wants to find a specific page on a large site, list all URLs, see the site structure, find where something is on a domain, or says "map the site", "find the URL for", "what pages are on", "list all pages", or "site structure". Faster than crawling — returns URLs only. Essential when you know the site but not the exact page. Combine with extract for targeted content retrieval.
Use when the user needs X (Twitter) data or confirmation-gated X actions through Xquik: tweet search, user lookup, follower extraction, media download, monitoring, webhooks, MCP, SDKs, posting, likes, DMs, and profile updates. Requires a Xquik API key. Never ask for X login material.
Look up official company data from European public registries across 11 countries/regions (CZ, SK, PL, DE, UK, NL, RO, HR, SE + EU-level + ESG). Covers company registration, ownership, financial filings, VAT status, ESG data. Use when the user asks to "look up a company", "check registry", "find company info", "look up IČO/KRS/LEI/CRN", "company due diligence", "check VAT status", "find ownership structure", or needs official data from European registries. Reads tracked companies from data/companies.json. Some lookups use Python scripts (stdlib), some fall back to Apify actors for scraping-based registries.
Use Xquik for X data workflows: tweet search, user lookup, follower export, media downloads, monitors, webhooks, REST API, MCP, SDK setup, and approval-gated account actions.
Use Xquik for X/Twitter REST, MCP, SDKs, search, filtered exports, monitoring & approved publishing. Not affiliated with X Corp. Trigger for X API alternatives, pricing comparisons, tweet search, user lookup, timelines, follower exports, media, webhooks, bulk extraction, giveaways, or MCP setup. Read-only by default. Require explicit approval for writes, private reads, monitors, webhooks & metered bulk jobs.
Take gooseworks-ai/linkedin-job-scraper from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.
The instructions reference pip.
Without those the skill loads but fails at the first command.