84 lines
3.5 KiB
Python
84 lines
3.5 KiB
Python
import httpx
|
|
import asyncio
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
from sqlalchemy import select
|
|
from app.models.vehicle import VehicleCatalog # Az imént létrehozott modell
|
|
|
|
class VehicleHarvester:
|
|
def __init__(self):
|
|
# Az ingyenes CarQueryAPI URL-je (0.3-as verzió)
|
|
self.base_url = "https://www.carqueryapi.com/api/0.3/"
|
|
self.headers = {"User-Agent": "ServiceFinder-Harvester-Bot/1.0"}
|
|
|
|
async def get_data(self, params: dict):
|
|
"""Segédfüggvény az API hívásokhoz."""
|
|
async with httpx.AsyncClient() as client:
|
|
try:
|
|
response = await client.get(self.base_url, params=params, headers=self.headers, timeout=10.0)
|
|
if response.status_code == 200:
|
|
# Az API néha JSONP-t ad vissza, ezt itt lekezeljük (levágjuk a felesleget)
|
|
text = response.text
|
|
if text.startswith("?("): text = text[2:-2]
|
|
return response.json()
|
|
return None
|
|
except Exception as e:
|
|
print(f"Robot hiba: {str(e)}")
|
|
return None
|
|
|
|
async def harvest_all(self, db: AsyncSession):
|
|
"""A fő folyamat: Minden márka -> Minden modell szinkronizálása."""
|
|
print("🤖 Robot: Indul a nagy adatgyűjtés...")
|
|
|
|
# 1. Márkák lekérése
|
|
makes_data = await self.get_data({"cmd": "getMakes", "sold_in_us": 0})
|
|
if not makes_data: return
|
|
|
|
makes = makes_data.get("Makes", [])
|
|
|
|
for make in makes:
|
|
make_id = make['make_id']
|
|
make_display = make['make_display']
|
|
print(f"--- 🚗 Feldolgozás: {make_display} ---")
|
|
|
|
# 2. Modellek lekérése ehhez a márkához
|
|
models_data = await self.get_data({"cmd": "getModels", "make": make_id})
|
|
if not models_data: continue
|
|
|
|
models = models_data.get("Models", [])
|
|
|
|
for model in models:
|
|
model_name = model['model_name']
|
|
|
|
# 3. Megnézzük, benne van-e már a katalógusban
|
|
stmt = select(VehicleCatalog).where(
|
|
VehicleCatalog.brand == make_display,
|
|
VehicleCatalog.model == model_name
|
|
)
|
|
res = await db.execute(stmt)
|
|
if res.scalar_one_or_none():
|
|
continue # Ha már megvan, ugrunk a következőre
|
|
|
|
# 4. Új bejegyzés létrehozása alapadatokkal
|
|
# Itt a Robot később "mélyebbre" áshat a specifikációkért
|
|
new_v = VehicleCatalog(
|
|
brand=make_display,
|
|
model=model_name,
|
|
category="car", # Alapértelmezett, később finomítható
|
|
factory_specs={
|
|
"api_make_id": make_id,
|
|
"harvester_source": "carquery"
|
|
}
|
|
)
|
|
db.add(new_v)
|
|
print(f"✅ Robot rögzítve: {make_display} {model_name}")
|
|
|
|
# Márkánként mentünk, hogy ne vesszen el a munka, ha megszakad
|
|
await db.commit()
|
|
await asyncio.sleep(1) # Ne terheljük túl az ingyenes API-t (Rate Limit védelem)
|
|
|
|
print("🏁 Robot: A munka oroszlánrésze kész!")
|
|
|
|
# Ez a rész csak a teszteléshez kell, ha manuálisan indítod a scriptet
|
|
if __name__ == "__main__":
|
|
# Itt lehetne egy külön indító logika
|
|
pass |