import streamlit as st import requests import whois import socket import ssl from bs4 import BeautifulSoup from datetime import datetime import matplotlib.pyplot as plt from wordcloud import WordCloud # تم إزالة TextBlob و NLTK # إعداد العربية في Streamlit st.set_page_config(page_title="أداة تحليل المواقع", layout="wide") def get_ssl_expiry_date(hostname): try: context = ssl.create_default_context() with socket.create_connection((hostname, 443), timeout=3) as sock: with context.wrap_socket(sock, server_hostname=hostname) as ssock: ssl_info = ssock.getpeercert() expire_date = datetime.strptime(ssl_info['notAfter'], '%b %d %H:%M:%S %Y %Z') days_left = (expire_date - datetime.utcnow()).days return days_left except Exception: return None def main(): st.title("🕵️‍♂️ أداة تحليل المواقع الشاملة") url = st.text_input("أدخل رابط الموقع (مثال: https://www.example.com)") if st.button("تحليل") and url: if not url.startswith("http"): url = "http://" + url try: response = requests.get(url, timeout=5) status_code = response.status_code if status_code != 200: st.error(f"الموقع غير متاح. رمز الحالة: {status_code}") return # تحليل SEO soup = BeautifulSoup(response.content, 'html.parser') title = soup.title.string.strip() if soup.title else "لم يتم العثور على وسم العنوان" meta_desc = soup.find('meta', attrs={'name': 'description'}) meta_desc_content = meta_desc['content'].strip() if meta_desc else "لم يتم العثور على ميتا الوصف" # تحليل الكلمات المفتاحية (بدون TextBlob و NLTK) texts = soup.get_text() # تقسيم النص إلى كلمات واستبعاد الكلمات الشائعة words = texts.lower().split() common_words = set(['و', 'في', 'من', 'على', 'أن', 'إلى', 'عن', 'هو', 'مع', 'هذا', 'ما', 'لم', 'كما', 'كل']) filtered_words = [word for word in words if word.isalpha() and word not in common_words] word_counts = {} for word in filtered_words: word_counts[word] = word_counts.get(word, 0) + 1 sorted_keywords = sorted(word_counts.items(), key=lambda x: x[1], reverse=True)[:10] # رسم سحابة الكلمات wordcloud = WordCloud(width=800, height=400, background_color='white', font_path='arial').generate(' '.join(filtered_words)) fig_wc, ax_wc = plt.subplots(figsize=(12, 6)) ax_wc.imshow(wordcloud, interpolation='bilinear') ax_wc.axis('off') # معلومات WHOIS domain = url.replace("http://", "").replace("https://", "").split('/')[0] domain_info = whois.whois(domain) # فحص SSL ssl_days_left = get_ssl_expiry_date(domain) if ssl_days_left is not None: ssl_status = f"شهادة SSL تنتهي صلاحيتها خلال {ssl_days_left} يومًا" else: ssl_status = "لم يتم العثور على شهادة SSL" # فحص الأمان security_score = 0 headers = response.headers security_headers = { 'X-Frame-Options': 'حماية من النقر', 'X-Content-Type-Options': 'منع نوع المحتوى', 'Content-Security-Policy': 'سياسة أمان المحتوى', 'Strict-Transport-Security': 'أمان النقل الصارم', 'Referrer-Policy': 'سياسة المرجع' } for header in security_headers: if header in headers: security_score += 10 # حساب التقييم الكلي total_score = security_score if title != "لم يتم العثور على وسم العنوان": total_score += 15 if meta_desc_content != "لم يتم العثور على ميتا الوصف": total_score += 15 if ssl_days_left is not None: total_score += 20 # الحد الأقصى للتقييم هو 100 if total_score > 100: total_score = 100 # عرض النتائج st.header("📊 نتائج التحليل") col1, col2 = st.columns(2) with col1: st.subheader("تحليل SEO") st.write(f"**وسم العنوان:** {title}") st.write(f"**ميتا الوصف:** {meta_desc_content}") st.subheader("أهم الكلمات تكرارًا") for word, count in sorted_keywords: st.write(f"- {word}: {count} مرة") st.pyplot(fig_wc) with col2: st.subheader("تحليل الأمان") st.write(f"**حالة SSL:** {ssl_status}") st.write("**عناوين الأمان:**") for header, desc in security_headers.items(): if header in headers: st.write(f"- {header}: متوفر ({desc})") else: st.write(f"- {header}: غير متوفر ({desc})") st.subheader("معلومات WHOIS") st.write(f"**اسم النطاق:** {domain_info.domain_name}") st.write(f"**المسجل:** {domain_info.registrar}") st.write(f"**تاريخ الإنشاء:** {domain_info.creation_date}") st.write(f"**تاريخ الانتهاء:** {domain_info.expiration_date}") st.header("🏆 التقييم الكلي") st.write(f"**التقييم الإجمالي:** {total_score} / 100") # رسم بياني للتقييم labels = ['SEO', 'الأمان', 'SSL', 'أخرى'] sizes = [30 if title != "لم يتم العثور على وسم العنوان" else 0, security_score, 20 if ssl_days_left is not None else 0, 100 - (30 + security_score + (20 if ssl_days_left is not None else 0))] fig_score, ax_score = plt.subplots() ax_score.pie(sizes, labels=labels, autopct='%1.1f%%', startangle=140) ax_score.axis('equal') st.pyplot(fig_score) st.header("💡 اقتراحات للتحسين") suggestions = [] if title == "لم يتم العثور على وسم العنوان": suggestions.append("- أضف وسم العنوان إلى صفحتك الرئيسية.") if meta_desc_content == "لم يتم العثور على ميتا الوصف": suggestions.append("- أضف ميتا الوصف إلى صفحتك لتحسين SEO.") if ssl_days_left is None: suggestions.append("- قم بتثبيت شهادة SSL لتأمين موقعك باستخدام HTTPS.") for header in security_headers: if header not in headers: suggestions.append(f"- أضف عنوان {header} ({security_headers[header]}) لتعزيز الأمان.") if suggestions: for suggestion in suggestions: st.write(suggestion) else: st.write("لا توجد اقتراحات. الموقع يبدو ممتازًا!") except Exception as e: st.error(f"حدث خطأ: {e}") if __name__ == "__main__": main()