-
-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #9 from elinventor/main
Fix: script para data desde Exchange Monitor
- Loading branch information
Showing
3 changed files
with
75 additions
and
52 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,62 +1,62 @@ | ||
from typing import Any, Dict, List | ||
from bs4 import BeautifulSoup | ||
from datetime import datetime | ||
import requests | ||
import pytz | ||
|
||
from ..network import _headers | ||
from ..utils.common import _convert_specific_format, _parse_price, _parse_percent | ||
from ..utils.time import get_formatted_date | ||
|
||
from .. import network | ||
from ..utils import time | ||
from ..utils.extras import list_monitors_images | ||
from ._base import Base | ||
from ..pages import ExchangeMonitor as ExchangeMonitorPage | ||
|
||
def _convert_specific_format(text: str, character: str = '_') -> str: | ||
acentos = {'á': 'a', 'é': 'e', 'í': 'i', 'ó': 'o', 'ú': 'u'} | ||
for acento, sin_acento in acentos.items(): | ||
text = text.lower().replace(acento, sin_acento).replace(' ', character) | ||
return text | ||
|
||
def _get_values_monitors(soup: BeautifulSoup): | ||
return [value for value in soup] | ||
|
||
class ExchangeMonitor(Base): | ||
PAGE = ExchangeMonitorPage | ||
|
||
@classmethod | ||
def _load(cls, **kwargs) -> List[Dict[str, Any]]: | ||
url = f'{cls.PAGE.provider}dolar-venezuela' if not kwargs.get('currency') == 'usd' else f'{cls.PAGE.provider}dolar-venezuela/EUR' | ||
response = network.curl('GET', url) | ||
soup = BeautifulSoup(response, 'html.parser') | ||
|
||
section_dolar_venezuela = soup.find_all("div", "col-xs-12 col-sm-6 col-md-4 col-tabla") | ||
_scraping_monitors = _get_values_monitors(section_dolar_venezuela) | ||
data = [] | ||
|
||
for scraping_monitor in _scraping_monitors: | ||
result = scraping_monitor.find("div", "module-table module-table-fecha") | ||
|
||
name = result.find("h6", "nombre").text | ||
key = _convert_specific_format(name) | ||
price = str(result.find('p', "precio").text).replace(',', '.') | ||
|
||
if price.count('.') == 2: | ||
price = price.replace('.', '', 1) | ||
|
||
price = float(price) | ||
last_update = time.get_formatted_time(' '.join(str(result.find('p', "fecha").text).split(' ')[1:]).capitalize()) | ||
symbol = str(result.find('p', "cambio-por").text)[0] if not str(result.find('p', "cambio-por").text)[0] == ' ' else '' | ||
color = "red" if symbol == '▼' else "green" if symbol == '▲' else "neutral" | ||
percent = float(str(result.find('p', "cambio-por").text)[1:].strip().replace(',', '.').replace('%', '')) | ||
change = float(str(result.find('p', "cambio-num").text).replace(',', '.')) | ||
image = next((image.image for image in list_monitors_images if image.provider == 'exchangemonitor' and image.title == _convert_specific_format(name)), None) | ||
|
||
data.append({ | ||
'key': key, | ||
'title': name, | ||
'price': price, | ||
'last_update': last_update, | ||
'percent': percent, | ||
'change': change, | ||
'color': color, | ||
'symbol': symbol, | ||
'image': image | ||
}) | ||
|
||
return data | ||
tz = pytz.timezone('America/Caracas') | ||
|
||
url = f'{cls.PAGE.provider}/data/data-rates/ve' | ||
|
||
# Realizar la solicitud GET a la API | ||
response = requests.get(url, headers=_headers) | ||
|
||
# Verificar que la solicitud fue exitosa | ||
if response.status_code == 200: | ||
data_json = response.json() | ||
|
||
# Extraer los datos requeridos | ||
result = [] | ||
for item in data_json["data"]: | ||
# Parsear la fecha y hora (sin zona horaria) | ||
date_naive = datetime.strptime(item.get("date"), "%d-%m-%Y %I:%M %p") | ||
|
||
# Asignar y formatear valores | ||
date_aware = str(tz.localize(date_naive)) | ||
logo = item.get("logo") | ||
net_change = _parse_percent(item.get("change_rate")) | ||
net_chg = str(item.get("change_rate")) | ||
color = "red" if "-" in net_chg else "green" if "+" in net_chg else "" | ||
symbol = "▼" if "-" in net_chg else "▲" if "+" in net_chg else "neutral" | ||
|
||
extracted_data = { | ||
"key": _convert_specific_format(item.get("id")), | ||
"title": _convert_specific_format(item.get("name")), | ||
"price": _parse_price(item.get("rate")), | ||
"price_old": _parse_price(item.get("last_rate")), | ||
"last_update":get_formatted_date(date_aware), | ||
"percent": _parse_percent(item.get("change_perc")), | ||
"change": net_change, | ||
"color": color, | ||
"symbol": symbol, | ||
"image": f'{cls.PAGE.provider}{logo}' | ||
} | ||
result.append(extracted_data) | ||
|
||
return result | ||
|
||
else: | ||
print(f"Error retrieving data from API: {response.status_code}") | ||
return [] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
def _convert_specific_format(text: str, character: str = '_') -> str: | ||
""" | ||
Formatea el nombre de moneda para omologar todas las salidas de los datos de un monitor específico. | ||
""" | ||
acentos = {'á': 'a', 'é': 'e', 'í': 'i', 'ó': 'o', 'ú': 'u'} | ||
for acento, sin_acento in acentos.items(): | ||
text = text.lower().replace(acento, sin_acento).replace(' ', character) | ||
return text | ||
|
||
def _parse_price(price: str) -> float: | ||
""" | ||
Convierte el formato de una moneda a de "," al uso del "." (Formato standard). | ||
""" | ||
price = price.replace(',', '.') | ||
if price.count('.') == 2: | ||
price = price.replace('.', '', 1) | ||
return float(price) | ||
|
||
def _parse_percent(percent: str) -> float: | ||
""" | ||
Convierte el formato del cambio porcentual de "," al uso del "." y agrega el simbolo "%". | ||
""" | ||
return float(percent.strip().replace(',', '.').replace('%', '')) |