joermd commited on
Commit
59844ed
·
verified ·
1 Parent(s): bf3ca2f

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +401 -151
app.py CHANGED
@@ -130,6 +130,8 @@ class WebsiteAnalyzer:
130
  domain = urlparse(url).netloc
131
 
132
  try:
 
 
133
 
134
  # استخدام بيانات من Alexa (إذا كانت متوفرة)
135
  alexa_rank = await self._get_alexa_rank(domain)
@@ -508,167 +510,415 @@ class WebsiteAnalyzer:
508
  else:
509
  return "موثوقية منخفضة ⛔"
510
  def _analyze_description(self, description):
511
- if not description:
512
- return {
513
- 'score': "0/10",
514
- 'recommendations': ["يجب إضافة وصف للصفحة"]
515
- }
516
-
517
- score = 10
518
- recommendations = []
519
-
520
- if len(description) < 120:
521
- score -= 2
522
- recommendations.append("الوصف قصير جداً، يُفضل أن يكون بين 120-155 حرفاً")
523
- elif len(description) > 155:
524
- score -= 2
525
- recommendations.append("الوصف طويل جداً، يجب تقصيره إلى 155 حرفاً كحد أقصى")
526
-
527
- if not any(char in description.lower() for char in ['ما', 'كيف', 'لماذا', 'متى', 'أين']):
528
- score -= 1
529
- recommendations.append("أضف كلمات استفهامية لجذب المزيد من النقرات")
530
-
531
  return {
532
- 'score': f"{score}/10",
533
- 'recommendations': recommendations
534
  }
535
-
536
- def _extract_keywords(self, soup):
537
- # استخراج النص من العناصر المهمة
538
- text_elements = []
539
- for tag in ['h1', 'h2', 'h3', 'p', 'li']:
540
- elements = soup.find_all(tag)
541
- for element in elements:
542
- text_elements.append(element.get_text())
 
 
543
 
544
- # تنظيف النص
545
- text = ' '.join(text_elements)
546
- words = re.findall(r'\b\w+\b', text.lower())
547
 
548
- # حذف الكلمات الشائعة
549
- stop_words = set(['في', 'من', 'على', 'إلى', 'عن', 'مع', 'هذا', 'هذه', 'تلك', 'ذلك'])
550
- words = [word for word in words if word not in stop_words and len(word) > 2]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
551
 
552
- # حساب تكرار الكلمات
553
- word_freq = {}
554
- for word in words:
555
- word_freq[word] = word_freq.get(word, 0) + 1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
556
 
557
- # ترتيب الكلمات حسب التكرار
558
- sorted_keywords = sorted(word_freq.items(), key=lambda x: x[1], reverse=True)
559
- return [word for word, freq in sorted_keywords[:10]]
560
-
561
- def _analyze_links(self, soup, base_url):
562
- internal_links = []
563
- external_links = []
564
- base_domain = urlparse(base_url).netloc
565
-
566
- for link in soup.find_all('a', href=True):
567
- href = link['href']
568
- if href.startswith('/') or base_domain in href:
569
- internal_links.append(href)
570
- elif href.startswith('http'):
571
- external_links.append(href)
572
-
573
- return internal_links, external_links
574
-
575
- def _analyze_content(self, soup):
576
- # استخراج النص الكامل
577
- text = ' '.join([p.get_text() for p in soup.find_all('p')])
578
- words = text.split()
579
 
