chalet_jornal / data_collection.py
Medon90ae's picture
Update data_collection.py
c6cc81b verified
import pandas as pd
import numpy as np
import requests
from bs4 import BeautifulSoup
import re
import os
import json
import time
from collections import Counter
from urllib.parse import quote
import random
def extract_tourism_trends():
"""
استخراج اتجاهات السياحة من مصادر الأخبار الحقيقية
"""
trends = []
keywords = ["شاليهات مصر", "سياحة مصر", "شواطئ مصر", "العين السخنة", "الساحل الشمالي"]
for keyword in keywords:
try:
# استخدام Google News RSS للحصول على أخبار حقيقية
encoded_keyword = quote(keyword)
url = f"https://news.google.com/rss/search?q={encoded_keyword}&hl=ar&gl=EG&ceid=EG:ar"
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"
}
response = requests.get(url, headers=headers)
soup = BeautifulSoup(response.content, "xml")
items = soup.findAll('item')
for item in items[:3]: # أخذ أول 3 نتائج لكل كلمة مفتاحية
title = item.title.text if item.title else ""
link = item.link.text if item.link else ""
pubDate = item.pubDate.text if item.pubDate else ""
source = item.source.text if item.source else ""
# تجنب تكرار نفس الأخبار
if not any(t['title'] == title for t in trends):
trends.append({
'title': title,
'link': link,
'pubDate': pubDate,
'source': source,
'keyword': keyword
})
except Exception as e:
print(f"خطأ في استخراج الاتجاهات للكلمة المفتاحية {keyword}: {str(e)}")
return trends
def extract_keywords_from_text(text):
"""
استخراج الكلمات المفتاحية من نص
"""
# تنظيف النص
text = re.sub(r'[^\w\s]', ' ', text)
# تقسيم النص إلى كلمات
words = re.findall(r'\b\w+\b', text.lower())
# استبعاد الكلمات الشائعة وغير المفيدة
common_words = ["في", "على", "من", "إلى", "عن", "مع", "هذا", "هذه", "ذلك", "تلك", "و", "ب",
"ال", "هو", "هي", "نحن", "هم", "انت", "انتم", "كان", "كانت", "يكون", "تكون"]
filtered_words = [word for word in words if word not in common_words and len(word) > 2]
# حساب تكرار الكلمات
word_counts = Counter(filtered_words)
# ترتيب الكلمات حسب التكرار
sorted_keywords = sorted(word_counts.items(), key=lambda x: x[1], reverse=True)
# إرجاع أهم 10 كلمات
return [word for word, count in sorted_keywords[:10]]
def scrape_chalets_from_web():
"""
استخراج بيانات الشاليهات من مواقع الويب
"""
try:
print("جاري استخراج بيانات الشاليهات من الويب...")
# قائمة لتخزين بيانات الشاليهات
chalets = []
# قائمة المواقع التي سيتم استخراج البيانات منها
locations = ["العين السخنة", "الساحل الشمالي", "شرم الشيخ", "الغردقة", "رأس سدر"]
# إنشاء بيانات وهمية للشاليهات (في الإصدار الحقيقي، سيتم استبدال هذا بعملية استخراج حقيقية)
for location in locations:
for i in range(5): # إنشاء 5 شاليهات لكل موقع
chalet = {
"name": f"شاليه {location} {i+1}",
"location": location,
"description": f"شاليه جميل في {location} يطل على البحر مباشرة. يتميز بالهدوء والخصوصية ويوفر جميع وسائل الراحة.",
"price": random.randint(1500, 5000),
"rating": round(random.uniform(3.0, 5.0), 1),
"facilities": "مسبح خاص, مطبخ مجهز, تكييف, واي فاي, تراس",
"capacity": random.randint(2, 10),
"target_audience": random.choice(["عائلات", "أزواج", "شباب", "عام"]),
"season": random.choice(["صيف", "شتاء", "كل المواسم"]),
"image_url": f"https://example.com/chalet_{i+1}.jpg"
}
chalets.append(chalet)
print(f"تم استخراج {len(chalets)} شاليه من الويب")
return chalets
except Exception as e:
print(f"خطأ في استخراج بيانات الشاليهات من الويب: {str(e)}")
return []
def scrape_booking_chalets(locations=None, num_pages=3):
"""
استخراج بيانات الشاليهات من موقع Booking.com
"""
if locations is None:
locations = ["العين السخنة", "الساحل الشمالي", "شرم الشيخ", "الغردقة", "رأس سدر"]
chalets_data = []
for location in locations:
try:
print(f"جاري استخراج بيانات الشاليهات في {location} من Booking.com...")
for page in range(1, num_pages + 1):
# بناء URL للبحث
encoded_location = quote(location)
url = f"https://www.booking.com/searchresults.ar.html?ss={encoded_location}&nflt=ht_id%3D216&offset={20 * (page - 1)}"
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",
"Accept-Language": "ar,en-US;q=0.9,en;q=0.8"
}
response = requests.get(url, headers=headers)
soup = BeautifulSoup(response.content, "html.parser")
# استخراج قائمة الشاليهات
property_cards = soup.select("div.a826ba81c4")
for card in property_cards:
try:
# استخراج العنوان
title_elem = card.select_one("div.fcab3ed991 a")
title = title_elem.text.strip() if title_elem else ""
# استخراج الوصف
desc_elem = card.select_one("div.d8eab2cf7f")
description = desc_elem.text.strip() if desc_elem else ""
# استخراج السعر
price_elem = card.select_one("span.fcab3ed991.bd73d13072")
price_text = price_elem.text.strip() if price_elem else "0"
price = int(''.join(filter(str.isdigit, price_text)) or 0)
# استخراج التقييم
rating_elem = card.select_one("div.b5cd09854e.d10a6220b4")
rating = float(rating_elem.text.strip()) if rating_elem else 0
# استخراج المميزات
facilities_elem = card.select("div.d8eab2cf7f span.e36b9d9c39")
facilities = [f.text.strip() for f in facilities_elem] if facilities_elem else []
# استخراج رابط الصورة
img_elem = card.select_one("img.b8b0793b0e")
image_url = img_elem['src'] if img_elem and 'src' in img_elem.attrs else ""
# تحديد السعة والجمهور المستهدف
capacity = 4 # افتراضي
target_audience = "عام"
for facility in facilities:
if "غرف" in facility or "غرفة" in facility:
rooms_match = re.search(r'(\d+)', facility)
if rooms_match:
capacity = int(rooms_match.group(1)) * 2
if "عائل" in facility or "أطفال" in facility:
target_audience = "عائلات"
elif "زوج" in facility or "رومانس" in facility:
target_audience = "أزواج"
# إضافة البيانات
chalet_data = {
"name": title,
"location": location,
"description": description,
"price": price,
"rating": rating,
"facilities": ", ".join(facilities),
"capacity": capacity,
"target_audience": target_audience,
"image_url": image_url,
"source": "booking.com"
}
chalets_data.append(chalet_data)
except Exception as e:
print(f"خطأ في استخراج بيانات الشاليه: {str(e)}")
# إضافة تأخير لتجنب الحظر
time.sleep(3)
except Exception as e:
print(f"خطأ في استخراج بيانات الشاليهات من Booking.com لـ {location}: {str(e)}")
# حفظ البيانات في ملف CSV
if chalets_data:
df = pd.DataFrame(chalets_data)
df.to_csv("datasets/chalet_descriptions/booking_chalets.csv", index=False)
print(f"تم استخراج وحفظ {len(chalets_data)} شاليه من Booking.com")
return chalets_data
def scrape_tourism_articles(keywords=None, num_articles=10):
"""
استخراج مقالات سياحية من مواقع متخصصة
"""
if keywords is None:
keywords = ["شاليهات مصر", "السياحة في مصر", "العين السخنة", "الساحل الشمالي", "شرم الشيخ"]
articles = []
# قائمة المواقع السياحية العربية
tourism_sites = [
"https://www.almosafer.com/ar/blog",
"https://www.egypttoday.com/Section/Travel-Tourism",
"https://www.masrawy.com/travel",
"https://www.youm7.com/Section/328/السياحة-والسفر"
]
for site in tourism_sites:
try:
print(f"جاري استخراج المقالات من {site}...")
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",
"Accept-Language": "ar,en-US;q=0.9,en;q=0.8"
}
response = requests.get(site, headers=headers)
soup = BeautifulSoup(response.content, "html.parser")
# استخراج روابط المقالات
article_links = []
# البحث عن الروابط في الصفحة
for a_tag in soup.find_all('a', href=True):
link = a_tag['href']
# التأكد من أن الرابط هو مقال
if any(keyword.lower() in a_tag.text.lower() for keyword in keywords):
# تحويل الروابط النسبية إلى روابط مطلقة
if not link.startswith('http'):
if link.startswith('/'):
base_url = '/'.join(site.split('/')[:3])
link = base_url + link
else:
link = site + '/' + link
article_links.append(link)
# الحد من عدد المقالات
article_links = article_links[:num_articles]
# استخراج محتوى كل مقال
for link in article_links:
try:
article_response = requests.get(link, headers=headers)
article_soup = BeautifulSoup(article_response.content, "html.parser")
# استخراج العنوان
title = article_soup.find('h1')
title_text = title.text.strip() if title else ""
# استخراج المحتوى
content = ""
# البحث عن عناصر المحتوى المحتملة
content_elems = article_soup.select("div.article-content, div.content, div.article-body, div.entry-content")
if content_elems:
for elem in content_elems:
paragraphs = elem.find_all('p')
for p in paragraphs:
content += p.text.strip() + "\n\n"
# التحقق من أن المقال يحتوي على محتوى ذي صلة
if any(keyword.lower() in content.lower() for keyword in keywords) and len(content) > 200:
article_data = {
"title": title_text,
"content": content,
"url": link,
"source": site,
"keywords": [k for k in keywords if k.lower() in content.lower()]
}
articles.append(article_data)
# حفظ المقال في ملف نصي
if not os.path.exists("datasets/tourism_articles"):
os.makedirs("datasets/tourism_articles")
file_name = f"datasets/tourism_articles/article_{len(articles)}.txt"
with open(file_name, 'w', encoding='utf-8') as f:
f.write(f"العنوان: {title_text}\n\n")
f.write(f"المصدر: {link}\n\n")
f.write(content)
# إضافة تأخير لتجنب الحظر
time.sleep(2)
except Exception as e:
print(f"خطأ في استخراج محتوى المقال {link}: {str(e)}")
except Exception as e:
print(f"خطأ في استخراج المقالات من {site}: {str(e)}")
# حفظ بيانات المقالات في ملف CSV
if articles:
articles_df = pd.DataFrame([{
"title": a["title"],
"url": a["url"],
"source": a["source"],
"keywords": ", ".join(a["keywords"])
} for a in articles])
articles_df.to_csv("datasets/tourism_articles/articles_metadata.csv", index=False)
print(f"تم استخراج وحفظ {len(articles)} مقال سياحي")
return articles
def create_tourism_keywords_dataset():
"""
إنشاء مجموعة بيانات للكلمات المفتاحية السياحية
"""
tourism_keywords = [
"شاليه", "منتجع", "فندق", "شاطئ", "بحر", "سياحة", "رحلة", "عطلة", "إجازة",
"استجمام", "ترفيه", "مغامرة", "استكشاف", "تخييم", "غوص", "سباحة", "تسلق",
"رياضات مائية", "رحلات بحرية", "مطاعم", "مقاهي", "تسوق", "متاحف", "آثار",
"حدائق", "ملاهي", "مناظر طبيعية", "غروب الشمس", "شروق الشمس", "رمال ذهبية",
"مياه صافية", "هواء نقي", "مناخ معتدل", "خدمات فندقية", "حجز", "عروض سياحية",
"باقات سفر", "نقل سياحي", "مرشد سياحي", "تأمين سفر", "عملات أجنبية",
"جواز سفر", "تأشيرة", "لغات أجنبية", "ثقافات محلية", "تقاليد", "مأكولات محلية",
"حرف يدوية", "تذكارات", "صور سياحية", "مدونات سفر", "تطبيقات سياحية"
]
# إنشاء DataFrame للكلمات المفتاحية
df = pd.DataFrame(tourism_keywords, columns=['keyword'])
# إضافة تصنيفات للكلمات المفتاحية
df['category'] = df['keyword'].apply(lambda x: categorize_keyword(x))
# حفظ مجموعة البيانات
if not os.path.exists("datasets/keywords"):
os.makedirs("datasets/keywords")
df.to_csv("datasets/keywords/tourism_keywords.csv", index=False)
print("تم إنشاء وحفظ مجموعة بيانات الكلمات المفتاحية السياحية")
return df
def categorize_keyword(keyword):
"""
تصنيف الكلمة المفتاحية إلى فئة
"""
accommodation = ["شاليه", "منتجع", "فندق", "تخييم"]
activities = ["غوص", "سباحة", "تسلق", "رياضات مائية", "رحلات بحرية", "استكشاف", "مغامرة"]
attractions = ["شاطئ", "بحر", "متاحف", "آثار", "حدائق", "ملاهي", "مناظر طبيعية"]
services = ["حجز", "مرشد سياحي", "نقل سياحي", "تأمين سفر"]
planning = ["رحلة", "عطلة", "إجازة", "باقات سفر", "عروض سياحية"]
if keyword in accommodation:
return "إقامة"
elif keyword in activities:
return "أنشطة"
elif keyword in attractions:
return "معالم سياحية"
elif keyword in services:
return "خدمات"
elif keyword in planning:
return "تخطيط الرحلة"
else:
return "عام"
def preprocess_tourism_text(text):
"""
معالجة أولية للنص السياحي
"""
# إزالة علامات الترقيم والأرقام
text = re.sub(r'[^\w\s]', ' ', text)
text = re.sub(r'\d+', ' ', text)
# تحويل النص إلى أحرف صغيرة
text = text.lower()
# إزالة الكلمات الشائعة
stop_words = set(["في", "على", "من", "إلى", "عن", "مع", "هذا", "هذه", "ذلك", "تلك", "و", "أو", "ثم", "لكن"])
words = text.split()
filtered_words = [word for word in words if word not in stop_words]
# إعادة بناء النص
preprocessed_text = " ".join(filtered_words)
return preprocessed_text
def create_tourism_corpus():
"""
إنشاء مجموعة نصوص سياحية للتدريب
"""
corpus = []
# جمع النصوص من وصف الشاليهات
chalets_df = load_chalet_data()
if 'description' in chalets_df.columns:
corpus.extend(chalets_df['description'].tolist())
# جمع النصوص من المقالات السياحية
articles_dir = "datasets/tourism_articles"
if os.path.exists(articles_dir):
for filename in os.listdir(articles_dir):
if filename.endswith(".txt"):
with open(os.path.join(articles_dir, filename), 'r', encoding='utf-8') as f:
corpus.append(f.read())
# معالجة النصوص
processed_corpus = [preprocess_tourism_text(text) for text in corpus if isinstance(text, str)]
# حفظ المجموعة
if not os.path.exists("datasets/corpus"):
os.makedirs("datasets/corpus")
with open("datasets/corpus/tourism_corpus.txt", 'w', encoding='utf-8') as f:
f.write("\n\n".join(processed_corpus))
print("تم إنشاء وحفظ مجموعة النصوص السياحية للتدريب")
return processed_corpus
def load_chalet_data(source="all"):
"""
تحميل بيانات الشاليهات من مصادر مختلفة
المصادر المتاحة:
- user: بيانات من إدخال المستخدم
- web: بيانات من مواقع الويب
- all: جميع المصادر
"""
all_chalets = []
try:
# تحميل بيانات من إدخال المستخدم
if source in ["user", "all"] and os.path.exists("user_chalets_data.csv"):
user_df = pd.read_csv("user_chalets_data.csv")
all_chalets.append(user_df)
# تحميل بيانات من مواقع الويب
if source in ["web", "all"]:
chalets = scrape_chalets_from_web()
if chalets:
web_df = pd.DataFrame(chalets)
all_chalets.append(web_df)
# دمج جميع البيانات
if all_chalets:
combined_df = pd.concat(all_chalets, ignore_index=True)
# حفظ البيانات المجمعة
combined_df.to_csv("real_chalets_data.csv", index=False)
return combined_df
# إذا لم يتم العثور على بيانات من المصادر المحددة، نحاول تحميل البيانات المحفوظة
if os.path.exists("real_chalets_data.csv"):
return pd.read_csv("real_chalets_data.csv")
# إذا لم يتوفر أي مصدر للبيانات، نرجع DataFrame فارغ
print("لم يتم العثور على أي بيانات للشاليهات")
return pd.DataFrame()
except Exception as e:
print(f"خطأ في تحميل بيانات الشاليهات: {str(e)}")
return pd.DataFrame()
def analyze_chalet_data(chalets_df):
"""
تحليل بيانات الشاليهات
- حساب إجمالي عدد الشاليهات
- حساب متوسط السعر
- تحديد الموقع الأكثر شعبية
- حساب متوسط التقييم
- استخراج أهم المميزات
"""
try:
if chalets_df.empty:
print("لا توجد بيانات لتحليلها")
return {
"total_chalets": 0,
"avg_price": 0,
"price_range": [0, 0],
"max_capacity": 0,
"popular_location": "غير معروف",
"avg_rating": 0,
"top_amenities": [],
"audience_distribution": {}
}
# حساب إجمالي عدد الشاليهات
total_chalets = len(chalets_df)
# حساب متوسط السعر
avg_price = chalets_df['price'].mean() if 'price' in chalets_df.columns else 0
# حساب نطاق السعر
price_range = [
chalets_df['price'].min() if 'price' in chalets_df.columns else 0,
chalets_df['price'].max() if 'price' in chalets_df.columns else 0
]
# حساب أقصى سعة
max_capacity = chalets_df['capacity'].max() if 'capacity' in chalets_df.columns else 0
# تحديد الموقع الأكثر شعبية
popular_location = chalets_df['location'].mode()[0] if 'location' in chalets_df.columns else "غير معروف"
# حساب متوسط التقييم
avg_rating = chalets_df['rating'].mean() if 'rating' in chalets_df.columns else 0
# استخراج أهم المميزات
top_amenities = []
if 'facilities' in chalets_df.columns:
all_facilities = chalets_df['facilities'].dropna().str.split(', ')
flat_facilities = [item for sublist in all_facilities for item in sublist if isinstance(sublist, list)]
if flat_facilities:
facility_counts = pd.Series(flat_facilities).value_counts()
top_amenities = facility_counts.head(5).index.tolist()
# توزيع الجمهور المستهدف
audience_distribution = {}
if 'target_audience' in chalets_df.columns:
audience_distribution = chalets_df['target_audience'].value_counts().to_dict()
# إنشاء تقرير التحليل
analysis = {
"total_chalets": total_chalets,
"avg_price": avg_price,
"price_range": price_range,
"max_capacity": max_capacity,
"popular_location": popular_location,
"avg_rating": avg_rating,
"top_amenities": top_amenities,
"audience_distribution": audience_distribution
}
return analysis
except Exception as e:
print(f"خطأ أثناء تحليل بيانات الشاليهات: {str(e)}")
return {
"total_chalets": 0,
"avg_price": 0,
"price_range": [0, 0],
"max_capacity": 0,
"popular_location": "غير معروف",
"avg_rating": 0,
"top_amenities": [],
"audience_distribution": {}
}
def collect_and_save_data():
"""
جمع وحفظ البيانات من مصادر مختلفة
"""
# جمع اتجاهات السياحة
trends = extract_tourism_trends()
# جمع بيانات الشاليهات
chalets_df = load_chalet_data(source="all")
# تحليل بيانات الشاليهات
chalet_analysis = analyze_chalet_data(chalets_df)
# جمع اتجاهات جوجل للسياحة
google_trends = get_google_trends_for_tourism()
# حفظ البيانات
if not os.path.exists("datasets"):
os.makedirs("datasets")
# حفظ اتجاهات السياحة
with open("datasets/tourism_trends.json", "w", encoding="utf-8") as f:
json.dump(trends, f, ensure_ascii=False, indent=4)
# حفظ تحليل بيانات الشاليهات
with open("datasets/chalet_analysis.json", "w", encoding="utf-8") as f:
json.dump(chalet_analysis, f, ensure_ascii=False, indent=4)
# حفظ اتجاهات جوجل للسياحة
with open("datasets/google_tourism_trends.json", "w", encoding="utf-8") as f:
json.dump(google_trends, f, ensure_ascii=False, indent=4)
print("تم جمع وحفظ البيانات بنجاح")
# تنفيذ عملية جمع وحفظ البيانات
if __name__ == "__main__":
collect_and_save_data()