Mazenbs commited on
Commit
e644b0b
·
verified ·
1 Parent(s): f26a27b

Update helpers/text_blocks.py

Browse files
Files changed (1) hide show
  1. helpers/text_blocks.py +119 -25
helpers/text_blocks.py CHANGED
@@ -1,30 +1,124 @@
1
- # helpers/text_blocks.py
2
-
3
  from bs4 import BeautifulSoup
4
- from typing import List, Dict
 
5
 
6
- # كل العناصر النصية المسموح استخراجها بشكل مستقل
7
- ALLOWED_TEXT_TAGS = ["p", "li", "span", "div", "h1", "h2", "h3", "h4", "h5"]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8
 
9
- def extract_all_text_blocks(soup: BeautifulSoup) -> List[Dict[str, str]]:
 
10
  """
11
- تعيد قائمة من القواميس بالشكل:
12
- - {"text": "..."} لكل عنصر tag نصي (بدون فقدان أي جزء)
13
- - {"image": "..."} لكل صورة
14
- كل tag يعاد كنص مستقل باستخدام get_text لضمان عدم فقدان النصوص الفرعية.
 
 
 
 
15
  """
16
- blocks: List[Dict[str, str]] = []
17
-
18
- # استخراج الصور
19
- for img_tag in soup.find_all("img"):
20
- src = img_tag.get("src")
21
- if src:
22
- blocks.append({"image": src})
23
-
24
- # استخراج النصوص من الـ tags المسموح بها
25
- for tag in soup.find_all(ALLOWED_TEXT_TAGS):
26
- text = tag.get_text(separator=" ", strip=True)
27
- if text:
28
- blocks.append({"text": text})
29
-
30
- return blocks
 
1
+ import requests
 
2
  from bs4 import BeautifulSoup
3
+ from typing import List, Dict, Optional
4
+ import re
5
 
6
+ class TextExtractor:
7
+ def __init__(self):
8
+ self.headers = {
9
+ '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'
10
+ }
11
+
12
+ def extract_text_from_url(self, url: str, timeout: int = 10) -> List[Dict[str, str]]:
13
+ """
14
+ استخراج جميع النصوص من صفحة ويب
15
+
16
+ Args:
17
+ url: رابط الصفحة المراد تحليلها
18
+ timeout: مهلة الانتظار بالثواني
19
+
20
+ Returns:
21
+ قائمة تحتوي على النصوص في شكل {'text': 'النص'}
22
+
23
+ Raises:
24
+ requests.RequestException: في حالة فشل جلب الصفحة
25
+ Exception: في حالة فشل تحليل المحتوى
26
+ """
27
+ try:
28
+ # جلب محتوى الصفحة
29
+ response = requests.get(url, headers=self.headers, timeout=timeout)
30
+ response.raise_for_status()
31
+
32
+ # تحليل HTML
33
+ soup = BeautifulSoup(response.content, 'html.parser')
34
+
35
+ # تنظيف HTML من العناصر غير المرغوب فيها
36
+ self._clean_html(soup)
37
+
38
+ # استخراج النصوص
39
+ text_elements = self._extract_texts(soup)
40
+
41
+ # تنظيف وتصفية النصوص
42
+ cleaned_texts = self._clean_and_filter_texts(text_elements)
43
+
44
+ # إزالة النصوص المكررة
45
+ unique_texts = self._remove_duplicates(cleaned_texts)
46
+
47
+ return unique_texts
48
+
49
+ except requests.RequestException as e:
50
+ raise requests.RequestException(f"Error fetching URL: {str(e)}")
51
+ except Exception as e:
52
+ raise Exception(f"Error processing content: {str(e)}")
53
+
54
+ def _clean_html(self, soup: BeautifulSoup) -> None:
55
+ """إزالة العناصر غير المرغوب فيها من HTML"""
56
+ unwanted_tags = ['script', 'style', 'meta', 'link', 'noscript', 'header', 'footer', 'nav']
57
+ for tag in unwanted_tags:
58
+ for element in soup.find_all(tag):
59
+ element.decompose()
60
+
61
+ def _extract_texts(self, soup: BeautifulSoup) -> List[str]:
62
+ """استخراج جميع النصوص من HTML"""
63
+ text_elements = []
64
+ for element in soup.find_all(text=True):
65
+ text = element.strip()
66
+ if text:
67
+ text_elements.append(text)
68
+ return text_elements
69
+
70
+ def _clean_and_filter_texts(self, texts: List[str]) -> List[str]:
71
+ """تنظيف وتصفية النصوص"""
72
+ cleaned_texts = []
73
+ for text in texts:
74
+ # تنظيف النص من المسافات الزائدة
75
+ cleaned_text = re.sub(r'\s+', ' ', text).strip()
76
+
77
+ # تصفية النصوص غير المرغوب فيها
78
+ if self._is_valid_text(cleaned_text):
79
+ cleaned_texts.append(cleaned_text)
80
+
81
+ return cleaned_texts
82
+
83
+ def _is_valid_text(self, text: str) -> bool:
84
+ """فحص صحة النص"""
85
+ # تجاهل النصوص الفارغة أو القصيرة جداً
86
+ if not text or len(text.strip()) < 2:
87
+ return False
88
+
89
+ # تجاهل النصوص التي تحتوي على مسافات فقط
90
+ if text.isspace():
91
+ return False
92
+
93
+ # تجاهل النصوص التي تحتوي على رموز خاصة فقط
94
+ if re.match(r'^[^\w\u0600-\u06FF]+$', text):
95
+ return False
96
+
97
+ return True
98
+
99
+ def _remove_duplicates(self, texts: List[str]) -> List[Dict[str, str]]:
100
+ """إزالة النصوص المكررة"""
101
+ seen = set()
102
+ unique_texts = []
103
+
104
+ for text in texts:
105
+ if text not in seen:
106
+ seen.add(text)
107
+ unique_texts.append({'text': text})
108
+
109
+ return unique_texts
110
 
111
+ # دالة مستقلة للاستخدام السريع
112
+ def extract_text_from_url(url: str, timeout: int = 10) -> List[Dict[str, str]]:
113
  """
114
+ دالة مستق��ة لاستخراج النصوص من رابط
115
+
116
+ Args:
117
+ url: رابط الصفحة
118
+ timeout: مهلة الانتظار
119
+
120
+ Returns:
121
+ قائمة النصوص المستخرجة
122
  """
123
+ extractor = TextExtractor()
124
+ return extractor.extract_text_from_url(url, timeout)