580
- # حساب كثافة الكلمات المفتاحية
581
- keywords = self._extract_keywords(soup)
582
- keyword_count = sum(text.lower().count(keyword) for keyword in keywords)
583
- keyword_density = keyword_count / len(words) if words else 0
584
-
585
- # تقييم تنوع المحتوى
586
- content_types = {
587
- 'صور': len(soup.find_all('img')),
588
- 'فيديوهات': len(soup.find_all(['video', 'iframe'])),
589
- 'جداول': len(soup.find_all('table')),
590
- 'قوائم': len(soup.find_all(['ul', 'ol'])),
591
- 'عناوين': len(soup.find_all(['h1', 'h2', 'h3', 'h4', 'h5', 'h6']))
592
- }
593
-
594
- # حساب قابلية القراءة (مقياس مبسط)
595
- sentences = text.split('.')
596
- avg_words_per_sentence = len(words) / len(sentences) if sentences else 0
597
-
598
- recommendations = []
599
- if len(words) < 300:
600
- recommendations.append("المحتوى قصير جداً، أضف المزيد من النصوص الغنية")
601
- if keyword_density < 0.01:
602
- recommendations.append("كثافة الكلمات المفتاحية منخفضة")
603
- elif keyword_density > 0.05:
604
- recommendations.append("كثافة الكلمات المفتاحية مرتفعة جداً")
605
- if avg_words_per_sentence > 20:
606
- recommendations.append("الجمل طويلة جداً، حاول تقصيرها لتحسين القراءة")
607
 
 
 
 
608
  return {
609
- 'word_count': len(words),
610
- 'keyword_density': f"{keyword_density:.2%}",
611
- 'content_diversity': self._evaluate_diversity(content_types),
612
- 'readability': self._evaluate_readability(avg_words_per_sentence),
613
- 'recommendations': recommendations
614
  }
615
 
616
- def _evaluate_diversity(self, content_types):
617
- score = 0
618
- total_elements = sum(content_types.values())
619
-
620
- if content_types['صور'] > 0:
621
- score += 2
622
- if content_types['فيديوهات'] > 0:
623
- score += 2
624
- if content_types['جداول'] > 0:
625
- score += 1
626
- if content_types['قوائم'] > 0:
627
- score += 1
628
- if content_types['عناوين'] >= 3:
629
- score += 2
630
-
631
- if total_elements > 10:
632
- score += 2
633
-
634
- return f"{score}/10"
635
-
636
- def _evaluate_readability(self, avg_words_per_sentence):
637
- if avg_words_per_sentence <= 12:
638
- return "ممتاز"
639
- elif avg_words_per_sentence <= 15:
640
- return "جيد"
641
- elif avg_words_per_sentence <= 20:
642
- return "متوسط"
643
- else:
644
- return "صعب"
645
-
646
- def _evaluate_speed(self, total_load_time):
647
- if total_load_time < 2:
648
- return "ممتاز ⚡"
649
- elif total_load_time < 3:
650
- return "جيد "
651
- elif total_load_time < 5:
652
- return "متوسط ⚠️"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
653
  else:
654
- return "بطيء "
655
 
656
- def _generate_performance_recommendations(self, metrics, resources):
657
- recommendations = []
658
-
659
- if metrics['ttfb'] > 0.5:
660
- recommendations.append("تحسين زمن استجابة الخادم")
661
-
662
- if resources['total_size'] > 1500: # أكثر من 1.5 ميجابايت
663
- recommendations.append("تقليل حجم الصفحة الإجمالي")
664
-
665
- if resources['images'] > 10:
666
- recommendations.append("ضغط وتحسين الصور")
667
-
668
- if resources['scripts'] > 15:
669
- recommendations.append("دمج وضغط ملفات JavaScript")
670
-
671
- if resources['stylesheets'] > 5:
672
- recommendations.append("دمج ملفات CSS")
673
-
674
- return recommendations
 
130
  domain = urlparse(url).netloc
131
 
132
  try:
133
+ # استخدام بيانات من SimilarWeb API (تحتاج لمفتاح API حقيقي)
134
+ similar_web_traffic = await self._get_similarweb_data(domain)
135
 
136
  # استخدام بيانات من Alexa (إذا كانت متوفرة)
137
  alexa_rank = await self._get_alexa_rank(domain)
 
510
  else:
511
  return "موثوقية منخفضة ⛔"
512
  def _analyze_description(self, description):
513
+ if not description:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
514
  return {
515
+ 'score': "0/10",
516
+ 'recommendations': ["يجب إضافة وصف للصفحة"]
517
  }
518
+
519
+ score = 10
520
+ recommendations = []
521
+
522
+ if len(description) < 120:
523
+ score -= 2
524
+ recommendations.append("الوصف قصير جداً، يُفضل أن يكون بين 120-155 حرفاً")
525
+ elif len(description) > 155:
526
+ score -= 2
527
+ recommendations.append("الوصف طويل جداً، يجب تقصيره إلى 155 حرفاً كحد أقصى")
528
 
