joermd commited on
Commit
9875a3c
·
verified ·
1 Parent(s): 0a58343

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +120 -63
app.py CHANGED
@@ -5,110 +5,167 @@ import socket
5
  import ssl
6
  from bs4 import BeautifulSoup
7
  from datetime import datetime
 
 
 
 
 
 
 
8
 
9
  def get_ssl_expiry_date(hostname):
10
  try:
11
  context = ssl.create_default_context()
12
- with socket.create_connection((hostname, 443)) as sock:
13
  with context.wrap_socket(sock, server_hostname=hostname) as ssock:
14
  ssl_info = ssock.getpeercert()
15
  expire_date = datetime.strptime(ssl_info['notAfter'], '%b %d %H:%M:%S %Y %Z')
16
  days_left = (expire_date - datetime.utcnow()).days
17
  return days_left
18
- except Exception as e:
19
  return None
20
 
21
  def main():
22
- st.title("Website Analysis Tool")
23
 
24
- url = st.text_input("Enter the website URL (e.g., https://www.example.com)")
25
 
26
- if st.button("Analyze") and url:
27
  if not url.startswith("http"):
28
  url = "http://" + url
29
 
30
  try:
31
- response = requests.get(url)
32
  status_code = response.status_code
33
 
34
- # Basic SEO Analysis
 
 
 
 
35
  soup = BeautifulSoup(response.content, 'html.parser')
36
- title = soup.title.string if soup.title else "No title tag found"
37
  meta_desc = soup.find('meta', attrs={'name': 'description'})
38
- meta_desc_content = meta_desc['content'] if meta_desc else "No meta description found"
 
 
 
 
 
 
 
 
 
 
 
 
39
 
40
- # WHOIS Information
41
  domain = url.replace("http://", "").replace("https://", "").split('/')[0]
42
  domain_info = whois.whois(domain)
43
 
44
- # SSL Certificate Check
45
  ssl_days_left = get_ssl_expiry_date(domain)
46
  if ssl_days_left is not None:
47
- ssl_status = f"SSL Certificate expires in {ssl_days_left} days"
48
  else:
49
- ssl_status = "No SSL Certificate found"
50
 
51
- # Security Headers Check
52
  security_score = 0
53
  headers = response.headers
54
 
55
- if 'X-Frame-Options' in headers:
56
- security_score += 10
57
- if 'X-Content-Type-Options' in headers:
58
- security_score += 10
59
- if 'Content-Security-Policy' in headers:
60
- security_score += 10
61
- if 'Strict-Transport-Security' in headers:
62
- security_score += 10
63
- if 'Referrer-Policy' in headers:
64
- security_score += 10
65
-
66
- # Overall Score Calculation
 
67
  total_score = security_score
68
- if title != "No title tag found":
69
- total_score += 20
70
- if meta_desc_content != "No meta description found":
71
- total_score += 20
72
  if ssl_days_left is not None:
73
  total_score += 20
74
 
