|
import streamlit as st |
|
from streamlit_lottie import st_lottie |
|
from streamlit_option_menu import option_menu |
|
import requests |
|
import pandas as pd |
|
import plotly.express as px |
|
import plotly.graph_objects as go |
|
from datetime import datetime |
|
import httpx |
|
import asyncio |
|
import aiohttp |
|
from bs4 import BeautifulSoup |
|
import whois |
|
import ssl |
|
import socket |
|
import dns.resolver |
|
from urllib.parse import urlparse |
|
import json |
|
import numpy as np |
|
from selenium import webdriver |
|
from selenium.webdriver.chrome.options import Options |
|
from webdriver_manager.chrome import ChromeDriverManager |
|
from PIL import Image |
|
import io |
|
import time |
|
import matplotlib.pyplot as plt |
|
import seaborn as sns |
|
|
|
|
|
st.set_page_config( |
|
layout="wide", |
|
page_title="محلل المواقع المتقدم | Website Analyzer Pro", |
|
page_icon="🔍", |
|
initial_sidebar_state="expanded" |
|
) |
|
|
|
|
|
st.markdown(""" |
|
<style> |
|
/* تخصيص الخلفية والألوان */ |
|
.main { |
|
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%); |
|
padding: 20px; |
|
} |
|
|
|
/* تنسيق البطاقات */ |
|
.metric-card { |
|
background: white; |
|
border-radius: 15px; |
|
padding: 20px; |
|
box-shadow: 0 4px 6px rgba(0,0,0,0.1); |
|
transition: transform 0.3s ease; |
|
} |
|
.metric-card:hover { |
|
transform: translateY(-5px); |
|
} |
|
|
|
/* تنسيق الأزرار */ |
|
.stButton>button { |
|
background: linear-gradient(45deg, #2196F3, #21CBF3); |
|
color: white; |
|
border-radius: 25px; |
|
padding: 15px 25px; |
|
border: none; |
|
box-shadow: 0 4px 15px rgba(0,0,0,0.2); |
|
transition: all 0.3s ease; |
|
} |
|
.stButton>button:hover { |
|
transform: translateY(-2px); |
|
box-shadow: 0 6px 20px rgba(0,0,0,0.25); |
|
} |
|
|
|
/* تنسيق العناوين */ |
|
h1, h2, h3 { |
|
color: #1E3D59; |
|
font-family: 'Tajawal', sans-serif; |
|
} |
|
|
|
/* تنسيق المدخلات */ |
|
.stTextInput>div>div>input { |
|
border-radius: 10px; |
|
border: 2px solid #E0E0E0; |
|
padding: 10px; |
|
} |
|
|
|
/* تنسيق التوسيعات */ |
|
.streamlit-expanderHeader { |
|
background-color: white; |
|
border-radius: 10px; |
|
} |
|
</style> |
|
<link href="https://fonts.googleapis.com/css2?family=Tajawal:wght@400;700&display=swap" rel="stylesheet"> |
|
""", unsafe_allow_html=True) |
|
|
|
|
|
def load_lottieurl(url): |
|
try: |
|
r = requests.get(url) |
|
if r.status_code == 200: |
|
return r.json() |
|
except: |
|
pass |
|
return None |
|
|
|
|
|
lottie_analyzing = load_lottieurl("https://assets5.lottiefiles.com/packages/lf20_qpwbqki6.json") |
|
lottie_success = load_lottieurl("https://assets9.lottiefiles.com/packages/lf20_jbrw3hcz.json") |
|
lottie_error = load_lottieurl("https://assets8.lottiefiles.com/packages/lf20_my7r4w9m.json") |
|
|
|
class WebsiteAnalyzer: |
|
def __init__(self): |
|
self.headers = { |
|
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36' |
|
} |
|
|
|
async def analyze_performance(self, url): |
|
try: |
|
start_time = time.time() |
|
async with httpx.AsyncClient() as client: |
|
response = await client.get(url) |
|
load_time = time.time() - start_time |
|
page_size = len(response.content) / 1024 |
|
|
|
|
|
performance_metrics = { |
|
"load_time": round(load_time, 2), |
|
"page_size": round(page_size, 2), |
|
"status_code": response.status_code, |
|
"تقدير السرعة": self._estimate_speed(load_time), |
|
"عدد الزيارات التقريبي": self._estimate_traffic(url), |
|
"ترتيب الموقع على جوجل": self._estimate_google_rank(url), |
|
"السعر التقريبي للموقع": self._estimate_website_value(url), |
|
"تقييم الأداء": self._calculate_performance_score(load_time, page_size), |
|
"توصيات تحسين الأداء": self._get_performance_recommendations(load_time, page_size) |
|
} |
|
|
|
return performance_metrics |
|
except Exception as e: |
|
return {"error": f"خطأ في تحليل الأداء: {str(e)}"} |
|
|
|
def _calculate_performance_score(self, load_time, page_size): |
|
score = 100 |
|
if load_time > 2: |
|
score -= (load_time - 2) * 10 |
|
if page_size > 1000: |
|
score -= (page_size - 1000) / 100 |
|
return max(0, min(100, round(score))) |
|
|
|
def _get_performance_recommendations(self, load_time, page_size): |
|
recommendations = [] |
|
if load_time > 2: |
|
recommendations.append("تحسين سرعة تحميل الصفحة") |
|
if page_size > 1000: |
|
recommendations.append("تقليل حجم الصفحة") |
|
return recommendations if recommendations else ["أداء الموقع جيد!"] |
|
|
|
async def analyze_seo(self, url): |
|
try: |
|
async with httpx.AsyncClient() as client: |
|
response = await client.get(url) |
|
soup = BeautifulSoup(response.text, 'html.parser') |
|
|
|
|
|
seo_analysis = { |
|
"العنوان": self._analyze_title(soup), |
|
"الوصف": self._analyze_description(soup), |
|
"الكلمات المفتاحية": self._analyze_keywords(soup), |
|
"هيكل العناوين": self._analyze_headings(soup), |
|
"الروابط": self._analyze_links(soup), |
|
"الصور": self._analyze_images(soup), |
|
"تقييم SEO الإجمالي": self._calculate_seo_score(soup) |
|
} |
|
|
|
return seo_analysis |
|
except Exception as e: |
|
return {"error": f"خطأ في تحليل SEO: {str(e)}"} |
|
|
|
def _analyze_title(self, soup): |
|
title = soup.title.string if soup.title else "" |
|
return { |
|
"النص": title, |
|
"الطول": len(title) if title else 0, |
|
"التقييم": "ممتاز" if title and 30 <= len(title) <= 60 else "يحتاج تحسين", |
|
"التوصيات": self._get_title_recommendations(title) |
|
} |
|
|
|
def _get_title_recommendations(self, title): |
|
recommendations = [] |
|
if not title: |
|
recommendations.append("إضافة عنوان للصفحة") |
|
elif len(title) < 30: |
|
recommendations.append("زيادة طول العنوان") |
|
elif len(title) > 60: |
|
recommendations.append("تقليل طول العنوان") |
|
return recommendations if recommendations else ["العنوان مثالي!"] |
|
|
|
def analyze_security(self, url): |
|
try: |
|
domain = urlparse(url).netloc |
|
security_analysis = { |
|
"شهادة SSL": self._analyze_ssl(url), |
|
"سجلات DNS": self._analyze_dns(domain), |
|
"تقييم الحماية": self._calculate_security_score(url), |
|
"توصيات الأمان": self._get_security_recommendations(url) |
|
} |
|
return security_analysis |
|
except Exception as e: |
|
return {"error": f"خطأ في تحليل الأمان: {str(e)}"} |
|
|
|
def _analyze_ssl(self, url): |
|
try: |
|
context = ssl.create_default_context() |
|
with socket.create_connection((urlparse(url).netloc, 443)) as sock: |
|
with context.wrap_socket(sock, server_hostname=urlparse(url).netloc) as ssock: |
|
cert = ssock.getpeercert() |
|
return { |
|
"الحالة": "آمن ✅", |
|
"تاريخ الانتهاء": cert['notAfter'], |
|
"مُصدر الشهادة": cert['issuer'][0][0][1] |
|
} |
|
except: |
|
return {"الحالة": "غير آمن ❌", "توصية": "تثبيت شهادة SSL"} |
|
|
|
def generate_reports(self, performance_data, seo_data, security_data): |
|
|
|
fig = plt.figure(figsize=(15, 10)) |
|
|
|
|
|
plt.subplot(2, 2, 1) |
|
performance_scores = [ |
|
performance_data.get('تقييم الأداء', 0), |
|
seo_data.get('تقييم SEO الإجمالي', 0), |
|
security_data.get('تقييم الحماية', 0) |
|
] |
|
plt.bar(['الأداء', 'SEO', 'الأمان'], performance_scores) |
|
plt.title('تقييم شامل للموقع') |
|
|
|
|
|
buf = io.BytesIO() |
|
plt.savefig(buf, format='png') |
|
buf.seek(0) |
|
return Image.open(buf) |
|
|
|
def main(): |
|
st.title("🔍 محلل المواقع المتقدم") |
|
|
|
|
|
with st.sidebar: |
|
selected = option_menu( |
|
menu_title="القائمة الرئيسية", |
|
options=["تحليل جديد", "التقارير السابقة", "الإحصائيات", "الإعدادات"], |
|
icons=["search", "file-text", "graph-up", "gear"], |
|
menu_icon="cast", |
|
styles={ |
|
"container": {"padding": "15px"}, |
|
"icon": {"color": "orange", "font-size": "25px"}, |
|
"nav-link": {"font-size": "16px", "text-align": "right", "margin": "0px"} |
|
} |
|
) |
|
|
|
if selected == "تحليل جديد": |
|
col1, col2 = st.columns([2, 1]) |
|
|
|
with col1: |
|
url = st.text_input("🌐 أدخل رابط الموقع", "https://example.com") |
|
analyze_button = st.button("⚡ بدء التحليل") |
|
|
|
if analyze_button: |
|
with st.spinner("جاري التحليل... ⏳"): |
|
st_lottie(lottie_analyzing, height=200) |
|
|
|
analyzer = WebsiteAnalyzer() |
|
|
|
|
|
loop = asyncio.new_event_loop() |
|
asyncio.set_event_loop(loop) |
|
|
|
performance_data = loop.run_until_complete(analyzer.analyze_performance(url)) |
|
seo_data = loop.run_until_complete(analyzer.analyze_seo(url)) |
|
security_data = analyzer.analyze_security(url) |
|
|
|
|
|
st.success("✨ تم اكتمال التحليل بنجاح!") |
|
|
|
|
|
col1, col2, col3, col4 = st.columns(4) |
|
with col1: |
|
st.metric( |
|
"⚡ سرعة التحميل", |
|
f"{performance_data.get('load_time', 'N/A')}s", |
|
delta="-0.2s" |
|
) |
|
with col2: |
|
st.metric( |
|
"👥 الزيارات الشهرية", |
|
f"{performance_data.get('عدد الزيارات التقريبي', 'N/A'):,}", |
|
delta="↑ 12%" |
|
) |
|
with col3: |
|
st.metric( |
|
"🎯 ترتيب جوجل", |
|
f"#{performance_data.get('ترتيب الموقع على جوجل', 'N/A')}", |
|
delta="↑ 5" |
|
) |
|
with col4: |
|
st.metric( |
|
"💰 القيمة التقديرية", |
|
f"${performance_data.get('السعر التقريبي للموقع', 'N/A'):,}", |
|
delta="↑ $1,000" |
|
) |
|
|
|
|
|
tabs = st.tabs(["📊 الأداء", "🎯 SEO", "🔒 الأمان", "📈 التقرير الشامل"]) |
|
|
|
with tabs[0]: |
|
st.subheader("تحليل الأداء التفصيلي") |
|
|
|
|
|
performance_fig = go.Figure() |
|
|
|
|
|
performance_fig.add_trace(go.Indicator( |
|
mode = "gauge+number", |
|
value = performance_data.get('تقييم الأداء', 0), |
|
title = {'text': "تقييم الأداء العام"}, |
|
gauge = { |
|
'axis': {'range': [0, 100]}, |
|
'steps': [ |
|
{'range': [0, 50], 'color': "lightgray"}, |
|
{'range': [50, 75], 'color': "gray"}, |
|
{'range': [75, 100], 'color': "darkblue"} |
|
], |
|
'bar': {'color': "royalblue"} |
|
} |
|
)) |
|
|
|
st.plotly_chart(performance_fig, use_container_width=True) |
|
|
|
|
|
st.markdown(""" |
|
<div class="metric-card"> |
|
<h3>📊 تفاصيل الأداء</h3> |
|
""", unsafe_allow_html=True) |
|
|
|
perf_cols = st.columns(2) |
|
with perf_cols[0]: |
|
st.markdown(f""" |
|
- ⚡ زمن التحميل: {performance_data.get('load_time')}s |
|
- 📦 حجم الصفحة: {performance_data.get('page_size')} KB |
|
- 🎯 تقدير السرعة: {performance_data.get('تقدير السرعة')} |
|
""") |
|
|
|
with perf_cols[1]: |
|
st.markdown(f""" |
|
- 👥 الزيارات الشهرية: {performance_data.get('عدد الزيارات التقريبي'):,} |
|
- 🌐 حالة الموقع: {performance_data.get('status_code')} |
|
- 💰 القيمة التقديرية: ${performance_data.get('السعر التقريبي للموقع'):,} |
|
""") |
|
|
|
with tabs[1]: |
|
st.subheader("تحليل SEO") |
|
|
|
|
|
seo_scores = { |
|
'العنوان': seo_data.get('العنوان', {}).get('التقييم', 0), |
|
'الوصف': seo_data.get('الوصف', {}).get('التقييم', 0), |
|
'الكلمات المفتاحية': seo_data.get('الكلمات المفتاحية', {}).get('التقييم', 0), |
|
'الروابط': seo_data.get('الروابط', {}).get('التقييم', 0), |
|
'الصور': seo_data.get('الصور', {}).get('التقييم', 0) |
|
} |
|
|
|
seo_fig = go.Figure(data=go.Scatterpolar( |
|
r=list(seo_scores.values()), |
|
theta=list(seo_scores.keys()), |
|
fill='toself' |
|
)) |
|
|
|
seo_fig.update_layout( |
|
polar=dict( |
|
radialaxis=dict(visible=True, range=[0, 100]) |
|
), |
|
showlegend=False |
|
) |
|
|
|
st.plotly_chart(seo_fig, use_container_width=True) |
|
|
|
|
|
seo_cols = st.columns(3) |
|
|
|
with seo_cols[0]: |
|
st.markdown(""" |
|
<div class="metric-card"> |
|
<h4>🎯 تحليل العنوان</h4> |
|
""", unsafe_allow_html=True) |
|
st.write(seo_data.get('العنوان', {})) |
|
|
|
with seo_cols[1]: |
|
st.markdown(""" |
|
<div class="metric-card"> |
|
<h4>📝 تحليل الوصف</h4> |
|
""", unsafe_allow_html=True) |
|
st.write(seo_data.get('الوصف', {})) |
|
|
|
with seo_cols[2]: |
|
st.markdown(""" |
|
<div class="metric-card"> |
|
<h4>🔍 الكلمات المفتاحية</h4> |
|
""", unsafe_allow_html=True) |
|
st.write(seo_data.get('الكلمات المفتاحية', {})) |
|
|
|
with tabs[2]: |
|
st.subheader("تحليل الأمان") |
|
|
|
|
|
security_score = security_data.get('تقييم الحماية', 0) |
|
|
|
security_fig = go.Figure(go.Indicator( |
|
mode = "gauge+number+delta", |
|
value = security_score, |
|
delta = {'reference': 90}, |
|
title = {'text': "مستوى الأمان العام"}, |
|
gauge = { |
|
'axis': {'range': [0, 100]}, |
|
'steps': [ |
|
{'range': [0, 50], 'color': "red"}, |
|
{'range': [50, 75], 'color': "yellow"}, |
|
{'range': [75, 100], 'color': "green"} |
|
] |
|
} |
|
)) |
|
|
|
st.plotly_chart(security_fig, use_container_width=True) |
|
|
|
|
|
security_cols = st.columns(3) |
|
|
|
with security_cols[0]: |
|
st.markdown(""" |
|
<div class="metric-card"> |
|
<h4>🔒 شهادة SSL</h4> |
|
""", unsafe_allow_html=True) |
|
st.write(security_data.get('شهادة SSL', {})) |
|
|
|
with security_cols[1]: |
|
st.markdown(""" |
|
<div class="metric-card"> |
|
<h4>🌐 سجلات DNS</h4> |
|
""", unsafe_allow_html=True) |
|
st.write(security_data.get('سجلات DNS', {})) |
|
|
|
with security_cols[2]: |
|
st.markdown(""" |
|
<div class="metric-card"> |
|
<h4>⚡ توصيات الأمان</h4> |
|
""", unsafe_allow_html=True) |
|
st.write(security_data.get('توصيات الأمان', [])) |
|
|
|
with tabs[3]: |
|
st.subheader("التقرير الشامل") |
|
|
|
|
|
if st.button("📥 تحميل التقرير الشامل (PDF)"): |
|
report_data = { |
|
'url': url, |
|
'date': datetime.now().strftime("%Y-%m-%d %H:%M:%S"), |
|
'performance': performance_data, |
|
'seo': seo_data, |
|
'security': security_data |
|
} |
|
|
|
|
|
st.success("تم تحضير التقرير بنجاح! اضغط هنا للتحميل") |
|
|
|
|
|
st.markdown(""" |
|
<div class="metric-card"> |
|
<h3>📊 ملخص التحليل الشامل</h3> |
|
""", unsafe_allow_html=True) |
|
|
|
summary_cols = st.columns(3) |
|
|
|
with summary_cols[0]: |
|
st.markdown(""" |
|
#### 🚀 الأداء العام |
|
""") |
|
st.progress(performance_data.get('تقييم الأداء', 0) / 100) |
|
|
|
with summary_cols[1]: |
|
st.markdown(""" |
|
#### 🎯 تقييم SEO |
|
""") |
|
st.progress(seo_data.get('تقييم SEO الإجمالي', 0) / 100) |
|
|
|
with summary_cols[2]: |
|
st.markdown(""" |
|
#### 🔒 مستوى الأمان |
|
""") |
|
st.progress(security_data.get('تقييم الحماية', 0) / 100) |
|
|
|
|
|
st.markdown(""" |
|
### 📈 توصيات التحسين |
|
""") |
|
|
|
recommendations = st.expander("عرض التوصيات", expanded=True) |
|
with recommendations: |
|
rec_cols = st.columns(3) |
|
|
|
with rec_cols[0]: |
|
st.markdown("#### 🚀 تحسين الأداء") |
|
for rec in performance_data.get('توصيات تحسين الأداء', []): |
|
st.markdown(f"- {rec}") |
|
|
|
with rec_cols[1]: |
|
st.markdown("#### 🎯 تحسين SEO") |
|
for rec in seo_data.get('توصيات', []): |
|
st.markdown(f"- {rec}") |
|
|
|
with rec_cols[2]: |
|
st.markdown("#### 🔒 تحسين الأمان") |
|
for rec in security_data.get('توصيات الأمان', []): |
|
st.markdown(f"- {rec}") |
|
|
|
with col2: |
|
st.subheader("📊 آخر التحليلات") |
|
|
|
st.markdown(""" |
|
<div class="metric-card"> |
|
<h4>آخر 5 مواقع تم تحليلها</h4> |
|
</div> |
|
""", unsafe_allow_html=True) |
|
|
|
|
|
recent_analyses = [ |
|
{"url": "example1.com", "date": "2024-03-15", "score": 85}, |
|
{"url": "example2.com", "date": "2024-03-14", "score": 92}, |
|
{"url": "example3.com", "date": "2024-03-13", "score": 78} |
|
] |
|
|
|
for analysis in recent_analyses: |
|
st.markdown(f""" |
|
<div style='padding: 10px; margin: 5px; background-color: white; border-radius: 5px;'> |
|
🌐 {analysis['url']}<br> |
|
📅 {analysis['date']}<br> |
|
⭐ {analysis['score']}/100 |
|
</div> |
|
""", unsafe_allow_html=True) |
|
|
|
elif selected == "التقارير السابقة": |
|
st.subheader("📊 التقارير السابقة") |
|
|
|
|
|
elif selected == "الإحصائيات": |
|
st.subheader("📈 إحصائيات التحليل") |
|
|
|
|
|
elif selected == "الإعدادات": |
|
st.subheader("⚙️ إعدادات التحليل") |
|
|
|
|
|
if __name__ == "__main__": |
|
main() |