529
+ if not any(char in description.lower() for char in ['ما', 'كيف', 'لماذا', 'متى', 'أين']):
530
+ score -= 1
531
+ recommendations.append("أضف كلمات استفهامية لجذب المزيد من النقرات")
532
 
533
+ return {
534
+ 'score': f"{score}/10",
535
+ 'recommendations': recommendations
536
+ }
537
+
538
+ def _extract_keywords(self, soup):
539
+ # استخراج النص من العناصر المهمة
540
+ text_elements = []
541
+ for tag in ['h1', 'h2', 'h3', 'p', 'li']:
542
+ elements = soup.find_all(tag)
543
+ for element in elements:
544
+ text_elements.append(element.get_text())
545
+
546
+ # تنظيف النص
547
+ text = ' '.join(text_elements)
548
+ words = re.findall(r'\b\w+\b', text.lower())
549
+
550
+ # حذف الكلمات الشائعة
551
+ stop_words = set(['في', 'من', 'على', 'إلى', 'عن', 'مع', 'هذا', 'هذه', 'تلك', 'ذلك'])
552
+ words = [word for word in words if word not in stop_words and len(word) > 2]
553
+
554
+ # حساب تكرار الكلمات
555
+ word_freq = {}
556
+ for word in words:
557
+ word_freq[word] = word_freq.get(word, 0) + 1
558
+
559
+ # ترتيب الكلمات حسب التكرار
560
+ sorted_keywords = sorted(word_freq.items(), key=lambda x: x[1], reverse=True)
561
+ return [word for word, freq in sorted_keywords[:10]]
562
+
563
+ def _analyze_links(self, soup, base_url):
564
+ internal_links = []
565
+ external_links = []
566
+ base_domain = urlparse(base_url).netloc
567
+
568
+ for link in soup.find_all('a', href=True):
569
+ href = link['href']
570
+ if href.startswith('/') or base_domain in href:
571
+ internal_links.append(href)
572
+ elif href.startswith('http'):
573
+ external_links.append(href)
574
+
575
+ return internal_links, external_links
576
+
577
+ def _analyze_content(self, soup):
578
+ # استخراج النص الكامل
579
+ text = ' '.join([p.get_text() for p in soup.find_all('p')])
580
+ words = text.split()
581
+
582
+ # حساب كثافة الكلمات المفتاحية
583
+ keywords = self._extract_keywords(soup)
584
+ keyword_count = sum(text.lower().count(keyword) for keyword in keywords)
585
+ keyword_density = keyword_count / len(words) if words else 0
586
+
587
+ # تقييم تنوع المحتوى
588
+ content_types = {
589
+ 'صور': len(soup.find_all('img')),
590
+ 'فيديوهات': len(soup.find_all(['video', 'iframe'])),
591
+ 'جداول': len(soup.find_all('table')),
592
+ 'قوائم': len(soup.find_all(['ul', 'ol'])),
593
+ 'عناوين': len(soup.find_all(['h1', 'h2', 'h3', 'h4', 'h5', 'h6']))
594
+ }
595
+
596
+ # حساب قابلية القراءة (مقياس مبسط)
597
+ sentences = text.split('.')
598
+ avg_words_per_sentence = len(words) / len(sentences) if sentences else 0
599
+
600
+ recommendations = []
601
+ if len(words) < 300:
602
+ recommendations.append("المحتوى قصير جداً، أضف المزيد من النصوص الغنية")
603
+ if keyword_density < 0.01:
604
+ recommendations.append("كثافة الكلمات المفتاحية منخفضة")
605
+ elif keyword_density > 0.05:
606
+ recommendations.append("كثافة الكلمات المفتاحية مرتفعة جداً")
607
+ if avg_words_per_sentence > 20:
608
+ recommendations.append("الجمل طويلة جداً، حاول تقصيرها لتحسين القراءة")
609
+
610
+ return {
611
+ 'word_count': len(words),
612
+ 'keyword_density': f"{keyword_density:.2%}",
613
+ 'content_diversity': self._evaluate_diversity(content_types),
614
+ 'readability': self._evaluate_readability(avg_words_per_sentence),
615
+ 'recommendations': recommendations
616
+ }
617
+
618
+ def _evaluate_diversity(self, content_types):
619
+ score = 0
620
+ total_elements = sum(content_types.values())
621
+
622
+ if content_types['صور'] > 0:
623
+ score += 2
624
+ if content_types['فيديوهات'] > 0:
625
+ score += 2
626
+ if content_types['جداول'] > 0:
627
+ score += 1
628
+ if content_types['قوائم'] > 0:
629
+ score += 1
630
+ if content_types['عناوين'] >= 3:
631
+ score += 2
632
+
633
+ if total_elements > 10:
634
+ score += 2
635
+
636
+ return f"{score}/10"
637
+
638
+ def _evaluate_readability(self, avg_words_per_sentence):
639
+ if avg_words_per_sentence <= 12:
640
+ return "ممتاز"
641
+ elif avg_words_per_sentence <= 15:
642
+ return "جيد"
643
+ elif avg_words_per_sentence <= 20:
644
+ return "متوسط"
645
+ else:
646
+ return "صعب"
647
+
648
+ def _evaluate_speed(self, total_load_time):
649
+ if total_load_time < 2:
650
+ return "ممتاز ⚡"
651
+ elif total_load_time < 3:
652
+ return "جيد ✅"
653
+ elif total_load_time < 5:
654
+ return "متوسط ⚠️"
655
+ else:
656
+ return "بطيء ❌"
657
+
658
+ def _generate_performance_recommendations(self, metrics, resources):
659
+ recommendations = []
660
+
661
+ if metrics['ttfb'] > 0.5:
662
+ recommendations.append("تحسين زمن استجابة الخادم")
663
+
664
+ if resources['total_size'] > 1500: # أكثر من 1.5 ميجابايت
665
+ recommendations.append("تقليل حجم الصفحة الإجمالي")
666
+
667
+ if resources['images'] > 10:
668
+ recommendations.append("ضغط وتحسين الصور")
669
+
670
+ if resources['scripts'] > 15:
671
+ recommendations.append("دمج وضغط ملفات JavaScript")
672
+
673
+ if resources['stylesheets'] > 5:
674
+ recommendations.append("دمج ملفات CSS")
675
+
676
+ return recommendations
677
+
678
+ async def _get_similarweb_data(self, domain):
679
+ """
680
+ الحصول على بيانات حركة المرور من SimilarWeb
681
+ تحتاج لمفتاح API حقيقي للاستخدام
682
+ """
683
+ try:
684
+ # هذا مجرد مثال، يجب استبداله بمفتاح API حقيقي
685
+ api_key = "YOUR_SIMILARWEB_API_KEY"
686
+ url = f"https://api.similarweb.com/v1/website/{domain}/total-traffic-and-engagement/visits"
687
 
