Spaces:
Sleeping
Sleeping
Simon commited on
Commit ·
c562ed5
1
Parent(s): 9147d47
Add functionality to load and process legitimate URLs from CSV files (#3)
Browse files
.gitattributes
CHANGED
|
@@ -1 +1,3 @@
|
|
| 1 |
src/phising_detection/data/phishing-links-ACTIVE.txt filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
|
|
|
| 1 |
src/phising_detection/data/phishing-links-ACTIVE.txt filter=lfs diff=lfs merge=lfs -text
|
| 2 |
+
src/phising_detection/data/legitimate-urls.txt filter=lfs diff=lfs merge=lfs -text
|
| 3 |
+
src/phising_detection/data/top-1m.csv filter=lfs diff=lfs merge=lfs -text
|
.gitignore
CHANGED
|
@@ -102,4 +102,5 @@ dmypy.json
|
|
| 102 |
.pytype/
|
| 103 |
|
| 104 |
# Ruff
|
| 105 |
-
.ruff_cache/
|
|
|
|
|
|
| 102 |
.pytype/
|
| 103 |
|
| 104 |
# Ruff
|
| 105 |
+
.ruff_cache/
|
| 106 |
+
/CLAUDE.md
|
examples/load_legitimate_urls_example.py
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Example script showing how to load legitimate URLs into a DataFrame."""
|
| 2 |
+
|
| 3 |
+
import sys
|
| 4 |
+
from pathlib import Path
|
| 5 |
+
|
| 6 |
+
# Add src directory to Python path
|
| 7 |
+
project_root = Path(__file__).parent.parent
|
| 8 |
+
sys.path.insert(0, str(project_root / "src"))
|
| 9 |
+
|
| 10 |
+
from phising_detection.data import load_phishing_urls
|
| 11 |
+
|
| 12 |
+
# Load legitimate URLs from the file (using is_phishing=False)
|
| 13 |
+
df = load_phishing_urls("../src/phising_detection/data/legitimate-urls.txt", is_phishing=False)
|
| 14 |
+
|
| 15 |
+
# Display basic information
|
| 16 |
+
print(f"Loaded {len(df)} legitimate URLs")
|
| 17 |
+
print(f"\nDataFrame shape: {df.shape}")
|
| 18 |
+
print(f"\nColumn names: {df.columns.tolist()}")
|
| 19 |
+
print("\nFirst 5 rows:")
|
| 20 |
+
print(df.head())
|
| 21 |
+
|
| 22 |
+
# Display summary statistics
|
| 23 |
+
print("\nDataset info:")
|
| 24 |
+
print(df.info())
|
| 25 |
+
|
| 26 |
+
# Check for duplicates
|
| 27 |
+
duplicates = df['url'].duplicated().sum()
|
| 28 |
+
print(f"\nNumber of duplicate URLs: {duplicates}")
|
src/phising_detection/data/legitimate-urls.txt
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:910be3bd462bb93fb74c2538037e41830129c03f80e8ed3f85ed09b8eb7201ac
|
| 3 |
+
size 14433775
|
src/phising_detection/data/load_data.py
CHANGED
|
@@ -42,4 +42,24 @@ def load_phishing_urls(
|
|
| 42 |
|
| 43 |
return df
|
| 44 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 45 |
|
|
|
|
| 42 |
|
| 43 |
return df
|
| 44 |
|
| 45 |
+
def convert_csv_to_urls(csv_path: Union[str, Path], output_path: Union[str, Path]) -> None:
|
| 46 |
+
"""
|
| 47 |
+
Convert a CSV file containing URLs to a text file with one URL per line.
|
| 48 |
+
|
| 49 |
+
Args:
|
| 50 |
+
csv_path: Path to the input CSV file.
|
| 51 |
+
output_path: Path to the output text file.
|
| 52 |
+
"""
|
| 53 |
+
csv_path = Path(csv_path)
|
| 54 |
+
output_path = Path(output_path)
|
| 55 |
+
|
| 56 |
+
if not csv_path.exists():
|
| 57 |
+
raise FileNotFoundError(f"CSV file not found: {csv_path}")
|
| 58 |
+
|
| 59 |
+
# Read CSV and extract domains
|
| 60 |
+
df = pd.read_csv(csv_path, header=None, names=['rank', 'domain'])
|
| 61 |
+
|
| 62 |
+
# Write domains to text file
|
| 63 |
+
output_path.write_text('\n'.join(df['domain']))
|
| 64 |
+
|
| 65 |
|
src/phising_detection/data/top-1m.csv
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:515899ed08b354920bac5aa60b351d25b8374f79a3f1bd7716a4f26b1c570ae2
|
| 3 |
+
size 22322672
|
tests/test_load_data.py
CHANGED
|
@@ -106,3 +106,43 @@ class TestLoadPhishingUrls:
|
|
| 106 |
|
| 107 |
assert df['url_id'].is_unique
|
| 108 |
assert len(df['url_id'].unique()) == len(df)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 106 |
|
| 107 |
assert df['url_id'].is_unique
|
| 108 |
assert len(df['url_id'].unique()) == len(df)
|
| 109 |
+
|
| 110 |
+
|
| 111 |
+
class TestLoadLegitimateUrls:
|
| 112 |
+
"""Tests for loading legitimate URLs using load_phishing_urls with is_phishing=False."""
|
| 113 |
+
|
| 114 |
+
def test_load_legitimate_urls_basic(self, temp_legitimate_file, sample_legitimate_urls):
|
| 115 |
+
"""Test basic loading of legitimate URLs."""
|
| 116 |
+
df = load_phishing_urls(temp_legitimate_file, is_phishing=False)
|
| 117 |
+
|
| 118 |
+
# Check DataFrame shape
|
| 119 |
+
assert len(df) == len(sample_legitimate_urls)
|
| 120 |
+
assert df.shape[1] == 3 # url_id, url, is_phishing
|
| 121 |
+
|
| 122 |
+
# Check all are labeled as non-phishing
|
| 123 |
+
assert all(df['is_phishing'] == 0)
|
| 124 |
+
|
| 125 |
+
def test_load_legitimate_urls_content(self, temp_legitimate_file, sample_legitimate_urls):
|
| 126 |
+
"""Test that legitimate URLs are loaded correctly."""
|
| 127 |
+
df = load_phishing_urls(temp_legitimate_file, is_phishing=False)
|
| 128 |
+
|
| 129 |
+
# Check URLs match
|
| 130 |
+
assert df['url'].tolist() == sample_legitimate_urls
|
| 131 |
+
|
| 132 |
+
# Check url_ids are sequential
|
| 133 |
+
assert df['url_id'].tolist() == list(range(len(sample_legitimate_urls)))
|
| 134 |
+
|
| 135 |
+
def test_combined_phishing_and_legitimate(
|
| 136 |
+
self, temp_phishing_file, temp_legitimate_file
|
| 137 |
+
):
|
| 138 |
+
"""Test loading and combining phishing and legitimate URLs."""
|
| 139 |
+
phishing_df = load_phishing_urls(temp_phishing_file, is_phishing=True)
|
| 140 |
+
legitimate_df = load_phishing_urls(temp_legitimate_file, is_phishing=False)
|
| 141 |
+
|
| 142 |
+
# Combine datasets
|
| 143 |
+
combined_df = pd.concat([phishing_df, legitimate_df], ignore_index=True)
|
| 144 |
+
|
| 145 |
+
# Check that we have both types
|
| 146 |
+
assert (combined_df['is_phishing'] == 1).sum() == len(phishing_df)
|
| 147 |
+
assert (combined_df['is_phishing'] == 0).sum() == len(legitimate_df)
|
| 148 |
+
assert len(combined_df) == len(phishing_df) + len(legitimate_df)
|