Phishing URL Detector
Python, scikit-learn, pandas · 2026 · View the code on GitHub
The question
Phishing links are designed to look boring. How much of that disguise can a model see through using nothing but the URL string itself, no page content, no network calls, just the text?
What I built
A class-weighted random forest trained on ~160,000 labeled URLs from a public Kaggle dataset, using 7 lexical features I engineered by hand: has_https, url_length, num_dots, num_hyphens, has_ip, count_digits, and has_extension. Every line of this one is mine, no frameworks doing the thinking, which is exactly why it taught me the most.
What I found
The real lesson was the imbalance. The dataset has roughly 194 legitimate URLs for every phishing URL. A model that labels everything "safe" scores wonderfully on raw accuracy and catches nothing. So I used balanced class weights and judged the model on metrics that survive a skewed base rate, instead of quoting a headline accuracy number that the base rate hands you for free. The interesting part was never the model. It was refusing to trust the number.
The limit, and the plan
Lexical features cannot catch lookalike domains. go1gle.com reads as clean, because character by character it almost is. Version 2 adds edit-distance comparison against known brand names to flag character-substitution attacks, which is the gap this version cannot close on its own.