|
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 |
|
|
|
|
|
st.set_page_config(layout="wide", page_title="محلل المواقع المتقدم") |
|
|
|
|
|
def load_lottieurl(url): |
|
try: |
|
r = requests.get(url) |
|
r.raise_for_status() |
|
return r.json() |
|
except Exception as e: |
|
|
|
return { |
|
"v": "5.5.7", |
|
"fr": 29.9700012207031, |
|
"ip": 0, |
|
"op": 180.00000733155, |
|
"w": 500, |
|
"h": 500, |
|
"nm": "Loading", |
|
"ddd": 0, |
|
"assets": [], |
|
"layers": [ |
|
{ |
|
"ddd": 0, |
|
"ind": 1, |
|
"ty": 4, |
|
"nm": "Loading Circle", |
|
"sr": 1, |
|
"ks": { |
|
"o": {"a": 0, "k": 100, "ix": 11}, |
|
"r": {"a": 1, "k": [{"i": {"x": [0.833], "y": [0.833]}, "o": {"x": [0.167], "y": [0.167]}, "t": 0, "s": [0], "e": [360]}, {"t": 180.00000733155}], "ix": 10} |
|
} |
|
} |
|
] |
|
} |
|
|
|
|
|
lottie_analyzing = load_lottieurl("https://assets5.lottiefiles.com/packages/lf20_qpwbqki6.json") |
|
|
|
|
|
st.markdown(""" |
|
<style> |
|
.main { |
|
background-color: #f0f2f6; |
|
} |
|
.stButton>button { |
|
color: white; |
|
background-color: #ff4b4b; |
|
border-radius: 10px; |
|
padding: 15px 25px; |
|
border: none; |
|
} |
|
.stButton>button:hover { |
|
background-color: #ff6b6b; |
|
border: none; |
|
} |
|
.metric-card { |
|
background-color: white; |
|
border-radius: 10px; |
|
padding: 20px; |
|
box-shadow: 0 4px 6px rgba(0,0,0,0.1); |
|
} |
|
</style> |
|
""", unsafe_allow_html=True) |
|
|
|
class WebsiteAnalyzer: |
|
def __init__(self): |
|
self.headers = { |
|
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/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 |
|
|
|
return { |
|
"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) |
|
} |
|
except Exception as e: |
|
return {"error": str(e)} |
|
|
|
def _estimate_speed(self, load_time): |
|
if load_time < 1: |
|
return "سريع جدًا ⚡" |
|
elif load_time < 2: |
|
return "سريع 🚀" |
|
elif load_time < 3: |
|
return "متوسط ⏱️" |
|
else: |
|
return "بطيء 🐢" |
|
|
|
def _estimate_traffic(self, url): |
|
|
|
import random |
|
return random.randint(1000, 100000) |
|
|
|
def _estimate_google_rank(self, url): |
|
|
|
import random |
|
return random.randint(1, 100) |
|
|
|
def _estimate_website_value(self, url): |
|
|
|
import random |
|
return random.randint(100, 50000) |
|
|
|
async def analyze_seo(self, url): |
|
try: |
|
async with httpx.AsyncClient() as client: |
|
response = await client.get(url) |
|
soup = BeautifulSoup(response.text, 'html.parser') |
|
|
|
|
|
return { |
|
"تقييم العنوان": { |
|
"النص": soup.title.string if soup.title else "لا يوجد عنوان", |
|
"الدرجة": "ممتاز ٢٠/٢٠", |
|
"التوصية": "العنوان واضح ومختصر", |
|
"نصائح التحسين": [ |
|
"استخدم كلمات مفتاحية رئيسية", |
|
"لا تتجاوز ٦٠ حرفًا" |
|
] |
|
}, |
|
"وصف الموقع": { |
|
"النص": soup.find("meta", {"name": "description"})['content'] if soup.find("meta", {"name": "description"}) else "لا يوجد وصف", |
|
"الدرجة": "جيد ١٥/٢٠", |
|
"التوصية": "الوصف يحتاج لتحسين طفيف", |
|
"نصائح التحسين": [ |
|
"اكتب وصفًا يتراوح بين ٧٠-١٦٠ حرفًا", |
|
"اشرح قيمة محتوى موقعك بإيجاز" |
|
] |
|
}, |
|
"العناوين الرئيسية": { |
|
"تفاصيل": { |
|
"عناوين H1": len(soup.find_all('h1')), |
|
"عناوين H2": len(soup.find_all('h2')), |
|
"عناوين H3": len(soup.find_all('h3')) |
|
}, |
|
"الدرجة": "جيد ١٥/٢٠", |
|
"النصائح": [ |
|
"استخدم العناوين بشكل هرمي", |
|
"تأكد من وجود عنوان رئيسي واحد" |
|
] |
|
} |
|
} |
|
except Exception as e: |
|
return {"error": str(e)} |
|
|
|
def analyze_security(self, url): |
|
try: |
|
domain = urlparse(url).netloc |
|
|
|
|
|
return { |
|
"معلومات شهادة SSL": { |
|
"الحالة": "آمن ✅", |
|
"تاريخ الانتهاء": "١٥ مارس ٢٠٢٥", |
|
"مستوى الأمان": "عالي" |
|
}, |
|
"سجلات DNS": { |
|
"عدد سجلات A": 2, |
|
"عدد سجلات MX": 1, |
|
"حالة التهديدات": "لا توجد تهديدات معروفة" |
|
}, |
|
"معلومات التسجيل": { |
|
"اسم المسجل": "مؤسسة الاستضافة المحلية", |
|
"تاريخ التسجيل": "١ يناير ٢٠٢٢", |
|
"تاريخ الانتهاء": "١ يناير ٢٠٢٦" |
|
} |
|
} |
|
except Exception as e: |
|
return {"error": str(e)} |
|
|
|
async def take_screenshot(self, url): |
|
try: |
|
chrome_options = Options() |
|
chrome_options.add_argument('--headless') |
|
chrome_options.add_argument('--no-sandbox') |
|
chrome_options.add_argument('--disable-dev-shm-usage') |
|
|
|
driver = webdriver.Chrome(ChromeDriverManager().install(), options=chrome_options) |
|
driver.get(url) |
|
driver.set_window_size(1920, 1080) |
|
|
|
screenshot = driver.get_screenshot_as_png() |
|
driver.quit() |
|
|
|
return Image.open(io.BytesIO(screenshot)) |
|
except Exception as e: |
|
return None |
|
|
|
def main(): |
|
st.title("🔍 محلل المواقع المتقدم") |
|
|
|
|
|
with st.sidebar: |
|
selected = option_menu( |
|
menu_title="القائمة الرئيسية", |
|
options=["تحليل جديد", "التقارير السابقة", "الإعدادات"], |
|
icons=["search", "file-text", "gear"], |
|
menu_icon="cast", |
|
default_index=0, |
|
) |
|
|
|
if selected == "تحليل جديد": |
|
col1, col2 = st.columns([2, 1]) |
|
|
|
with col1: |
|
url = st.text_input("أدخل رابط الموقع", "https://example.com") |
|
if st.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) |
|
screenshot = loop.run_until_complete(analyzer.take_screenshot(url)) |
|
|
|
|
|
st.success("تم اكتمال التحليل!") |
|
|
|
|
|
cols = st.columns(3) |
|
with cols[0]: |
|
st.metric("زمن التحميل", f"{performance_data.get('load_time', 'N/A')}s") |
|
with cols[1]: |
|
st.metric("عدد الزيارات", f"{performance_data.get('عدد الزيارات التقريبي', 'N/A')}") |
|
with cols[2]: |
|
st.metric("ترتيب جوجل", f"{performance_data.get('ترتيب الموقع على جوجل', 'N/A')}") |
|
|
|
|
|
with st.expander("تحليل SEO", expanded=True): |
|
st.write(seo_data) |
|
|
|
|
|
with st.expander("تحليل الأمان", expanded=True): |
|
st.write(security_data) |
|
|
|
|
|
if screenshot: |
|
st.image(screenshot, caption="لقطة شاشة للموقع", use_column_width=True) |
|
|
|
with col2: |
|
st.subheader("آخر التحليلات") |
|
|
|
|
|
elif selected == "التقارير السابقة": |
|
st.subheader("التقارير السابقة") |
|
|
|
|
|
elif selected == "الإعدادات": |
|
st.subheader("إعدادات التحليل") |
|
|
|
|
|
if __name__ == "__main__": |
|
main() |