yc-jobs-scraper

$npx mdskill add Varnan-Tech/opendirectory/yc-jobs-scraper

Scrapes daily YC job listings without duplicates

  • Automatically logs in to access private job listings and company pages.
  • Uses Inertia.js JSON payloads for extracting company slugs and Playwright for authentication.
  • Maintains a SQLite database of seen jobs to prevent duplicate scraping.
  • Sends scraped job data to the user or agent for further processing.

SKILL.md

.github/skills/yc-jobs-scraperView on GitHub ↗
---
name: yc-jobs-scraper
description: Scrape daily job listings from YCombinator's Workatastartup platform without duplicates. Use this skill when asked to scrape YC jobs, update the YC companies list, or retrieve the latest startup jobs. It handles authentication, extracts company slugs via Inertia.js JSON payloads, falls back to public YC job pages when necessary, and maintains a local SQLite database to track historical jobs and prevent duplicates.
---

# YC Jobs Scraper

This skill provides a robust architecture for scraping jobs from YCombinator and `workatastartup.com`. It is designed to run automatically, bypass login bottlenecks, and maintain state to never scrape duplicate jobs.

## Architecture

The scraper uses a hybrid approach to maximize reliability and minimize bot detection:

1. **Authentication:** `scripts/auth.js` uses Playwright to let a human log in once and saves the session to `scripts/state.json`.
2. **Database:** `scripts/db.js` uses `better-sqlite3` to manage `scripts/jobs.db`. It tracks every `company_slug` and `job_id` ever seen.
3. **Primary Extraction:** `scripts/scraper.js` loads `state.json`, visits YC query URLs, and extracts company slugs from the hidden Inertia.js `data-page` JSON payload.
4. **Job Extraction (JSON):** It then visits the authenticated company pages (`/companies/[slug]`) to extract jobs from the backend JSON payload to ensure we get the real `job_id` for accurate deduplication.
5. **Job Extraction (Fallback):** If the JSON extraction fails, it falls back to parsing public HTML job cards from `ycombinator.com/companies/[slug]/jobs`.

## Workflows

### 1. First-Time Setup
If this is the first time running the scraper in an environment, or if `node_modules` is missing:
```bash
cd @path/scripts
npm install
npx playwright install
```

### 2. Authentication (Manual Step)
If `scripts/state.json` is missing or expired, the scraper will fail. You must instruct the human user to run the authentication script manually:
```bash
cd @path/scripts
node auth.js
```
Tell the user a browser will open, and they must log in. Playwright will automatically save the cookies/tokens to `state.json`.

### 3. Running the Daily Scraper
To scrape for new companies and jobs:
```bash
cd @path/scripts
node scraper.js
```
This script will output exactly how many new companies and new jobs were found. Because of `jobs.db`, running it multiple times consecutively will result in `0 new jobs found`.

### 4. Querying the Database
If you need to analyze the scraped data or view the companies/jobs, you can query `scripts/jobs.db` directly using `better-sqlite3`.

**Example: Count Companies**
```bash
cd @path/scripts
node -e "const db = require('better-sqlite3')('jobs.db'); console.log('Companies:', db.prepare('SELECT COUNT(*) as count FROM companies').get().count);"
```

**Example: View Recent Jobs**
```bash
cd @path/scripts
node -e "const db = require('better-sqlite3')('jobs.db'); const jobs = db.prepare('SELECT title, company_slug, location FROM jobs ORDER BY created_at DESC LIMIT 5').all(); console.table(jobs);"
```

More from Varnan-Tech/opendirectory

SkillDescription
app-store-review-arbitrageFetches low-star App Store and Google Play reviews, clusters them into broken-promise patterns, and generates a ranked copy brief with positioning opportunities.
blog-cover-generatorUse when the user asks to generate a blog cover image, thumbnail, or article header. Automatically uses modern typography, brand logos, and Google Search grounding to create beautiful 16:9 images with Gemini 3.1 Flash Image Preview.
brand-alchemyWorld-class brand strategist and naming expert. Uses an interrogation-led discovery phase to extract your brand's DNA, then applies scientific naming frameworks (Phonosemantics) and automated multi-TLD domain checking.
claude-md-generatorUse when the user asks to generate or update a project's CLAUDE or AGENTS context file from a codebase scan. Writes a focused file under 100 lines containing only the non-obvious build commands, conventions, and gotchas Claude Code needs.
cold-email-verifierUse when the user wants to verify cold emails, enrich a lead list, or autonomously guess email addresses from a CSV using ValidEmail.co or the open-source Reacher engine.
company-radarCompetitive intelligence orchestrator tracking companies across 8+ platforms (GitHub, Twitter, Reddit, HN, PH, YC Jobs) with heat scores and AI briefings.
competitor-pr-finderGive it your product URL or description. It finds your top 5 competitors, runs three-track PR research across all of them (editorial, podcasts, communities), identifies which channels appear most frequently, looks up the journalist or host for each, and returns a tiered outreach list with story angles and ready-to-send cold pitch drafts tailored to your product. Use when asked to find PR opportunities, discover where competitors got featured, build a media outreach list, find which journalists cover my space, or get pitch templates for press coverage.
cook-the-blogGenerate high-converting, deep-dive growth case studies in MDX format. Use this skill when asked to write a case study or blog post about a company's growth, tech stack, or product-led strategy. It handles the full pipeline (researching the company via Tavily, generating a 16:9 cover image, quality checking the draft, uploading assets to cloud storage, and pushing directly to the target repository).
dependency-update-botScans your project for outdated npm, pip, Cargo, Go, or Ruby packages. Runs a CVE security audit. Fetches changelogs, summarizes breaking changes with Gemini, and opens one PR per risk group (patch, minor, major). Includes Diagnosis Mode for install conflicts. Use when asked to update dependencies, check for outdated packages, open dependency PRs, scan for package updates, audit for CVEs, or flag breaking changes in upgrades. Trigger when a user says "check for outdated packages", "update my dependencies", "open PRs for dependency updates", "scan for CVEs", or "which packages need upgrading".
docs-from-codeGenerates and updates README.md and API reference docs by reading your codebase's functions, routes, types, schemas, and architecture. Uses graphify to build a knowledge graph first, then writes accurate docs from it. Use when asked to write docs, generate a README, document an API, update stale docs, create an API reference from code, add an architecture section, or document a project in any language. Trigger when a user says their docs are missing, outdated, or wants to document their codebase without writing it manually.