File size: 6,704 Bytes
ce348e1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
import requests
from bs4 import BeautifulSoup
import logging
import json
import time
from typing import List, Dict
from random import choice
from datetime import datetime

# Logging setup
logging.basicConfig(
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
    level=logging.INFO,
    handlers=[logging.FileHandler("scraper.log", encoding='utf-8'), logging.StreamHandler()]
)
logger = logging.getLogger(__name__)

# قائمة User-Agent عشوائية لتجنب الحظر
USER_AGENTS = [
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.1 Safari/605.1.15",
    "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36",
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:89.0) Gecko/20100101 Firefox/89.0"
]

# Headers لمحاكاة متصفح حقيقي
def get_headers() -> dict:
    return {
        "User-Agent": choice(USER_AGENTS),
        "Accept-Language": "en-US,en;q=0.9",
        "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
        "Connection": "keep-alive"
    }

def scrape_website(url: str, retries: int = 3) -> List[Dict]:
    """

    جمع بيانات السيارات من موقع ويب معين مع إعادة المحاولة عند الفشل.

    """
    for attempt in range(retries):
        try:
            response = requests.get(url, headers=get_headers(), timeout=10)
            response.raise_for_status()
            soup = BeautifulSoup(response.content, "html.parser")
            cars_data = []

            # محددات عامة (يجب تعديلها حسب هيكلية كل موقع)
            car_listings = soup.select(".car-item, .listing-item, .product-item, .car-listing, .ad-item, .vehicle-item")
            if not car_listings:
                logger.warning(f"لم يتم العثور على قوائم سيارات في {url}. تحققي من المحددات.")
                return cars_data

            for car in car_listings:
                try:
                    car_data = {}
                    # تحقق من وجود العنصر قبل استخراج النص
                    name_elem = car.select_one(".car-title, .product-title, .listing-title, .ad-title, .vehicle-title, h2, h3")
                    car_data["name"] = name_elem.text.strip() if name_elem else "غير محدد"
                    
                    price_elem = car.select_one(".car-price, .price, .product-price, .listing-price, .ad-price")
                    car_data["price"] = price_elem.text.strip() if price_elem else "غير محدد"
                    
                    year_elem = car.select_one(".car-year, .year, .model-year")
                    car_data["model_year"] = year_elem.text.strip() if year_elem else "غير محدد"
                    
                    location_elem = car.select_one(".car-location, .location, .city")
                    car_data["location"] = location_elem.text.strip() if location_elem else "غير محدد"
                    
                    desc_elem = car.select_one(".car-description, .description, .details")
                    car_data["description"] = desc_elem.text.strip() if desc_elem else "غير محدد"
                    
                    # إضافة بيانات الصيانة وقطع الغيار
                    maintenance_elem = car.select_one(".maintenance, .service-info")
                    car_data["maintenance"] = maintenance_elem.text.strip() if maintenance_elem else "غير محدد"
                    
                    spare_parts_elem = car.select_one(".spare-parts, .parts-info")
                    car_data["spare_parts"] = spare_parts_elem.text.strip() if spare_parts_elem else "غير محدد"
                    
                    car_data["source"] = url.split("//")[1].split("/")[0]
                    car_data["scraped_at"] = datetime.now().isoformat()
                    cars_data.append(car_data)
                    logger.info(f"تم جمع بيانات: {car_data['name']} - {car_data['price']} من {url}")
                except Exception as e:
                    logger.error(f"خطأ في استخراج بيانات سيارة من {url}: {str(e)}")
                    continue

            return cars_data
        except requests.exceptions.RequestException as e:
            logger.error(f"خطأ في الاتصال بـ {url} (محاولة {attempt + 1}/{retries}): {str(e)}")
            if attempt < retries - 1:
                time.sleep(5 * (attempt + 1))  # تأخير متزايد
            else:
                return []
        except Exception as e:
            logger.error(f"خطأ غير متوقع في scrape_website لـ {url}: {str(e)}")
            return []

def save_data(data: List[Dict], filename: str = "cars_data.json"):
    """

    تخزين البيانات في ملف JSON.

    """
    try:
        with open(filename, "w", encoding="utf-8") as f:
            json.dump(data, f, ensure_ascii=False, indent=4)
        logger.info(f"تم تخزين {len(data)} عنصر في {filename}")
    except Exception as e:
        logger.error(f"خطأ في تخزين البيانات في {filename}: {str(e)}")

if __name__ == "__main__":
    websites = [
        "https://iq.labeb.com/ct/cars-for-sale-558",
        "https://www.akosayara.com/",
        "https://www.iqcars.net/",
        "https://alrashad.com.iq/",
        "https://website.tao.iq/index.php/ar/",
        "https://www.quattro-iq.com/home-ar",
        "https://iq.opensooq.com/ar/%D9%85%D8%B1%D8%A7%D9%83%D8%B2-%D8%AE%D8%AF%D9%85%D8%A7%D8%AA-%D8%A7%D9%84%D8%B3%D9%8A%D8%A7%D8%B1%D8%A7%D8%AA/%D8%A7%D9%84%D8%AE%D8%AF%D9%85%D8%A7%D8%AA/%D9%82%D8%B7%D8%B9-%D8%BA%D9%8A%D8%A7%D8%B1",
        "https://ghiarati.com/",
        "https://www.motors.iq/",
        "https://www.alsayyara.com/"
    ]

    while True:
        all_cars_data = []
        for url in websites:
            logger.info(f"جمع البيانات من {url}")
            cars_data = scrape_website(url)
            all_cars_data.extend(cars_data)
            time.sleep(5)  # تأخير 5 ثواني لتجنب الحظر

        save_data(all_cars_data)
        logger.info("تم الانتهاء من جمع البيانات. النوم لمدة ساعة...")
        time.sleep(3600)  # تحديث كل ساعة