75
- st.subheader("SEO Analysis")
76
- st.write(f"**Title Tag:** {title}")
77
- st.write(f"**Meta Description:** {meta_desc_content}")
78
-
79
- st.subheader("Security Analysis")
80
- st.write(f"**SSL Status:** {ssl_status}")
81
- st.write("**Security Headers:**")
82
- for header in ['X-Frame-Options', 'X-Content-Type-Options', 'Content-Security-Policy',
83
- 'Strict-Transport-Security', 'Referrer-Policy']:
84
- if header in headers:
85
- st.write(f"- {header}: {headers[header]}")
86
- else:
87
- st.write(f"- {header}: Not Found")
88
-
89
- st.subheader("WHOIS Information")
90
- st.write(f"**Domain Name:** {domain_info.domain_name}")
91
- st.write(f"**Registrar:** {domain_info.registrar}")
92
- st.write(f"**Creation Date:** {domain_info.creation_date}")
93
- st.write(f"**Expiration Date:** {domain_info.expiration_date}")
94
-
95
- st.subheader("Overall Score")
96
- st.write(f"**Total Score:** {total_score} / 100")
97
-
98
- st.subheader("Suggestions for Improvement")
99
- if title == "No title tag found":
100
- st.write("- Add a title tag to your homepage.")
101
- if meta_desc_content == "No meta description found":
102
- st.write("- Add a meta description to your homepage.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
103
  if ssl_days_left is None:
104
- st.write("- Install an SSL certificate to secure your site with HTTPS.")
105
- for header in ['X-Frame-Options', 'X-Content-Type-Options', 'Content-Security-Policy',
106
- 'Strict-Transport-Security', 'Referrer-Policy']:
107
  if header not in headers:
108
- st.write(f"- Add the {header} header to improve security.")
 
 
 
 
 
 
109
 
110
  except Exception as e:
111
- st.error(f"An error occurred: {e}")
112
 
113
  if __name__ == "__main__":
114
  main()
 
5
  import ssl
6
  from bs4 import BeautifulSoup
7
  from datetime import datetime
8
+ import matplotlib.pyplot as plt
9
+ from wordcloud import WordCloud
10
+ from langdetect import detect
11
+ from textblob import TextBlob
12
+
13
+ # إعداد العربية في Streamlit
14
+ st.set_page_config(page_title="أداة تحليل المواقع", layout="wide")
15
 
16
  def get_ssl_expiry_date(hostname):
17
  try:
18
  context = ssl.create_default_context()
19
+ with socket.create_connection((hostname, 443), timeout=3) as sock:
20
  with context.wrap_socket(sock, server_hostname=hostname) as ssock:
21
  ssl_info = ssock.getpeercert()
22
  expire_date = datetime.strptime(ssl_info['notAfter'], '%b %d %H:%M:%S %Y %Z')
23
  days_left = (expire_date - datetime.utcnow()).days
24
  return days_left
25
+ except Exception:
26
  return None
27
 
28
  def main():
29
+ st.title("🕵️‍♂️ أداة تحليل المواقع الشاملة")
30
 
31
+ url = st.text_input("أدخل رابط الموقع (مثال: https://www.example.com)")
32
 
33
+ if st.button("تحليل") and url:
34
  if not url.startswith("http"):
35
  url = "http://" + url
36
 
37
  try:
38
+ response = requests.get(url, timeout=5)
39
  status_code = response.status_code
40
 
41
+ if status_code != 200:
42
+ st.error(f"الموقع غير متاح. رمز الحالة: {status_code}")
43
+ return
44
+
45
+ # تحليل SEO
46
  soup = BeautifulSoup(response.content, 'html.parser')
47
+ title = soup.title.string.strip() if soup.title else "لم يتم العثور على وسم العنوان"
48
  meta_desc = soup.find('meta', attrs={'name': 'description'})
49
+ meta_desc_content = meta_desc['content'].strip() if meta_desc else "لم يتم العثور على ميتا الوصف"
50
+
51
+ # تحليل الكلمات المفتاحية
52
+ texts = soup.get_text()
53
+ blob = TextBlob(texts)
54
+ keywords = blob.word_counts.items()
55
+ sorted_keywords = sorted(keywords, key=lambda x: x[1], reverse=True)[:10]
56
+
57
+ # رسم سحابة الكلمات
58
+ wordcloud = WordCloud(width=800, height=400, background_color='white').generate(texts)
59
+ fig_wc, ax_wc = plt.subplots(figsize=(12, 6))
60
+ ax_wc.imshow(wordcloud, interpolation='bilinear')
61
+ ax_wc.axis('off')
62
 
63
+ # معلومات WHOIS
64
  domain = url.replace("http://", "").replace("https://", "").split('/')[0]
65
  domain_info = whois.whois(domain)
66
 
67
+ # فحص SSL
68
  ssl_days_left = get_ssl_expiry_date(domain)
69
  if ssl_days_left is not None:
70
+ ssl_status = f"شهادة SSL تنتهي صلاحيتها خلال {ssl_days_left} يومًا"
71
  else:
72
+ ssl_status = "لم يتم العثور على شهادة SSL"
73
 
74
+ # فحص الأمان
75
  security_score = 0
76
  headers = response.headers
77
 
78
+ security_headers = {
79
+ 'X-Frame-Options': 'حماية من النقر',
80
+ 'X-Content-Type-Options': 'منع نوع المحتوى',
81
+ 'Content-Security-Policy': 'سياسة أمان المحتوى',
82
+ 'Strict-Transport-Security': 'أمان النقل الصارم',
83
+ 'Referrer-Policy': 'سياسة المرجع'
84
+ }
85
+
86
+ for header in security_headers:
87
+ if header in headers:
88
+ security_score += 10
89
+
90
+ # حساب التقييم الكلي
91
  total_score = security_score
92
+ if title != "لم يتم العثور على وسم العنوان":
93
+ total_score += 15
94
+ if meta_desc_content != "لم يتم العثور على ميتا الوصف":
95
+ total_score += 15
96
  if ssl_days_left is not None:
97
  total_score += 20
98
 
99
+ # الحد الأقصى للتقييم هو 100
100
+ if total_score > 100:
101
+ total_score = 100
102
+
103
+ # عرض النتائج
104
+ st.header("📊 نتائج التحليل")
105
+
106
+ col1, col2 = st.columns(2)
107
+
108
+ with col1:
109
+ st.subheader("تحليل SEO")
110
+ st.write(f"**وسم العنوان:** {title}")
111
+ st.write(f"**ميتا الوصف:** {meta_desc_content}")
112
+
113
+ st.subheader("أهم الكلمات تكرارًا")
114
+ for word, count in sorted_keywords:
115
+ st.write(f"- {word}: {count} مرة")
116
+
117
+ st.pyplot(fig_wc)
118
+
119
+ with col2:
120
+ st.subheader("تحليل الأمان")
121
+ st.write(f"**حالة SSL:** {ssl_status}")
122
+ st.write("**عناوين الأمان:**")
123
+ for header, desc in security_headers.items():
124
+ if header in headers:
125
+ st.write(f"- {header}: متوفر ({desc})")
126
+ else:
127
+ st.write(f"- {header}: غير متوفر ({desc})")
128
+
129
+ st.subheader("معلومات WHOIS")
130
+ st.write(f"**اسم النطاق:** {domain_info.domain_name}")
131
+ st.write(f"**المسجل:** {domain_info.registrar}")
132
+ st.write(f"**تاريخ الإنشاء:** {domain_info.creation_date}")
133
+ st.write(f"**تاريخ الانتهاء:** {domain_info.expiration_date}")
134
+
135
+ st.header("🏆 التقييم الكلي")
136
+ st.write(f"**التقييم الإجمالي:** {total_score} / 100")
137
+
138
+ # رسم بياني للتقييم
139
+ labels = ['SEO', 'الأمان', 'SSL', 'أخرى']
140
+ sizes = [30 if title != "لم يتم العثور على وسم العنوان" else 0,
141
+ security_score,
142
+ 20 if ssl_days_left is not None else 0,
143
+ 100 - (30 + security_score + (20 if ssl_days_left is not None else 0))]
144
+ fig_score, ax_score = plt.subplots()
145
+ ax_score.pie(sizes, labels=labels, autopct='%1.1f%%', startangle=140)
146
+ ax_score.axis('equal')
147
+ st.pyplot(fig_score)
148
+
149
+ st.header("💡 اقتراحات للتحسين")
150
+ suggestions = []
151
+ if title == "لم يتم العثور على وسم العنوان":
152
+ suggestions.append("- أضف وسم العنوان إلى صفحتك الرئيسية.")
153
+ if meta_desc_content == "لم يتم العثور على ميتا الوصف":
154
+ suggestions.append("- أضف ميتا الوصف إلى صفحتك لتحسين SEO.")
155
  if ssl_days_left is None:
156
+ suggestions.append("- قم بتثبيت شهادة SSL لتأمين موقعك باستخدام HTTPS.")
157
+ for header in security_headers:
 
158
  if header not in headers:
159
+ suggestions.append(f"- أضف عنوان {header} ({security_headers[header]}) لتعزيز الأمان.")
160
+
161
+ if suggestions:
162
+ for suggestion in suggestions:
163
+ st.write(suggestion)
164
+ else:
165
+ st.write("لا توجد اقتراحات. الموقع يبدو ممتازًا!")
166
 
167
  except Exception as e:
168
+ st.error(f"حدث خطأ: {e}")
169
 
170
  if __name__ == "__main__":
171
  main()