Job hunting is one of those things that looks simple until you do it every day.
Open a portal.
Search the same roles.
Change the location.
Read the experience requirement.
Check the skills.
Remove duplicate listings.
Remember which jobs you've already seen.
Repeat it all again tomorrow.
I didn't want to keep doing the repetitive part manually.
So I treated my own job search like an engineering problem.
As a Data Analytics / Data Science learner, I built a personal automation system that brings together multiple job sources, processes hundreds of listings, evaluates relevance, ranks opportunities, and tracks what has already been seen.
And I built it with a very deliberate philosophy:
This isn't a tool I built because I wanted another portfolio project.
I built it because I actually needed it.
The system is optimized around my current career stage and preferences:
| ๐ฏ Area | Current Focus |
|---|---|
| Primary roles | Data Analyst โข Data Analyst Intern โข Junior Data Analyst |
| Additional roles | Data Analytics Intern โข Data Science Intern |
| Secondary roles | BI Analyst โข Reporting Analyst โข MIS Analyst โข Analytics Associate |
| Experience | Fresher / Entry-Level / ~0โ1 year |
| Locations | Delhi โข Noida โข Gurgaon / Gurugram โข Remote |
| Priority skills | SQL โข Excel โข Power BI โข Python โข Pandas โข EDA |
| Freshness | Prefer recent opportunities |
| Final action | Human review before applying |
๐ MULTIPLE JOB SOURCES
โ
๐ฅ COLLECT RAW LISTINGS
โ
๐งน NORMALIZE & TRANSFORM
โ
๐ EXTRACT SKILLS / EXPERIENCE / ELIGIBILITY
โ
๐ฏ FILTER ROLE + LOCATION + EXPERIENCE + FRESHNESS
โ
โป๏ธ DETECT DUPLICATES & POSSIBLE REPOSTS
โ
๐ CALCULATE MATCH SCORE
โ
๐ก๏ธ ASSESS QUALITY + RISK
โ
๐ RANK RESULTS
โ
๐ TRACK NEW JOBS IN GOOGLE SHEETS
โ
๐ค HUMAN DECISION
The collector layer currently supports:
| Source | Role |
|---|---|
| ๐ต Adzuna | Job discovery |
| ๐ Jooble | Job discovery |
| ๐ฃ The Muse | Job discovery |
| ๐ Himalayas | Remote-focused discovery |
| ๐ Jobicy | Remote-focused discovery |
| ๐ Remotive | Remote-focused discovery |
The point isn't simply to collect more jobs.
The point is to avoid depending on one source and create a broader search surface before the filtering pipeline removes noise.
Each source returns job listings in its own structure.
The collector layer brings those listings into one pipeline.
Different APIs use different field names and formats.
The transformation layer standardizes:
- Company
- Role
- Location
- Work mode
- Salary
- Description
- URL
- Posted date
- Experience
- Eligibility
- Skills
- Job ID
The parser extracts signals from job descriptions.
SQL โข Microsoft Excel โข Power BI โข Python โข Pandas โข NumPy โข Data Cleaning โข EDA โข Statistical Analysis โข Data Visualization โข Feature Engineering โข MySQL โข Machine Learning โข Scikit-learn โข XGBoost โข Git โข GitHub โข Matplotlib โข Seaborn โข Plotly
The system evaluates:
- ๐ Location
- ๐ผ Role relevance
- ๐งโ๐ป Experience compatibility
- ๐ Freshness
The system checks:
- Same source + job ID
- Same job URL
- Identical descriptions
- Same company + role + similar description
- Same company + role + location + description similarity
Relevant skills, role relevance, experience, location, and supporting signals contribute to the match score.
The strongest opportunities rise to the top.
I intentionally avoided building an extremely hard filter.
Why?
Because real job descriptions are messy.
A good Data Analyst opening may:
- omit some skills,
- leave experience unknown,
- use different terminology,
- have an incomplete description,
- or appear slightly different across sources.
So the system follows:
That gives the pipeline a better balance between precision and recall.
| Decision | Meaning |
|---|---|
๐ข APPLY |
Very strong match worth prioritizing |
๐ข STRONG MATCH |
Highly relevant opportunity |
๐ก REVIEW |
Relevant, but manually verify |
๐ก CONSIDER |
Potentially useful |
โช SKIP |
Low relevance for the current profile |
๐ด DO NOT APPLY |
High risk or strong incompatibility |
This system does not blindly apply to jobs.
It helps me discover, evaluate, prioritize, and track opportunities.
The final application decision remains mine.
A job title alone doesn't tell the whole story.
The pipeline also considers job quality and potential scam risk.
This gives the final output another layer of context:
MATCH SCORE
+
QUALITY
+
RISK
=
BETTER DECISION
Relevant new opportunities can be stored in a personal Google Sheet.
Typical fields include:
Date โข Source โข Company โข Role โข Location โข Work Mode โข Experience โข Skills โข Score โข Risk โข Quality โข Decision โข Job URL
This turns the search process into a lightweight personal job-search database.
The automation tracks newly discovered job opportunities in a dedicated Google Sheet, keeping the search results structured, reviewable, and easy to act on.
The sheet captures the key decision-making fields used by the pipeline, including:
Date โข Source โข Company โข Role โข Location โข Work Mode โข Experience โข Skills โข Score โข Risk โข Quality โข Decision โข Job URL
This provides a practical view of how the automation turns filtered job listings into a personal, searchable job-tracking workflow.
The system keeps a local history of previously seen job URLs.
That means:
Seen before?
โ
โโโ YES โ already seen
โ
โโโ NO โ new opportunity
This is especially useful when multiple sources surface the same listing.
๐ Personal history remains outside the public repository.
The system can be scheduled with Windows Task Scheduler.
My personal workflow is configured around:
๐ Start: ~8:00 AM
๐ Repeat: every hour
So instead of manually opening the project again and again:
8:00 AM
โ
SEARCH
โ
FILTER
โ
SCORE
โ
TRACK
9:00 AM
โ
SEARCH AGAIN
10:00 AM
โ
SEARCH AGAIN
...
The machine handles the repetitive search cycle while I focus on learning, projects, applications, and interview preparation.
A real run can start with hundreds of raw listings and reduce them dramatically.
Example:
RAW JOBS: 800+
LOCATION REJECTED: 290+
ROLE REJECTED: 340+
OLD JOBS: 100+
And then surface something like:
๐ ICG Medical | Data Analyst
๐ Noida
๐งโ๐ป Experience: 1 year
๐ ๏ธ Skills: SQL, Power BI, Python, Reporting, Dashboarding
๐ Score: 86
๐ก๏ธ Risk: LOW
โญ Quality: HIGH
๐ฏ Decision: STRONG MATCH
The objective isn't:
"Show me as many jobs as possible."
The objective is:
"Show me the opportunities most worth my attention."
AI-Job-Search-Automation/
โ
โโโ config/
โ โโโ profile.yaml
โ
โโโ src/
โ โโโ collectors/
โ โ โโโ adzuna.py
โ โ โโโ the_muse.py
โ โ โโโ jooble.py
โ โ โโโ himalayas.py
โ โ โโโ jobicy.py
โ โ โโโ remotive.py
โ โ โโโ multi_source.py
โ โ
โ โโโ processing/
โ โ โโโ batch_processor.py
โ โ โโโ transform.py
โ โ โโโ job_parser.py
โ โ โโโ freshness.py
โ โ โโโ deduplication.py
โ โ โโโ location_eligibility.py
โ โ โโโ experience_eligibility.py
โ โ โโโ work_mode.py
โ โ โโโ scam_detector.py
โ โ โโโ quality.py
โ โ โโโ filters.py
โ โ
โ โโโ matching/
โ โ โโโ score.py
โ โ โโโ match_result.py
โ โ โโโ decision.py
โ โ โโโ ranking.py
โ โ
โ โโโ storage/
โ โโโ json_store.py
โ โโโ google_sheets.py
โ โโโ job_history.py
โ
โโโ run.py
โโโ requirements.txt
โโโ .env.example
โโโ .gitignore
โโโ LICENSE
โโโ README.md
| Component | Responsibility |
|---|---|
collectors/ |
Multi-source job collection |
processing/ |
Cleaning, parsing, filtering & deduplication |
matching/ |
Scoring, decisions & ranking |
storage/ |
JSON, history & Google Sheets |
config/ |
Personal job-search preferences |
run.py |
Main pipeline entry point |
git clone <YOUR_REPOSITORY_URL>
cd AI-Job-Search-Automation
python -m venv .venv
.venv\Scripts\activate
pip install -r requirements.txtCreate your local .env file and add the required API credentials.
Configure:
config/profile.yaml
Then:
python run.pyPrivate information is intentionally excluded from Git:
.env
credentials/
data/
.venv/
__pycache__/
*.pyc
Never publish API keys, Google credentials, or personal job history.
One of the most meaningful parts of this project was the development process itself.
I worked closely with AI throughout the build to accelerate:
- ๐งฉ architecture exploration
- ๐ debugging
- ๐ง implementation
- ๐ iteration
- ๐ง problem solving
- ๐งช testing ideas
- ๐ system design
But the project was driven by a real problem, my own requirements, and my decisions about how the system should behave.
AI was the development partner. I was the system designer and decision-maker.
That distinction matters to me.
The goal wasn't to ask AI for a random project.
The goal was to take my own problem, define the requirements, build the system, test it against real outputs, identify weaknesses, iterate, and turn it into something I can actually use.
This project brings together practical engineering concepts:
- ๐ Python
- ๐ REST APIs
- ๐ Multi-source data collection
- ๐งน Data transformation
- ๐ Regular expressions
- ๐ง Rule-based intelligence
- ๐ Scoring systems
- ๐ Ranking
- โป๏ธ Similarity-based deduplication
- ๐ก๏ธ Risk detection
- ๐ Google Sheets integration
- ๐พ Local persistence
- โฐ Windows automation
- ๐งฑ Modular architecture
- ๐ค AI-assisted development
More importantly:
The architecture leaves room for:
- ๐ Better semantic job matching
- ๐ข Stronger company-quality signals
- ๐ Improved work-mode detection
- ๐ฐ Better salary normalization
- ๐ฉ Email / notification integration
- ๐ Application-status tracking
- ๐ Historical job-search analytics
- ๐ง Ranking calibration from real application outcomes
- ๐ Additional job sources
The system can evolve without throwing away the existing architecture.
This is a personal job-discovery and decision-support system.
It does not guarantee:
- job availability
- listing accuracy
- recruiter response
- interviews
- selection
- application success
Third-party sources can provide incomplete, duplicated, outdated, or inconsistent information.
Always verify the original listing before applying.
I enjoy taking repetitive real-world problems and turning them into practical systems.
This project is one example of that approach:
Problem โ Data โ Logic โ Automation โ Better Workflow
Built for my journey.
Built to save time.
Built to keep moving forward. ๐

