forked from cybersecurity-team/TorBot
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlink.py
More file actions
122 lines (101 loc) · 3.07 KB
/
Copy pathlink.py
File metadata and controls
122 lines (101 loc) · 3.07 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
"""
This module is used to create a LinkNode that can be consumued by a LinkTree
and contains useful Link methods
"""
import requests
import requests.exceptions
import validators
from bs4 import BeautifulSoup
from .utils import multi_thread
from .color import color
def get_emails(node):
"""Finds all emails associated with node
Args:
node (LinkNode): node used to get emails from
Returns:
emails (list): list of emails
"""
emails = []
for child in node.children:
link = child.get('href')
if link and 'mailto' in link:
email_addr = link.split(':')
if LinkNode.valid_email(email_addr[1]) and len(email_addr) > 1:
emails.append(email_addr[1])
return emails
def get_links(node):
"""Finds all links associated with node
Args:
node (LinkNode): node used to get links from
Returns:
links (list): list of links
"""
def retrieve_link(child):
link = child.get('href')
if link and LinkNode.valid_link(link):
return link
return None
return multi_thread(node.children, retrieve_link)
class LinkNode:
"""Represents link node in a link tree
Attributes:
link (str): link to be used as node
"""
def __init__(self, link):
# If link has invalid form, throw an error
if not self.valid_link(link):
raise ValueError("Invalid link format.")
self._children = []
self._emails = []
self._links = []
# Attempts to connect to link, throws an error if link is unreachable
try:
self.response = requests.get(link)
except (requests.exceptions.ChunkedEncodingError,
requests.exceptions.HTTPError,
requests.exceptions.ConnectionError,
ConnectionError) as err:
raise err
self._node = BeautifulSoup(self.response.text, 'html.parser')
if not self._node.title:
self.name = "TITLE NOT FOUND"
self.status = color(link, 'yellow')
else:
self.name = self._node.title.string
self.status = color(link, 'green')
@property
def emails(self):
"""
Getter for node emails
"""
if not self._emails:
self._emails = get_emails(self)
return self._emails
@property
def links(self):
"""
Getter for node links
"""
if not self._links:
self._links = get_links(self)
return self._links
@property
def children(self):
"""
Getter for node children
"""
if not self._children:
self._children = self._node.find_all('a')
return self._children
@staticmethod
def valid_email(email):
"""Static method used to validate emails"""
if validators.email(email):
return True
return False
@staticmethod
def valid_link(link):
"""Static method used to validate links"""
if validators.url(link):
return True
return False