Пишем конвертер валют на Python
Конвертер валют — это приложение, позволяющее быстро переводить одну валюту в другую по курсу. Такие инструменты массово доступны в интернете, воспользоваться ими можно бесплатно. В этой статье мы разберем, как создать конвертер валют на Python.Мы рассмотрим различные способы получения актуального курса обмена валют. Некоторые из них связаны с парсингом общедоступных веб-страниц, другие — с использованием официальных API (эти данные более надежны и пригодны для коммерческого использования).
Всего мы рассмотрим пять способов получения курса:
- Парсинг X-RATES
- Использование сервиса Xe
- Парсинг платформы Yahoo Finance
- Использование ExchangeRate API
- Использование Fixer API
Вы можете изучить все пять способов и выбрать тот, который вам понравится больше всего.
Для начала не забудьте установить необходимые библиотеки для всех методов, которые мы будем использовать. Запустите следующую команду:
$ pip install python-dateutil requests bs4 yahoo_fin
Итак, теперь мы начинаем приступать!
Парсинг X-RATES
В этом разделе мы будем извлекать данные с сайта x-rates.com. Если вы перейдете на целевую веб-страницу, вы увидите большинство валют мира с курсом, определенным на текущий момент.
Давайте сначала очистим страницу. Сделать это можно следующим образом:
import requests
from bs4 import BeautifulSoup as bs
from dateutil.parser import parse
from pprint import pprint
Следующая функция отвечает за выполнение запроса к странице и извлечение данных из таблиц:
def get_exchange_list_xrates(currency, amount=1):
# make the request to x-rates.com to get current exchange rates for common currencies
content = requests.get(f"https://www.x-rates.com/table/?from={currency}&amount={amount}").content
# initialize beautifulsoup
soup = bs(content, "html.parser")
# get the last updated time
price_datetime = parse(soup.find_all("span", attrs={"class": "ratesTimestamp"})[1].text)
# get the exchange rates tables
exchange_tables = soup.find_all("table")
exchange_rates = {}
for exchange_table in exchange_tables:
for tr in exchange_table.find_all("tr"):
# for each row in the table
tds = tr.find_all("td")
if tds:
currency = tds[0].text
# get the exchange rate
exchange_rate = float(tds[1].text)
exchange_rates[currency] = exchange_rate
return price_datetime, exchange_rates
Как создать конвертер валют на Python
ОПУБЛИКОВАНО ТОП
Конвертер валют — это приложение, позволяющее быстро переводить одну валюту в другую по курсу. Такие инструменты массово доступны в интернете, воспользоваться ими можно бесплатно. В этой статье мы разберем, как создать конвертер валют на Python.
Мы рассмотрим различные способы получения актуального курса обмена валют. Некоторые из них связаны с парсингом общедоступных веб-страниц, другие — с использованием официальных API (эти данные более надежны и пригодны для коммерческого использования).
Всего мы рассмотрим пять способов получения курса:
- Парсинг X-RATES
- Использование сервиса Xe
- Парсинг платформы Yahoo Finance
- Использование ExchangeRate API
- Использование Fixer API
Вы можете изучить все пять способов и выбрать тот, который вам понравится больше всего.
Для начала не забудьте установить необходимые библиотеки для всех методов, которые мы будем использовать. Запустите следующую команду:
$ pip install python-dateutil requests bs4 yahoo_fin
Итак, теперь мы готовы, давайте приступать!
Парсинг X-RATES
В этом разделе мы будем извлекать данные с сайта x-rates.com. Если вы перейдете на целевую веб-страницу, вы увидите большинство валют мира с курсом, определенным на текущий момент.
Давайте сначала очистим страницу. Сделать это можно следующим образом:import requestsfrom bs4 import BeautifulSoup as bsfrom dateutil.parser import parsefrom pprint import pprint
Следующая функция отвечает за выполнение запроса к странице и извлечение данных из таблиц:
def get_exchange_list_xrates(currency, amount=1):
# make the request to x-rates.com to get current exchange rates for common currencies
content = requests.get(f"https://www.x-rates.com/table/?from={currency}&amount={amount}").content
# initialize beautifulsoup
soup = bs(content, "html.parser")
# get the last updated time
price_datetime = parse(soup.find_all("span", attrs={"class": "ratesTimestamp"})[1].text)
# get the exchange rates tables
exchange_tables = soup.find_all("table")
exchange_rates = {}
for exchange_table in exchange_tables:
for tr in exchange_table.find_all("tr"):
# for each row in the table
tds = tr.find_all("td")
if tds:
currency = tds[0].text
# get the exchange rate
exchange_rate = float(tds[1].text)
exchange_rates[currency] = exchange_rate
return price_datetime, exchange_rates
Эта функция принимает исходную валюту и необходимую сумму в качестве параметров и возвращает соответствующие суммы в разных валютах мира вместе с датой и временем последнего обновления.
Время последнего обновления находится в теге span
с классом rateTimestamp
. Обратите внимание, что мы используем функцию parse()
из модуля dateutil.parser
для автоматического парсинга строки в объект Python DateTime
.
Курсы валют размещены в двух таблицах. Мы извлекаем их с помощью метода find_all()
из модуля BeautifulSoup
, получаем название валюты и сумму по курсу в каждой строке таблиц и добавляем их в наш словарь exchange_rates
, который выведем в конце.
Что ж, давайте воспользуемся этой функцией:
if __name__ == "__main__":
import sys
source_currency = sys.argv[1]
amount = float(sys.argv[3])
target_currency = "GBP"
price_datetime, exchange_rates = get_exchange_list_xrates(source_currency, amount)
print("Last updated:", price_datetime)
pprint(exchange_rates)
Мы используем встроенный модуль sys
, чтобы получать целевую валюту и сумму из командной строки. Давайте запустим следующую команду и попробуем перевести 1000 евро во все другие валюты:
$ python currency_converter_xrates.py EUR 1000
Результат будет таким:
Last updated: 2022-02-01 12:13:00+00:00
{'Argentine Peso': 118362.205708,
'Australian Dollar': 1586.232315,
'Bahraini Dinar': 423.780164,
'Botswana Pula': 13168.450636,
'Brazilian Real': 5954.781483,
'British Pound': 834.954104,
'Bruneian Dollar': 1520.451015,
'Bulgarian Lev': 1955.83,
'Canadian Dollar': 1430.54405,
'Chilean Peso': 898463.818465,
'Chinese Yuan Renminbi': 7171.445692,
'Colombian Peso': 4447741.922165,
'Croatian Kuna': 7527.744707,
'Czech Koruna': 24313.797041,
'Danish Krone': 7440.613895,
'Emirati Dirham': 4139.182587,
'Hong Kong Dollar': 8786.255952,
'Hungarian Forint': 355958.035747,
'Icelandic Krona': 143603.932438,
'Indian Rupee': 84241.767127,
'Indonesian Rupiah': 16187150.010697,
'Iranian Rial': 47534006.535121,
'Israeli Shekel': 3569.191411,
'Japanese Yen': 129149.364679,
'Kazakhstani Tenge': 489292.515538,
'Kuwaiti Dinar': 340.959682,
'Libyan Dinar': 5196.539901,
'Malaysian Ringgit': 4717.485104,
'Mauritian Rupee': 49212.933037,
'Mexican Peso': 23130.471272,
'Nepalese Rupee': 134850.008728,
'New Zealand Dollar': 1703.649473,
'Norwegian Krone': 9953.078431,
'Omani Rial': 433.360301,
'Pakistani Rupee': 198900.635421,
'Philippine Peso': 57574.278782,
'Polish Zloty': 4579.273862,
'Qatari Riyal': 4102.552652,
'Romanian New Leu': 4946.638369,
'Russian Ruble': 86197.012666,
'Saudi Arabian Riyal': 4226.530892,
'Singapore Dollar': 1520.451015,
'South African Rand': 17159.831129,
'South Korean Won': 1355490.097163,
'Sri Lankan Rupee': 228245.645722,
'Swedish Krona': 10439.125427,
'Swiss Franc': 1037.792217,
'Taiwan New Dollar': 31334.286611,
'Thai Baht': 37436.518169,
'Trinidadian Dollar': 7636.35428,
'Turkish Lira': 15078.75981,
'US Dollar': 1127.074905,
'Venezuelan Bolivar': 511082584.868731}
На момент написания данного руководства это около 1127,07 долларов США. Обратите внимание на дату и время последнего обновления. Обычно курс обновляется каждую минуту.
Использование сервиса Xe
А теперь давайте рассмотрим альтернативный вариант.
Xe — это компания, предоставляющая инструменты и услуги по обмену иностранной валюты онлайн. Наиболее известна Xe своим онлайн-конвертером валют. В этом разделе мы воспользуемся такими библиотеками, как requests
и BeautifulSoup
, чтобы сделать на их основе собственный конвертер валют.
Приступим!
Откройте новый файл Python и импортируйте все необходимые библиотеки:
import requests
from bs4 import BeautifulSoup as bs
import re
from dateutil.parser import parse
Теперь давайте создадим функцию, которая принимает исходную валюту, целевую валюту и сумму, которую мы хотим конвертировать, а затем возвращает конвертированную сумму вместе с датой и временем обменного курса.
Выглядеть это будет следующим образом:
def convert_currency_xe(src, dst, amount):
def get_digits(text):
"""Returns the digits and dots only from an input `text` as a float
Args:
text (str): Target text to parse
"""
new_text = ""
for c in text:
if c.isdigit() or c == ".":
new_text += c
return float(new_text)
url = f"https://www.xe.com/currencyconverter/convert/?Amount={amount}&From={src}&To={dst}"
content = requests.get(url).content
soup = bs(content, "html.parser")
exchange_rate_html = soup.find_all("p")[2]
# get the last updated datetime
last_updated_datetime = parse(re.search(r"Last updated (.+)", exchange_rate_html.parent.parent.find_all("div")[-2].text).group()[12:])
return last_updated_datetime, get_digits(exchange_rate_html.text)
На момент написания данного руководства обменный курс находился в третьем абзаце HTML-страницы. Это объясняет строчку soup.find_all("p")[2]
. Не забывайте вносить правки, когда в HTML-страницу вносятся изменения.
В HTML DOM последняя дата и время обменного курса находятся во втором родителе абзаца exchange rate.
Поскольку обменный курс содержит строковые символы, мы создали функцию get_digits()
для извлечения из заданной строки только цифр и точек.
Что ж, давайте воспользуемся нашей функцией:
if __name__ == "__main__":
import sys
source_currency = sys.argv[1]
destination_currency = sys.argv[2]
amount = float(sys.argv[3])
last_updated_datetime, exchange_rate = convert_currency_xe(source_currency, destination_currency, amount)
print("Last updated datetime:", last_updated_datetime)
print(f"{amount} {source_currency} = {exchange_rate} {destination_currency}")
На этот раз нам нужно передать исходную и целевую валюты, а также сумму из командной строки. Мы также попытаемся конвертировать 1000 евро в доллары США с помощью команды в консоли:
$ python currency_converter_xe.py EUR USD 1000
Мы получим следующий результат:Last updated datetime: 2022-02-01 13:04:00+00:001000.0 EUR = 1125.8987 USD
Замечательно! Xe обычно обновляется каждую минуту, так что мы получаем результат в режиме реального времени!
Парсинг платформы Yahoo Finance
Ещё один источник, который мы сегодня рассмотрим, это Yahoo Finance. Он предоставляет финансовые новости, валютные данные, котировки акций, пресс-релизы и различные финансовые отчеты. В этом разделе нашей статьи для создания конвертера валют на основе данных Yahoo Finance мы мы используем библиотеку yahoo_fin .
Для начала давайте выполним импорт библиотек, которые нам понадобятся:
import yahoo_fin.stock_info as si
from datetime import datetime, timedelta
yahoo_fin
отлично справляется с извлечением данных с веб-страницы Yahoo Finance. Мы используем метод get_data()
из модуля stock_info
и передаем ему символ исходной валюты.
Ниже приведена функция, которая использует данную функцию и возвращает сумму, переведенную из одной валюты в другую:
def convert_currency_yahoofin(src, dst, amount):
# construct the currency pair symbol
symbol = f"{src}{dst}=X"
# extract minute data of the recent 2 days
latest_data = si.get_data(symbol, interval="1m", start_date=datetime.now() - timedelta(days=2))
# get the latest datetime
last_updated_datetime = latest_data.index[-1].to_pydatetime()
# get the latest price
latest_price = latest_data.iloc[-1].close
# return the latest datetime with the converted amount
return last_updated_datetime, latest_price * amount
Мы передаем “1m”
в качестве параметра interval
в методе get_data()
для извлечения данных на текущую минуту, а не текущий день (значение по умолчанию). Мы также извлекаем поминутные данные за предыдущие два дня, просто чтобы перестраховаться (с данными курса в выходные могут быть проблемы).
Существенным преимуществом этого метода является то, что вы можете получить исторические данные, просто изменив параметры start_date
и end_date
в данном методе. Более того, вы также можете изменить интервал: "1d"
для ежедневного обновления, "1wk"
для еженедельного и "1mo"
для обновления курса один раз в месяц.
Теперь воспользуемся функцией, которая у нас получилась:
if __name__ == "__main__":
import sys
source_currency = sys.argv[1]
destination_currency = sys.argv[2]
amount = float(sys.argv[3])
last_updated_datetime, exchange_rate = convert_currency_yahoofin(source_currency, destination_currency, amount)
print("Last updated datetime:", last_updated_datetime)
print(f"{amount} {source_currency} = {exchange_rate} {destination_currency}")
Запустим код из консоли следующей командой:
$ python currency_converter_yahoofin.py EUR USD 1000
Мы опять переводим 1000 евро в доллары США. И вот какой результат у нас получился:Last updated datetime: 2022-02-01 13:26:341000.0 EUR = 1126.1261701583862 USD
Использование API ExchangeRate
Как упоминалось в самом начале данного руководства, если вы хотите создать более надежный конвертер валют, делать это лучше на базе API. Для данной цели существует несколько различных API. Мы выбрали два наиболее удобных и простых в использовании. Их мы и рассмотрим далее.
Начнем с ExchangeRate API. Он поддерживает 161 валюту и предлагает 1500 бесплатных запросов в месяц. Кроме того, также есть открытый API, который предлагает ежедневно обновляемые данные. Его-то мы и используем:
import requests
from dateutil.parser import parse
def get_all_exchange_rates_erapi(src):
url = f"https://open.er-api.com/v6/latest/{src}"
# request the open ExchangeRate API and convert to Python dict using .json()
data = requests.get(url).json()
if data["result"] == "success":
# request successful
# get the last updated datetime
last_updated_datetime = parse(data["time_last_update_utc"])
# get the exchange rates
exchange_rates = data["rates"]
return last_updated_datetime, exchange_rates
Приведенная выше функция запрашивает открытый API и возвращает обменные курсы для всех валют с последней датой и временем.
Давайте используем эту функцию, чтобы написать свой конвертер валют:
def convert_currency_erapi(src, dst, amount):
# get all the exchange rates
last_updated_datetime, exchange_rates = get_all_exchange_rates_erapi(src)
# convert by simply getting the target currency exchange rate and multiply by the amount
return last_updated_datetime, exchange_rates[dst] * amount
Далее как обычно, напишем основной код:
if __name__ == "__main__":
import sys
source_currency = sys.argv[1]
destination_currency = sys.argv[2]
amount = float(sys.argv[3])
last_updated_datetime, exchange_rate = convert_currency_erapi(source_currency, destination_currency, amount)
print("Last updated datetime:", last_updated_datetime)
print(f"{amount} {source_currency} = {exchange_rate} {destination_currency}")
И запустим из консоли нашу программу с помощью следующей команды:
$ python currency_converter_erapi.py EUR USD 1000
На выходе мы получим вот такой результат:Last updated datetime: 2022-02-01 00:02:31+00:001000.0 EUR = 1120.0 USD
Курсы обновляются ежедневно. Стоит отметить, что открытый API не предлагает точный курс обмена. Но вы можете бесплатно зарегистрироваться и получить ключ API, чтобы извлекать точные обменные курсы.
Использование Fixer API
И последний способ получения курса валют — при помощи Fixer API. Это простой и легковесный API для конвертирования валют как в режиме реального времени, так и по состоянию на прошлые периоды.
Вы можете без проблем создать учетную запись и получить ключ API. После этого вы сможете использовать конечную точку /convert
для конвертации сумм из одной валюты в другую. Однако, к сожалению, это не входит в бесплатный план и требует апгрейда вашей учетной записи.
Но ещё есть конечная точка /latest
, которая отлично работает при бесплатном аккаунте. Она возвращает текущие курсы обмена для валюты вашего региона. В неё мы можем передать исходную и целевую валюты для конвертации и рассчитать обменный курс между ними. Данная функция может быть представлена следующим образом:
import requests
from datetime import datetime
API_KEY = "<YOUR_API_KEY_HERE>"
def convert_currency_fixerapi_free(src, dst, amount):
"""converts `amount` from the `src` currency to `dst` using the free account"""
url = f"http://data.fixer.io/api/latest?access_key={API_KEY}&symbols={src},{dst}&format=1"
data = requests.get(url).json()
if data["success"]:
# request successful
rates = data["rates"]
# since we have the rate for our currency to src and dst, we can get exchange rate between both
# using below calculation
exchange_rate = 1 / rates[src] * rates[dst]
last_updated_datetime = datetime.fromtimestamp(data["timestamp"])
return last_updated_datetime, exchange_rate * amount
Ниже приведена функция, которая использует конечную точку /convert
(подходит для платного аккаунта):
def convert_currency_fixerapi(src, dst, amount):
"""converts `amount` from the `src` currency to `dst`, requires upgraded account"""
url = f"https://data.fixer.io/api/convert?access_key={API_KEY}&from={src}&to={dst}&amount={amount}"
data = requests.get(url).json()
if data["success"]:
# request successful
# get the latest datetime
last_updated_datetime = datetime.fromtimestamp(data["info"]["timestamp"])
# get the result based on the latest price
result = data["result"]
return last_updated_datetime, result
Воспользуйтесь той из двух функций, которая вам больше подходит:
if __name__ == "__main__":
import sys
source_currency = sys.argv[1]
destination_currency = sys.argv[2]
amount = float(sys.argv[3])
# free account
last_updated_datetime, exchange_rate = convert_currency_fixerapi_free(source_currency, destination_currency, amount)
# upgraded account, uncomment if you have one
# last_updated_datetime, exchange_rate = convert_currency_fixerapi(source_currency, destination_currency, amount)
print("Last updated datetime:", last_updated_datetime)
print(f"{amount} {source_currency} = {exchange_rate} {destination_currency}")
Перед запуском скрипта обязательно замените API_KEY
на ключ API, который вы получаете при регистрации учетной записи.
Запустим наш скрипт и получим следующий результат:
Last updated datetime: 2022-02-01 15:54:041000.0 EUR = 1126.494 USD
сли вы хотите узнать больше про Fixer API, то вы можете ознакомиться с документацией.
Заключение
Что ж, вот и всё! Сегодня мы разобрали, как написать конвертер валют на Python. При написании такой программы один из самых важных моментов — получение актуального курса валют. В этой статье мы рассмотрели пять способов получить курс. Если вам не подходит ни один из них, ничего страшного — вы можете выбрать любой другой!
Если вам необходимо, вы можете получить полный код для рассмотренных примеров здесь.
Надеемся, данная статья была вам полезна! Успехов в написании кода!