688
+ async with httpx.AsyncClient() as client:
689
+ response = await client.get(url, headers={'Authorization': api_key})
690
+ data = response.json()
691
+ return data.get('visits', 0)
692
+ except:
693
+ return None
694
+
695
+ async def _get_alexa_rank(self, domain):
696
+ """
697
+ الحصول على تصنيف Alexa للموقع
698
+ ملاحظة: خدمة Alexa متوقفة حالياً، هذا مجرد مثال
699
+ """
700
+ try:
701
+ url = f"http://data.alexa.com/data?cli=10&url={domain}"
702
+ async with httpx.AsyncClient() as client:
703
+ response = await client.get(url)
704
+ soup = BeautifulSoup(response.text, 'xml')
705
+ rank = soup.find('REACH')['RANK']
706
+ return int(rank)
707
+ except:
708
+ return None
709
+
710
+ def _rank_to_traffic(self, rank):
711
+ """تحويل تصنيف Alexa إلى تقدير تقريبي لحركة المرور"""
712
+ if not rank:
713
+ return None
714
+ # معادلة تقريبية جداً
715
+ return int(1000000 / (rank ** 0.6))
716
+
717
+ def _calculate_security_score(self, ssl_info, security_headers):
718
+ score = 0
719
+
720
+ # تقييم SSL
721
+ if isinstance(ssl_info, dict) and ssl_info.get("الحالة") == "✅ آمن":
722
+ score += 40
723
+
724
+ # تقييم رؤوس الأمان
725
+ headers_score = float(security_headers.get("درجة الأمان", "0/100").split('/')[0])
726
+ score += headers_score * 0.6
727
+
728
+ return f"{min(score, 100)}/100"
729
+
730
+ def analyze_website(self, url):
731
+ """
732
+ تحليل شامل للموقع يشمل الأداء والأمان وSEO
733
+ """
734
+ results = {
735
+ "url": url,
736
+ "تاريخ_التحليل": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
737
+ "نتائج_التحليل": {}
738
+ }
739
+
740
+ try:
741
+ # تحليل الأداء
742
+ performance_results = asyncio.run(self.analyze_performance(url))
743
+ results["نتائج_التحليل"]["الأداء"] = performance_results
744
 
