Files
linkme/README.md
T

71 lines
2.4 KiB
Markdown

# linkme
Scrapes LinkedIn job listings into a local CSV. Run it daily, delete rows you've applied to.
## Usage
```bash
bun fetch
```
No setup needed. Results are appended to `jobs.csv` — reruns are safe, already-seen jobs are skipped by ID.
## Output
`jobs.csv` — one row per job:
| column | description |
|---|---|
| `date_found` | date you ran the fetch |
| `posted_at` | date the job was posted on LinkedIn |
| `search` | which search config matched it |
| `title` | job title |
| `company` | hiring company |
| `link` | canonical LinkedIn job URL |
Open in any spreadsheet app. Delete rows as you apply or dismiss.
## How it works
- **Paginated scraping** — fetches up to 6 pages per search (150 jobs) with a 400 ms delay between pages to avoid rate limiting
- **Card-boundary-safe parsing** — each job card is isolated before extracting fields, preventing content from adjacent cards bleeding into company or date values
- **Language filter** — drops German (`m/w/d`, umlauts, gender-marked vocabulary) and French (`H/F`, accented characters) job titles automatically
- **Software-role filter** — requires the title to contain a relevant term (software, developer, data, AI, backend, devops, platform, architect, technical, solutions, consultant, product/IT/engineering manager, etc.) — eliminates aviation, mechanical, and pharma-process roles that match "Engineer" broadly
- **Seniority filter** — drops junior, intern, trainee, and apprentice titles
- **Global deduplication** — job IDs are indexed from the existing CSV on startup; jobs you've already seen are never re-added, even if you delete and re-run
- **30-day recency** — only fetches jobs posted in the last month (`f_TPR=r2592000`)
## Configure searches
Edit `config.ts`:
```ts
const KEYWORDS = [
"Software Engineer",
"Full Stack Engineer",
"Data Engineer",
"AI Engineer",
"Ruby on Rails",
"Python",
// add or remove freely
].join(" OR ");
export const searches: SearchConfig[] = [
{
label: "Basel (city)",
keywords: KEYWORDS,
geoId: "103383283",
location: "Basel",
workType: ["onsite", "hybrid"],
timePosted: "month",
},
];
```
`geoId` values for the Basel area:
- `103383283` — Basel (city)
- `90009885` — Basel Metropolitan Area
- `107117530` — Basel-Country
You can also paste any LinkedIn search URL directly as `url:` instead of building from filters.