Spaces:
Build error
Build error
Update app.py
Browse files
app.py
CHANGED
|
@@ -88,7 +88,7 @@ def normalize_title(title):
|
|
| 88 |
# Legge gli ANNUNCI (pagina x pagina) sulla base del COMUNE di appartenenza
|
| 89 |
def scrape_immobiliare(provincia, comune, prezzo_medio_mq, prezzo_minimo, prezzo_massimo, locali_minimo, locali_massimo):
|
| 90 |
print(provincia + " " + comune + " " + prezzo_medio_mq)
|
| 91 |
-
comune_url = comune.replace(" ", "-").replace("è", "e").replace("é", "e").replace("ò", "o").replace("à", "a").replace("ù", "u").replace("ì", "i")
|
| 92 |
if st.tipologia_case == "Asta Immobiliare":
|
| 93 |
tipologia_url = "aste-immobiliari"
|
| 94 |
else:
|
|
@@ -124,7 +124,7 @@ def scrape_immobiliare(provincia, comune, prezzo_medio_mq, prezzo_minimo, prezzo
|
|
| 124 |
obj for obj in results
|
| 125 |
if normalize_title(obj['Titolo']) not in seen_titles and not seen_titles.add(normalize_title(obj['Titolo']))
|
| 126 |
]
|
| 127 |
-
return json.dumps(results, ensure_ascii=False, indent=2)
|
| 128 |
|
| 129 |
# Restituisce l'elenco dei COMUNI di una Provincia e il PREZZO MEDIO
|
| 130 |
def get_elenco_comuni(provincia):
|
|
@@ -155,10 +155,16 @@ def get_elenco_comuni(provincia):
|
|
| 155 |
cerca_premuto = False
|
| 156 |
comuni_provincia = {}
|
| 157 |
|
| 158 |
-
def scrivi_dataframe(output, riepilogo, comune, da_excel = False, df_excel = None):
|
| 159 |
if len(output) > 0 or (da_excel and df_excel is not None):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 160 |
st.numero_immobili_validi = st.numero_immobili_validi + 1
|
| 161 |
-
if not riepilogo:
|
| 162 |
st.write(f"### {comune}")
|
| 163 |
if da_excel:
|
| 164 |
df = df_excel
|
|
@@ -199,8 +205,7 @@ def scrivi_dataframe(output, riepilogo, comune, da_excel = False, df_excel = Non
|
|
| 199 |
st.metric("Media Superficie", int(superficie_count//total_rows), int(superficie_count))
|
| 200 |
st.write('Prezzo Medio al Metro Quadro')
|
| 201 |
chart_data = df_originale["PrezzoMq"]
|
| 202 |
-
st.area_chart(chart_data, color = "#FF4B4B", height=110)
|
| 203 |
-
|
| 204 |
st.dataframe(df, hide_index=True, use_container_width=True,
|
| 205 |
column_config ={
|
| 206 |
"Vantaggioso": st.column_config.CheckboxColumn("Vantaggioso"),
|
|
@@ -224,7 +229,10 @@ def scrivi_dataframe(output, riepilogo, comune, da_excel = False, df_excel = Non
|
|
| 224 |
"Locali": "Locali",
|
| 225 |
"Link": st.column_config.LinkColumn("App URL")
|
| 226 |
})
|
| 227 |
-
|
|
|
|
|
|
|
|
|
|
| 228 |
st.divider()
|
| 229 |
|
| 230 |
def analizza_dati_ai(output, tipologia):
|
|
@@ -398,6 +406,33 @@ def calcola_prezzo_mq(row):
|
|
| 398 |
else:
|
| 399 |
return row['Prezzo'] // row['Superficie']
|
| 400 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 401 |
def importa_excel(file):
|
| 402 |
df = None
|
| 403 |
if file.name.endswith('.csv'):
|
|
@@ -417,6 +452,8 @@ def importa_excel(file):
|
|
| 417 |
cell = ws.cell(row=i, column=link_column_index)
|
| 418 |
if cell.hyperlink:
|
| 419 |
df.at[i - 2, "Link asta"] = cell.hyperlink.target
|
|
|
|
|
|
|
| 420 |
if 'Perizia' in df.columns:
|
| 421 |
link_column_index = df.columns.get_loc("Perizia") + 1
|
| 422 |
for i in range(2, ws.max_row + 1):
|
|
@@ -437,11 +474,12 @@ def importa_excel(file):
|
|
| 437 |
df['Locali'] = df['Locali'].fillna(0).astype(int)
|
| 438 |
df['PrezzoMq'] = df.apply(calcola_prezzo_mq, axis=1)
|
| 439 |
df['PrezzoMq'] = df['PrezzoMq'].fillna(0).astype(int)
|
| 440 |
-
df['Vantaggioso'] = False
|
| 441 |
-
df['Vantaggio'] = 50
|
| 442 |
df['Immagine'] = ""
|
| 443 |
-
|
| 444 |
-
|
|
|
|
|
|
|
|
|
|
| 445 |
return df
|
| 446 |
|
| 447 |
if cerca_premuto:
|
|
@@ -451,9 +489,14 @@ if cerca_premuto:
|
|
| 451 |
df = importa_excel(file)
|
| 452 |
dfs.append(df)
|
| 453 |
if dfs:
|
|
|
|
| 454 |
concatenated_df = pd.concat(dfs, ignore_index=True)
|
| 455 |
-
|
| 456 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 457 |
st.success("File Excel importati con successo")
|
| 458 |
|
| 459 |
if len(comune_input)>0:
|
|
@@ -478,22 +521,27 @@ if cerca_premuto:
|
|
| 478 |
|
| 479 |
output = []
|
| 480 |
output_singolo = []
|
|
|
|
|
|
|
|
|
|
|
|
|
| 481 |
for comune_provincia in comuni_provincia:
|
| 482 |
if comune_provincia['comune'].upper() in comuni_selezionati:
|
| 483 |
with st.spinner(f"Ricerca Immobili Comune: {comune_provincia['comune']}"):
|
| 484 |
-
|
| 485 |
-
|
| 486 |
-
|
| 487 |
-
|
| 488 |
-
|
| 489 |
-
|
| 490 |
-
|
| 491 |
-
|
|
|
|
| 492 |
output += output_singolo
|
| 493 |
time.sleep(0.10)
|
| 494 |
if len(comuni_selezionati)>1 and st.numero_immobili_validi>1:
|
| 495 |
st.write(f"### Comuni Selezionati")
|
| 496 |
-
scrivi_dataframe(output, True, '')
|
| 497 |
if st.numero_immobili_validi > 0 and st.analisi_ai:
|
| 498 |
st.title("✨ Analisi Intelligenza Artificiale")
|
| 499 |
st.write("### Considerazioni")
|
|
|
|
| 88 |
# Legge gli ANNUNCI (pagina x pagina) sulla base del COMUNE di appartenenza
|
| 89 |
def scrape_immobiliare(provincia, comune, prezzo_medio_mq, prezzo_minimo, prezzo_massimo, locali_minimo, locali_massimo):
|
| 90 |
print(provincia + " " + comune + " " + prezzo_medio_mq)
|
| 91 |
+
comune_url = comune.replace(" ", "-").replace("è", "e").replace("é", "e").replace("ò", "o").replace("à", "a").replace("ù", "u").replace("ì", "i").replace("'", "-")
|
| 92 |
if st.tipologia_case == "Asta Immobiliare":
|
| 93 |
tipologia_url = "aste-immobiliari"
|
| 94 |
else:
|
|
|
|
| 124 |
obj for obj in results
|
| 125 |
if normalize_title(obj['Titolo']) not in seen_titles and not seen_titles.add(normalize_title(obj['Titolo']))
|
| 126 |
]
|
| 127 |
+
return base_url, json.dumps(results, ensure_ascii=False, indent=2)
|
| 128 |
|
| 129 |
# Restituisce l'elenco dei COMUNI di una Provincia e il PREZZO MEDIO
|
| 130 |
def get_elenco_comuni(provincia):
|
|
|
|
| 155 |
cerca_premuto = False
|
| 156 |
comuni_provincia = {}
|
| 157 |
|
| 158 |
+
def scrivi_dataframe(url_ricerca, output, riepilogo, comune, da_excel = False, df_excel = None):
|
| 159 |
if len(output) > 0 or (da_excel and df_excel is not None):
|
| 160 |
+
|
| 161 |
+
for comune_excel, df_comune in dataframes_per_comune.items():
|
| 162 |
+
if comune_excel == comune:
|
| 163 |
+
print('a')
|
| 164 |
+
# Da fare MATTEO st.write(df_comune)
|
| 165 |
+
|
| 166 |
st.numero_immobili_validi = st.numero_immobili_validi + 1
|
| 167 |
+
if not riepilogo or da_excel:
|
| 168 |
st.write(f"### {comune}")
|
| 169 |
if da_excel:
|
| 170 |
df = df_excel
|
|
|
|
| 205 |
st.metric("Media Superficie", int(superficie_count//total_rows), int(superficie_count))
|
| 206 |
st.write('Prezzo Medio al Metro Quadro')
|
| 207 |
chart_data = df_originale["PrezzoMq"]
|
| 208 |
+
st.area_chart(chart_data, color = "#FF4B4B", height=110)
|
|
|
|
| 209 |
st.dataframe(df, hide_index=True, use_container_width=True,
|
| 210 |
column_config ={
|
| 211 |
"Vantaggioso": st.column_config.CheckboxColumn("Vantaggioso"),
|
|
|
|
| 229 |
"Locali": "Locali",
|
| 230 |
"Link": st.column_config.LinkColumn("App URL")
|
| 231 |
})
|
| 232 |
+
testo_riepilogativo = f"Riepilogando nel comune [{comune}]({url_ricerca}) sono presenti **{vantaggioso_count} Immobili vantaggiosi** rispetto ai {total_rows} totali"
|
| 233 |
+
st.write(testo_riepilogativo)
|
| 234 |
+
|
| 235 |
+
|
| 236 |
st.divider()
|
| 237 |
|
| 238 |
def analizza_dati_ai(output, tipologia):
|
|
|
|
| 406 |
else:
|
| 407 |
return row['Prezzo'] // row['Superficie']
|
| 408 |
|
| 409 |
+
def calcola_vantaggio(row):
|
| 410 |
+
if pd.isnull(row['PrezzoMedioMq']) or pd.isnull(row['PrezzoMq']):
|
| 411 |
+
return 0
|
| 412 |
+
else:
|
| 413 |
+
if isinstance(row['PrezzoMedioMq'], str):
|
| 414 |
+
prezzo_medio_mq_numerico = int(row['PrezzoMedioMq'].replace(".", ""))
|
| 415 |
+
else:
|
| 416 |
+
prezzo_medio_mq_numerico = row['PrezzoMedioMq']
|
| 417 |
+
differenza = prezzo_medio_mq_numerico - int(row['PrezzoMq'])
|
| 418 |
+
if prezzo_medio_mq_numerico != 0:
|
| 419 |
+
vantaggio = (differenza / prezzo_medio_mq_numerico) * 100
|
| 420 |
+
else:
|
| 421 |
+
vantaggio = 0
|
| 422 |
+
vantaggio = max(0, vantaggio)
|
| 423 |
+
vantaggio = int(vantaggio)
|
| 424 |
+
return vantaggio
|
| 425 |
+
|
| 426 |
+
def calcola_vantaggioso(row):
|
| 427 |
+
if isinstance(row['PrezzoMedioMq'], str):
|
| 428 |
+
prezzo_medio_mq_numerico = int(row['PrezzoMedioMq'].replace(".", ""))
|
| 429 |
+
else:
|
| 430 |
+
prezzo_medio_mq_numerico = row['PrezzoMedioMq']
|
| 431 |
+
if row['PrezzoMq'] < prezzo_medio_mq_numerico:
|
| 432 |
+
return True
|
| 433 |
+
else:
|
| 434 |
+
return False
|
| 435 |
+
|
| 436 |
def importa_excel(file):
|
| 437 |
df = None
|
| 438 |
if file.name.endswith('.csv'):
|
|
|
|
| 452 |
cell = ws.cell(row=i, column=link_column_index)
|
| 453 |
if cell.hyperlink:
|
| 454 |
df.at[i - 2, "Link asta"] = cell.hyperlink.target
|
| 455 |
+
else:
|
| 456 |
+
df.at[i - 2, "Link asta"] = ""
|
| 457 |
if 'Perizia' in df.columns:
|
| 458 |
link_column_index = df.columns.get_loc("Perizia") + 1
|
| 459 |
for i in range(2, ws.max_row + 1):
|
|
|
|
| 474 |
df['Locali'] = df['Locali'].fillna(0).astype(int)
|
| 475 |
df['PrezzoMq'] = df.apply(calcola_prezzo_mq, axis=1)
|
| 476 |
df['PrezzoMq'] = df['PrezzoMq'].fillna(0).astype(int)
|
|
|
|
|
|
|
| 477 |
df['Immagine'] = ""
|
| 478 |
+
mappatura_prezzi = {item['comune'].lower(): item['prezzo'] for item in comuni_provincia}
|
| 479 |
+
df['PrezzoMedioMq'] = df['Comune'].str.lower().map(mappatura_prezzi).combine_first(df['Prezzo'])
|
| 480 |
+
df['Vantaggio'] = df.apply(calcola_vantaggio, axis=1)
|
| 481 |
+
df['Vantaggioso'] = df.apply(calcola_vantaggioso, axis=1)
|
| 482 |
+
|
| 483 |
return df
|
| 484 |
|
| 485 |
if cerca_premuto:
|
|
|
|
| 489 |
df = importa_excel(file)
|
| 490 |
dfs.append(df)
|
| 491 |
if dfs:
|
| 492 |
+
st.info('Aste PVP')
|
| 493 |
concatenated_df = pd.concat(dfs, ignore_index=True)
|
| 494 |
+
concatenated_df = concatenated_df.sort_values(by=['Comune', 'Vantaggio', 'PrezzoMq'], ascending=[True, False, False])
|
| 495 |
+
dataframes_per_comune = {comune: df for comune, df in concatenated_df.groupby('Comune')}
|
| 496 |
+
for comune, df_comune in dataframes_per_comune.items():
|
| 497 |
+
scrivi_dataframe('', [], False, comune, True, df_comune)
|
| 498 |
+
concatenated_df = concatenated_df.sort_values(by=['Vantaggio', 'PrezzoMq'], ascending=[False, False])
|
| 499 |
+
scrivi_dataframe('', [], False, 'Riepilogo PVP', True, concatenated_df)
|
| 500 |
st.success("File Excel importati con successo")
|
| 501 |
|
| 502 |
if len(comune_input)>0:
|
|
|
|
| 521 |
|
| 522 |
output = []
|
| 523 |
output_singolo = []
|
| 524 |
+
if st.tipologia_case == "Asta Immobiliare":
|
| 525 |
+
st.info('Aste Immobiliare.it')
|
| 526 |
+
else:
|
| 527 |
+
st.info('Vendita Immobiliare.it')
|
| 528 |
for comune_provincia in comuni_provincia:
|
| 529 |
if comune_provincia['comune'].upper() in comuni_selezionati:
|
| 530 |
with st.spinner(f"Ricerca Immobili Comune: {comune_provincia['comune']}"):
|
| 531 |
+
url_ricerca, json_object = scrape_immobiliare(comune_provincia['provincia'],
|
| 532 |
+
comune_provincia['comune'],
|
| 533 |
+
comune_provincia['prezzo'],
|
| 534 |
+
prezzo_minimo,
|
| 535 |
+
prezzo_massimo,
|
| 536 |
+
locali_minimo,
|
| 537 |
+
locali_massimo)
|
| 538 |
+
output_singolo = json.loads(json_object)
|
| 539 |
+
scrivi_dataframe(url_ricerca, output_singolo, False, comune_provincia['comune'])
|
| 540 |
output += output_singolo
|
| 541 |
time.sleep(0.10)
|
| 542 |
if len(comuni_selezionati)>1 and st.numero_immobili_validi>1:
|
| 543 |
st.write(f"### Comuni Selezionati")
|
| 544 |
+
scrivi_dataframe('', output, True, '')
|
| 545 |
if st.numero_immobili_validi > 0 and st.analisi_ai:
|
| 546 |
st.title("✨ Analisi Intelligenza Artificiale")
|
| 547 |
st.write("### Considerazioni")
|