import requests from bs4 import BeautifulSoup import json import os import gradio as gr from sentence_transformers import SentenceTransformer, util # Load the car data with open('car_dataformatted.json', 'r') as f: car_data = json.load(f) # Function to normalize key names def normalize_key(key): return key.strip().lower().replace(' ', '_') # Prepare car listings with additional fields car_listings = [] for car in car_data: description = f"{car.get('title')} - {car.get('price')} - {car.get('status')} - {car.get('link')} - {car.get('year')} - {car.get('location')} - {car.get('image_url')} - {car.get('mileage')} - {car.get('BodyType')} - {car.get('colour')} - {car.get('DrivingWheels')} - {car.get('EngineSize')} - {car.get('FuelType')} - {car.get('GearboxType')} - {car.get('power')} - {car.get('seats')}" car_listings.append(description.strip()) # Load a pre-trained Sentence Transformer model model_name = 'paraphrase-MiniLM-L6-v2' model = SentenceTransformer(model_name) # Vectorize the car listings car_embeddings = model.encode(car_listings, convert_to_tensor=True) def search_cars(query): # Vectorize the query query_embedding = model.encode(query, convert_to_tensor=True) # Calculate cosine similarity between the query and each car listing cos_scores = util.pytorch_cos_sim(query_embedding, car_embeddings)[0] # Normalize query to lower case and remove spaces for comparison query_normalized = query.replace(" ", "").lower() # Adjust boost logic and thresholds boosted_scores = [] for score, car in zip(cos_scores, car_data): boost = 0 # Normalize fields for comparison normalized_fields = {normalize_key(field): car.get(field, '').replace(" ", "").lower() for field in ['title', 'price', 'status', 'year', 'location']} # Check if query term is in any relevant field if any(query_normalized in normalized_fields[field] for field in normalized_fields): boost = 0.8 # Increase boost for better differentiation boosted_scores.append(score.item() + boost) # Combine the scores with their respective car descriptions and sort results = list(zip(boosted_scores, car_listings, car_data)) results = sorted(results, key=lambda x: x[0], reverse=True) # Separate results into two tables based on the score threshold high_score_results = [r for r in results if r[0] >= 0.5] # Adjust threshold as needed low_score_results = [r for r in results if 0.1 <= r[0] < 0.5] # Adjust lower score threshold # Format results for display as cards response_html = "" # High score results cards if high_score_results: response_html += "
Price: {car_info.get('price')}
" response_html += f"Status: {car_info.get('status')}
" response_html += f"Body Type: {car_info.get('BodyType')}
" response_html += f"Year: {car_info.get('year')}
" response_html += f"Mileage: {car_info.get('Mileage')}
" response_html += f"Location: {car_info.get('location')}
" response_html += f"View Listing" response_html += f"Similarity Score: {score:.4f}
" response_html += "Price: {car_info.get('price')}
" response_html += f"Status: {car_info.get('status')}
" response_html += f"Body Type: {car_info.get('BodyType')}
" response_html += f"Year: {car_info.get('year')}
" response_html += f"Mileage: {car_info.get('Mileage')}
" response_html += f"Location: {car_info.get('location')}
" response_html += f"View Listing" response_html += f"Similarity Score: {score:.4f}
" response_html += "