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)