Mazenbs commited on
Commit
12deac4
·
verified ·
1 Parent(s): 37ff93a

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +58 -89
app.py CHANGED
@@ -1,98 +1,67 @@
1
- from fastapi import FastAPI, Query, HTTPException
2
- import httpx
 
3
  from bs4 import BeautifulSoup
4
- from typing import List, Dict, Any
 
5
 
6
- # تهيئة تطبيق FastAPI
7
- app = FastAPI(
8
- title="محلل محتوى الصفحة (Page Content Analyzer)",
9
- description="تطبيق لاستخراج النصوص من صفحة ويب معينة بناءً على رابط URL.",
10
- version="1.0.0"
11
- )
12
 
13
- # قائمة بالوسوم (Tags) التي يجب تجاهل محتواها عادةً (مثل النصوص البرمجية والأنماط)
14
- # Ignore these common noise-generating tags
15
- IGNORE_TAGS = {
16
- 'script', 'style', 'noscript', 'head', 'meta', 'link', 'img', 'svg',
17
- 'button', 'input', 'select', 'textarea', 'nav', 'footer', 'header',
18
- 'form', 'iframe'
19
- }
20
 
21
- # دالة مساعدة لجلب وتحليل الرابط
22
- async def fetch_and_analyze(url: str) -> List[Dict[str, str]]:
23
- """
24
- تقوم بجلب محتوى الرابط، وتحليله، واستخراج النصوص الموجودة داخل وسوم HTML.
25
- """
26
- # تعيين مهلة قصوى للطلب (بالثواني)
27
- TIMEOUT = 15
28
 
 
 
29
  try:
30
- # 1. جلب المحتوى باستخدام عميل غير متزامن
31
- # Fetch content using an async client
32
- async with httpx.AsyncClient(timeout=TIMEOUT, follow_redirects=True) as client:
33
- response = await client.get(url)
34
- # إطلاق استثناء في حال وجود رمز حالة خطأ (4xx أو 5xx)
35
- response.raise_for_status()
36
- html_content = response.text
37
-
38
- # 2. تحليل المحتوى باستخدام BeautifulSoup
39
- # Parse content using BeautifulSoup
40
- soup = BeautifulSoup(html_content, 'html.parser')
41
-
42
- results: List[Dict[str, str]] = []
43
-
44
- # Find all tags that might contain text
45
- # البحث عن جميع الوسوم التي قد تحتوي على نص
46
- for element in soup.find_all(True):
47
- # التحقق مما إذا كان الوسم خارج قائمة التجاهل وليس جزءاً من وسم آخر تم استخلاصه
48
- # Check if the tag is not in the ignore list
49
- if element.name not in IGNORE_TAGS:
50
- # الحصول على النص النظيف والمجرد من المسافات البيضاء الزائدة
51
- # Get the clean, stripped text
52
- text = element.get_text(strip=True, separator=' ')
53
-
54
- # التحقق من أن النص ليس فارغاً
55
- # Check if the text is meaningful
56
- if text:
57
- # إضافة النص إلى قائمة النتائج بالتنسيق المطلوب: {'text': '...'}
58
- results.append({'text': text})
59
-
60
- return results
61
-
62
- except httpx.InvalidURL:
63
- raise HTTPException(status_code=400, detail="الرابط غير صالح. يرجى التأكد من أن الرابط صحيح ويتضمن http:// أو https://.")
64
- except httpx.ConnectTimeout:
65
- raise HTTPException(status_code=504, detail="انتهت مهلة الاتصال بالرابط.")
66
- except httpx.HTTPStatusError as e:
67
- # Handling HTTP error status codes
68
- raise HTTPException(status_code=e.response.status_code, detail=f"فشل في جلب الرابط: {e.response.status_code} - {e.response.reason_phrase}")
69
  except Exception as e:
70
- # Catch other unexpected errors
71
- raise HTTPException(status_code=500, detail=f"حدث خطأ غير متوقع أثناء التحليل: {type(e).__name__} - {str(e)}")
72
-
73
-
74
- @app.get(
75
- "/analyze_url",
76
- summary="تحليل محتوى الصفحة واستخراج النصوص",
77
- description="يقوم بتحليل صفحة الويب المحددة واستخراج جميع النصوص الموجودة داخل وسوم HTML.",
78
- response_model=List[Dict[str, str]]
79
- )
80
- async def get_page_content(
81
- url: str = Query(
82
- ...,
83
- description="أدخل الرابط كاملاً (على سبيل المثال: https://www.google.com)",
84
- example="https://www.google.com"
85
- )
86
- ):
87
- """
88
- المسار الرئيسي لاستقبال رابط URL وتنفيذ عملية التحليل.
89
 
90
- - **url**: الرابط المراد تحليله.
91
- - **النتيجة**: قائمة من القواميس، حيث يحتوي كل قاموس على نص تم استخلاصه من وسم: `{'text': 'النص المستخرج'}`.
92
- """
93
- # استدعاء دالة الجلب والتحليل
94
- return await fetch_and_analyze(url)
95
 
96
- # معلومات تشغيل التطبيق (للتذكير)
97
- # To run this app, you would use: uvicorn app:app --reload
98
- # This instruction is for user reference only.
 
1
+ from fastapi import FastAPI, HTTPException
2
+ from pydantic import BaseModel, HttpUrl
3
+ import requests
4
  from bs4 import BeautifulSoup
5
+ from typing import List, Dict
6
+ import re
7
 
8
+ app = FastAPI(title="Text Extractor API", version="1.0.0")
 
 
 
 
 
9
 
10
+ class URLRequest(BaseModel):
11
+ url: HttpUrl
 
 
 
 
 
12
 
13
+ class TextResponse(BaseModel):
14
+ text: str
 
 
 
 
 
15
 
16
+ @app.post("/extract-text", response_model=List[TextResponse])
17
+ async def extract_text_from_url(request: URLRequest):
18
  try:
19
+ # إرسال طلب GET للرابط
20
+ headers = {
21
+ 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
22
+ }
23
+ response = requests.get(str(request.url), headers=headers, timeout=10)
24
+ response.raise_for_status()
25
+
26
+ # تحليل HTML
27
+ soup = BeautifulSoup(response.content, 'html.parser')
28
+
29
+ # إزالة العناصر غير المرغوب فيها
30
+ for element in soup(['script', 'style', 'meta', 'link', 'noscript']):
31
+ element.decompose()
32
+
33
+ # استخراج جميع النصوص من كل العناصر
34
+ text_elements = []
35
+
36
+ # البحث عن جميع العناصر التي تحتوي على نص
37
+ for element in soup.find_all(text=True):
38
+ text = element.strip()
39
+ # تنظيف النص وإزالة المسافات الزائدة
40
+ text = re.sub(r'\s+', ' ', text)
41
+
42
+ # تجاهل النصوص الفارغة والنصوص التي تحتوي على محارف خاصة فقط
43
+ if text and len(text) > 1 and not text.isspace():
44
+ text_elements.append({'text': text})
45
+
46
+ # إزالة النصوص المكررة
47
+ seen = set()
48
+ unique_texts = []
49
+ for item in text_elements:
50
+ if item['text'] not in seen:
51
+ seen.add(item['text'])
52
+ unique_texts.append(item)
53
+
54
+ return unique_texts
55
+
56
+ except requests.RequestException as e:
57
+ raise HTTPException(status_code=400, detail=f"Error fetching URL: {str(e)}")
58
  except Exception as e:
59
+ raise HTTPException(status_code=500, detail=f"Error processing content: {str(e)}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
60
 
61
+ @app.get("/")
62
+ async def root():
63
+ return {"message": "Text Extractor API is running! Send POST request to /extract-text"}
 
 
64
 
65
+ if __name__ == "__main__":
66
+ import uvicorn
67
+ uvicorn.run(app, host="0.0.0.0", port=8000)