A daily automated scraper for quantitative trading internships, competitions, and programs targeted at first-year Australian undergraduate students (particularly University of Melbourne students).
| Source Type | Examples | Target |
|---|---|---|
| Company Career Pages | Optiver, IMC, SIG, Jane Street, Citadel, Akuna, HRT, Jump, Five Rings, Flow Traders, DRW, Tower, XTX, Belvedere, Headlands, Quantlab, Walleye, Radix | Direct applications |
| Aggregator Boards | GradConnection, Prosple, Indeed AU | Broad coverage |
| Competitions & Programs | IMC Trading Challenge, Optiver Academy, SIG Grid, WorldQuant Challenge, QuantLeague, Citadel Quant, Jane Street Academy | First-year CV builders |
- 🎯 First-year focused — Filters for roles suitable for 1st/2nd year undergrads
- 🇦🇺 Australia-aware — Prioritizes Sydney, Melbourne, Brisbane, Perth, Adelaide, Canberra, ANZ, APAC, remote-AU
- 📊 Quant-trading specific — Keyword matching for quant researcher, quant trader, systematic trading, market making, HFT, prop trading, quant developer
- 🤖 Daily automation — Runs every morning at ~07:30 Melbourne time via GitHub Actions
- 📁 Versioned data — Append-only JSONL log + human-readable CSV committed to repo
- 🔍 Zero infra — Just browse the
data/folder in GitHub to see latest opportunities
# Clone
git clone https://github.com/<your-username>/internship-scraper.git
cd internship-scraper
# Install dependencies
pip install -r requirements.txt
pip install -e .
# Run a full scrape
python -m scraper scrape --verbose
# View top opportunities
python -m scraper top --limit 20
# View statistics
python -m scraper stats
# List all opportunities
python -m scraper list| Command | Description |
|---|---|
scrape |
Run all scrapers and update data/ |
top -n 20 |
Show top 20 ranked opportunities |
stats |
Show summary statistics |
list |
List all opportunities (raw) |
# Only company career pages
python -m scraper scrape --category company
# Only aggregators
python -m scraper scrape --category aggregator
# Only competitions
python -m scraper scrape --category competition
# Multiple categories
python -m scraper scrape -c company -c competitionThe scraper maintains two files in data/:
| File | Format | Description |
|---|---|---|
opportunities.jsonl |
JSON Lines | Append-only master log, one opportunity per line |
latest.csv |
CSV | Human-readable snapshot, ranked by relevance |
{
"id": "a1b2c3d4e5f6g7h8", // SHA256 hash of URL+title (dedup key)
"url": "https://careers.optiver.com/jobs/123",
"title": "Quantitative Trading Summer Intern",
"company": "Optiver",
"description": "Full description text...",
"location": "Sydney, Australia",
"employment_type": "internship",
"posted_date": "2024-01-15T00:00:00Z",
"application_deadline": "2024-03-01T23:59:00Z",
"start_date": "2024-11-01",
"end_date": "2025-02-01",
"source": "optiver",
"source_category": "company_page",
"scraped_at": "2024-01-20T07:30:00Z",
"quant_relevance_score": 0.95,
"first_year_suitable": true,
"keywords_matched": ["quantitative trading", "summer intern", "internship"],
"location_match": true
}The workflow runs automatically daily. To enable:
- Push this repo to GitHub
- Go to Settings → Actions → General → Workflow permissions
- Select "Read and write permissions" (needed to commit data files)
- Save
The workflow will:
- Run daily at ~07:30 Melbourne time
- Commit new opportunities to
data/ - Push the commit (you'll see it in your repo history)
Edit src/scraper/sources/company_pages.py:
# Add to COMPANY_SCRAPERS dict
"new-company": GreenhouseSource("New Company", "greenhouse-board-token"),Find the Greenhouse board token from the company's careers page URL: https://boards.greenhouse.io/<board_token>
Create a new class in src/scraper/sources/aggregators.py inheriting from AggregatorSource, then add to AGGREGATOR_SCRAPERS.
Create src/scraper/sources/unimelb.py with a scraper for careers.unimelb.edu.au or the student portal, then import in main.py.
Edit src/scraper/config.py:
QUANT_TRADING_KEYWORDS— Add/remove relevance keywordsEXCLUSION_KEYWORDS— Add roles to excludeAUSTRALIAN_LOCATIONS— Add location variants
internship-scraper/
├── .github/workflows/daily.yml # Daily CI workflow
├── data/ # Committed data files
│ ├── opportunities.jsonl # Append-only master log
│ └── latest.csv # Ranked CSV snapshot
├── src/scraper/
│ ├── __init__.py
│ ├── config.py # Keywords, companies, settings
│ ├── models.py # Opportunity dataclass
│ ├── sources/
│ │ ├── base.py # BaseSource abstract class
│ │ ├── company_pages.py # Greenhouse/Lever/Ashby/Workday scrapers
│ │ ├── aggregators.py # GradConnection, Prosple, Indeed AU
│ │ └── competitions.py # IMC Challenge, Optiver Academy, etc.
│ ├── filters.py # Ranking & filtering logic
│ ├── store.py # JSONL + CSV storage
│ └── main.py # CLI entrypoint
├── tests/test_filters.py
├── requirements.txt
├── pyproject.toml
└── README.md
As a first-year University of Melbourne student targeting quant trading, I found:
- Company career pages are scattered across different ATS platforms (Greenhouse, Lever, Ashby, Workday)
- Aggregators like GradConnection/Prosple have Australian focus but noisy results
- Competitions (IMC Trading Challenge, Optiver Academy, SIG Grid) are golden opportunities for first-years but easy to miss
- No existing tool combines all three with first-year + Australia + quant-trading filters
This scraper solves that.
See CONTRIBUTING.md for guidelines.
MIT License — see LICENSE.
Disclaimer: This tool scrapes publicly available job postings. Always verify details on the company's official careers page before applying. Respect robots.txt and rate limits.