745
+ # تحليل الأمان
746
+ security_results = self.analyze_security(url)
747
+ results["نتائج_التحليل"]["الأمان"] = security_results
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
748
 
749
+ # تحليل SEO
750
+ seo_results = asyncio.run(self.analyze_seo(url))
751
+ results["نتائج_التحليل"]["SEO"] = seo_results
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
752
 
753
+ return results
754
+
755
+ except Exception as e:
756
  return {
757
+ "error": f"حدث خطأ أثناء تحليل الموقع: {str(e)}",
758
+ "url": url,
759
+ "تاريخ_التحليل": datetime.now().strftime("%Y-%m-%d %H:%M:%S")
 
 
760
  }
761
 
762
+ def generate_report(self, results):
763
+ """
764
+ إنشاء تقرير مفصل بنتائج التحليل
765
+ """
766
+ report = {
767
+ "ملخص_التحليل": {
768
+ "الموقع": results["url"],
769
+ "تاريخ_التحليل": results["تاريخ_التحليل"],
770
+ "الحالة_العامة": self._calculate_overall_status(results)
771
+ },
772
+ "تفاصيل_التحليل": results["نتائج_التحليل"],
773
+ "توصيات_عامة": self._generate_general_recommendations(results)
774
+ }
775
+
776
+ return report
777
+
778
+ def _calculate_overall_status(self, results):
779
+ """
780
+ حساب الحالة العامة للموقع بناءً على جميع النتائج
781
+ """
782
+ if "error" in results:
783
+ return "فشل التحليل ❌"
784
+
785
+ scores = []
786
+
787
+ # حساب درجة الأداء
788
+ if "الأداء" in results["نتائج_التحليل"]:
789
+ performance = results["نتائج_التحليل"]["الأداء"]
790
+ if isinstance(performance, dict) and "أداء الموقع" in performance:
791
+ speed_rating = performance["أداء الموقع"]["تقييم السرعة"]
792
+ scores.append(self._convert_rating_to_score(speed_rating))
793
+
794
+ # حساب درجة الأمان
795
+ if "الأمان" in results["نتائج_التحليل"]:
796
+ security = results["نتائج_التحليل"]["الأمان"]
797
+ if isinstance(security, dict) and "تحليل الأمان" in security:
798
+ security_score = security["تحليل الأمان"].get("درجة الأمان الكلية", "0/100")
799
+ scores.append(float(security_score.split('/')[0]))
800
+
801
+ # حساب درجة SEO
802
+ if "SEO" in results["نتائج_التحليل"]:
803
+ seo = results["نتائج_التحليل"]["SEO"]
804
+ if isinstance(seo, dict) and "تحليل العناوين" in seo:
805
+ seo_score = float(seo["تحليل العناوين"]["تقييم العنوان"].split('/')[0])
806
+ scores.append(seo_score * 10) # تحويل من 10 إلى 100
807
+
808
+ if not scores:
809
+ return "غير معروف"
810
+
811
+ average_score = sum(scores) / len(scores)
812
+
813
+ if average_score >= 80:
814
+ return "ممتاز 🌟"
815
+ elif average_score >= 60:
816
+ return "جيد ✅"
817
+ elif average_score >= 40:
818
+ return "متوسط ⚠️"
819
+ else:
820
+ return "ضعيف ❌"
821
+
822
+ def _convert_rating_to_score(self, rating):
823
+ """
824
+ تحويل التقييم النصي إلى درجة رقمية
825
+ """
826
+ ratings = {
827
+ "ممتاز ⚡": 100,
828
+ "جيد ✅": 75,
829
+ "متوسط ⚠️": 50,
830
+ "بطيء ❌": 25
831
+ }
832
+ return ratings.get(rating, 0)
833
+
834
+ def _generate_general_recommendations(self, results):
835
+ """
836
+ توليد توصيات عامة بناءً على نتائج التحليل
837
+ """
838
+ recommendations = []
839
+
840
+ if "نتائج_التحليل" not in results:
841
+ return recommendations
842
+
843
+ analysis = results["نتائج_التحليل"]
844
+
845
+ # توصيات الأداء
846
+ if "الأداء" in analysis:
847
+ performance = analysis["الأداء"]
848
+ if isinstance(performance, dict):
849
+ if "التوصيات" in performance:
850
+ recommendations.extend(performance["التوصيات"])
851
+
852
+ # توصيات الأمان
853
+ if "الأمان" in analysis:
854
+ security = analysis["الأمان"]
855
+ if isinstance(security, dict) and "تحليل الأمان" in security:
856
+ security_analysis = security["تحليل الأمان"]
857
+ if "رؤوس الأمان" in security_analysis and "التوصيات" in security_analysis["رؤوس الأمان"]:
858
+ recommendations.extend(security_analysis["رؤوس الأمان"]["التوصيات"])
859
+
860
+ # توصيات SEO
861
+ if "SEO" in analysis:
862
+ seo = analysis["SEO"]
863
+ if isinstance(seo, dict):
864
+ for section in ["تحليل العناوين", "تحليل الوصف", "تحليل الكلمات المفتاحية"]:
865
+ if section in seo and "التوصيات" in seo[section]:
866
+ recommendations.extend(seo[section]["التوصيات"])
867
+
868
+ return list(set(recommendations)) # إزالة التوصيات المكررة
869
+
870
+ # إنشاء واجهة التطبيق باستخدام Streamlit
871
+ def create_app():
872
+ st.set_page_config(page_title="محلل المواقع", page_icon="🔍", layout="wide")
873
+
874
+ st.title("🔍 محلل المواقع الشامل")
875
+ st.markdown("---")
876
+
877
+ # إدخال عنوان الموقع
878
+ url = st.text_input("أدخل عنوان الموقع المراد تحليله", placeholder="https://example.com")
879
+
880
+ if st.button("تح��يل الموقع"):
881
+ if url:
882
+ try:
883
+ with st.spinner("جاري تحليل الموقع..."):
884
+ analyzer = WebsiteAnalyzer()
885
+ results = analyzer.analyze_website(url)
886
+ report = analyzer.generate_report(results)
887
+
888
+ # عرض النتائج
889
+ st.success("تم اكتمال التحليل بنجاح!")
890
+
891
+ # عرض الملخص
892
+ st.subheader("📊 ملخص التحليل")
893
+ col1, col2, col3 = st.columns(3)
894
+ with col1:
895
+ st.metric("الحالة العامة", report["ملخص_التحليل"]["الحالة_العامة"])
896
+
897
+ # عرض تفاصيل التحليل
898
+ st.subheader("📝 تفاصيل التحليل")
899
+ tabs = st.tabs(["الأداء", "الأمان", "SEO"])
900
+
901
+ with tabs[0]:
902
+ if "الأداء" in report["تفاصيل_التحليل"]:
903
+ st.json(report["تفاصيل_التحليل"]["الأداء"])
904
+
905
+ with tabs[1]:
906
+ if "الأمان" in report["تفاصيل_التحليل"]:
907
+ st.json(report["تفاصيل_التحليل"]["الأمان"])
908
+
909
+ with tabs[2]:
910
+ if "SEO" in report["تفاصيل_التحليل"]:
911
+ st.json(report["تفاصيل_التحليل"]["SEO"])
912
+
913
+ # عرض التوصيات
914
+ st.subheader("💡 التوصيات")
915
+ for i, recommendation in enumerate(report["توصيات_عامة"], 1):
916
+ st.markdown(f"{i}. {recommendation}")
917
+
918
+ except Exception as e:
919
+ st.error(f"حدث خطأ أثناء تحليل الموقع: {str(e)}")
920
  else:
921
+ st.warning("الرجاء إدخال عنوان الموقع المراد تحليله")
922
 
923
+ if __name__ == "__main__":
924
+ create_app()