Spaces:
Sleeping
Sleeping
import requests | |
import pandas as pd | |
from bs4 import BeautifulSoup | |
from datetime import datetime | |
import gradio as gr | |
import os | |
import schedule | |
import time | |
import threading | |
def scrape_exchange_rates(): | |
url = "https://www.mcb.com.lk/exchange-rates/" | |
try: | |
r = requests.get(url, timeout=10) | |
print(f"Status code: {r.status_code}") | |
if r.status_code != 200: | |
print(f"Failed to fetch URL: Status code {r.status_code}") | |
return None | |
soup = BeautifulSoup(r.text, "lxml") | |
table = soup.find("table", class_="uael-text-break uael-column-rules uael-table") | |
if not table: | |
print("Table not found in webpage") | |
return None | |
headers = ["Currency Type", "Buying Rate", "Selling Rate"] | |
rows = [] | |
for tr in table.find_all("tr")[2:]: | |
cells = tr.find_all("td") | |
if len(cells) >= 3: | |
row = [ | |
cells[0].text.strip(), | |
cells[1].text.strip(), | |
cells[2].text.strip() | |
] | |
rows.append(row) | |
if not rows: | |
print("No data rows found in table") | |
return None | |
df = pd.DataFrame(rows, columns=headers) | |
df['extracted_date'] = datetime.now().strftime('%Y-%m-%d') | |
print("Scraping successful") | |
return df | |
except Exception as e: | |
print(f"Scraping error: {str(e)}") | |
return None | |
def update_csv(): | |
csv_file = "data.csv" | |
today = datetime.now().strftime('%Y-%m-%d') | |
if not os.path.exists(csv_file): | |
print("CSV file not found, creating new one") | |
df = scrape_exchange_rates() | |
if df is not None: | |
df.to_csv(csv_file, index=False) | |
print(f"Initial CSV created with data for {today}") | |
else: | |
print("Failed to create initial CSV - scraping returned no data") | |
return | |
try: | |
existing_df = pd.read_csv(csv_file) | |
except Exception as e: | |
print(f"Error reading CSV: {e}") | |
existing_df = pd.DataFrame(columns=["Currency Type", "Buying Rate", "Selling Rate", "extracted_date"]) | |
if 'extracted_date' not in existing_df.columns or today not in existing_df['extracted_date'].values: | |
print(f"Updating data for {today}") | |
new_df = scrape_exchange_rates() | |
if new_df is not None: | |
updated_df = pd.concat([existing_df, new_df], ignore_index=True) | |
updated_df.to_csv(csv_file, index=False) | |
print(f"Data updated successfully for {today}") | |
else: | |
print("Failed to update data - scraping returned no data") | |
def run_schedule(): | |
schedule.every().day.at("14:00").do(update_csv) | |
while True: | |
schedule.run_pending() | |
time.sleep(60) | |
def start_scheduler(): | |
update_csv() | |
scheduler_thread = threading.Thread(target=run_schedule, daemon=True) | |
scheduler_thread.start() | |
def get_display_data(): | |
csv_file = "data.csv" | |
if os.path.exists(csv_file): | |
try: | |
df = pd.read_csv(csv_file) | |
if 'extracted_date' in df.columns and not df.empty: | |
last_date = df['extracted_date'].iloc[-1] | |
return last_date, df | |
except Exception as e: | |
print(f"Error in get_display_data: {e}") | |
return "No data available yet", pd.DataFrame(columns=["Currency Type", "Buying Rate", "Selling Rate", "extracted_date"]) | |
# Gradio interface | |
with gr.Blocks(title="Exchange Rate Monitor") as demo: | |
gr.Markdown("# Exchange Rate Monitoring System") | |
with gr.Row(): | |
last_update = gr.Textbox(label="Last Data Scraping Date", value="Loading...") | |
with gr.Row(): | |
data_table = gr.Dataframe( | |
label="Exchange Rates History", | |
headers=["Currency Type", "Buying Rate", "Selling Rate", "extracted_date"], | |
datatype=["str", "str", "str", "str"], | |
interactive=False | |
) | |
refresh_btn = gr.Button("Refresh Data") | |
def update_display(): | |
last_date, df = get_display_data() | |
return last_date, df | |
demo.load( | |
fn=update_display, | |
inputs=None, | |
outputs=[last_update, data_table] | |
) | |
refresh_btn.click( | |
fn=update_display, | |
inputs=None, | |
outputs=[last_update, data_table] | |
) | |
demo.load(fn=start_scheduler, inputs=None, outputs=None) | |
demo.launch(debug=True) |