The dataset, end to end

Every number on this site comes from a training run you can reproduce. Here is where the data came from, what was thrown away, and what survived into the model.

88,647
Total URLs
58,000
Legitimate
30,647
Phishing
70,917
Train rows
17,730
Test rows
34
Features

Sources

Pipeline

01

Ingest

Download the raw CSV, assert the schema, and normalise the label column to {0,1}.

02

Clean

Drop null rows, strip duplicate URLs, and clip absurd outliers on length columns.

03

Engineer

Reduce to the 34 features computable from a URL string alone — no WHOIS, no DNS, no network.

04

Split & train

80/20 stratified split, standardise on train statistics only, fit class-balanced logistic regression.

Class balance

65.4%
34.6%
Legitimate · 58,000 Phishing · 30,647

The corpus is imbalanced roughly 2:1, so training uses class_weight="balanced" — otherwise the model learns to under-predict phishing, which is exactly the failure mode that matters.

What was deliberately excluded

  • WHOIS age and registrar fields — unavailable in the browser and stale in the source data.
  • DNS / SPF / TTL lookups — require network calls and leak the URL being checked.
  • Page content and TLS certificate features — would mean visiting the suspicious page.
  • Third-party reputation scores — turn the tool into a proxy for someone else's blocklist.