Конвертер валют — это приложение, позволяющее быстро переводить одну валюту в другую по курсу. Такие инструменты массово доступны в интернете, воспользоваться ими можно бесплатно. В этой статье мы разберем, как создать конвертер валют на 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
ОПУБЛИКОВАНО 16.05.2022ТОП
Конвертер валют — это приложение, позволяющее быстро переводить одну валюту в другую по курсу. Такие инструменты массово доступны в интернете, воспользоваться ими можно бесплатно. В этой статье мы разберем, как создать конвертер валют на 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. При написании такой программы один из самых важных моментов — получение актуального курса валют. В этой статье мы рассмотрели пять способов получить курс. Если вам не подходит ни один из них, ничего страшного — вы можете выбрать любой другой!
Если вам необходимо, вы можете получить полный код для рассмотренных примеров здесь.
Надеемся, данная статья была вам полезна! Успехов в написании кода!
https://t.me/pythonl
Просмотры: 2 626
Конвертер валют — это приложение, позволяющее быстро переводить одну валюту в другую по курсу. Такие инструменты массово доступны в интернете, воспользоваться ими можно бесплатно. В этой статье мы разберем, как создать конвертер валют на 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
[python_ad_block]
Следующая функция отвечает за выполнение запроса к странице и извлечение данных из таблиц:
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:00 1000.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:34 1000.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:00 1000.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:04 1000.0 EUR = 1126.494 USD
Если вы хотите узнать больше про Fixer API, то вы можете ознакомиться с документацией.
Заключение
Что ж, вот и всё! Сегодня мы разобрали, как написать конвертер валют на Python. При написании такой программы один из самых важных моментов — получение актуального курса валют. В этой статье мы рассмотрели пять способов получить курс. Если вам не подходит ни один из них, ничего страшного — вы можете выбрать любой другой!
Если вам необходимо, вы можете получить полный код для рассмотренных примеров здесь.
Надеемся, данная статья была вам полезна! Успехов в написании кода!
Перевод статьи «How to Make a Currency Converter in Python».
import
tkinter as tk
from
tkinter
import
*
import
tkinter.messagebox
root
=
tk.Tk()
root.title(
"Currency converter:GeeksForGeeks"
)
Tops
=
Frame(root, bg
=
'#e6e5e5'
, pady
=
2
, width
=
1850
, height
=
100
, relief
=
"ridge"
)
Tops.grid(row
=
0
, column
=
0
)
headlabel
=
tk.Label(Tops, font
=
(
'lato black'
,
19
,
'bold'
), text
=
'Currency converter :GeeksForGeeks '
,
bg
=
'#e6e5e5'
, fg
=
'black'
)
headlabel.grid(row
=
1
, column
=
0
, sticky
=
W)
variable1
=
tk.StringVar(root)
variable2
=
tk.StringVar(root)
variable1.
set
(
"currency"
)
variable2.
set
(
"currency"
)
def
RealTimeCurrencyConversion():
from
forex_python.converter
import
CurrencyRates
c
=
CurrencyRates()
from_currency
=
variable1.get()
to_currency
=
variable2.get()
if
(Amount1_field.get()
=
=
""):
tkinter.messagebox.showinfo(
"Error !!"
,
"Amount Not Entered.n Please a valid amount."
)
elif
(from_currency
=
=
"currency"
or
to_currency
=
=
"currency"
):
tkinter.messagebox.showinfo(
"Error !!"
,
"Currency Not Selected.n Please select FROM and TO Currency form menu."
)
else
:
new_amt
=
c.convert(from_currency, to_currency,
float
(Amount1_field.get()))
new_amount
=
float
(
"{:.4f}"
.
format
(new_amt))
Amount2_field.insert(
0
,
str
(new_amount))
def
clear_all():
Amount1_field.delete(
0
, tk.END)
Amount2_field.delete(
0
, tk.END)
CurrenyCode_list
=
[
"INR"
,
"USD"
,
"CAD"
,
"CNY"
,
"DKK"
,
"EUR"
]
root.configure(background
=
'#e6e5e5'
)
root.geometry(
"700x400"
)
Label_1
=
Label(root, font
=
(
'lato black'
,
27
,
'bold'
), text
=
"
", padx=2, pady=2, bg="
Label_1.grid(row
=
1
, column
=
0
, sticky
=
W)
label1
=
tk.Label(root, font
=
(
'lato black'
,
15
,
'bold'
), text
=
"t Amount : "
, bg
=
"#e6e5e5"
, fg
=
"black"
)
label1.grid(row
=
2
, column
=
0
, sticky
=
W)
label1
=
tk.Label(root, font
=
(
'lato black'
,
15
,
'bold'
), text
=
"t From Currency : "
, bg
=
"#e6e5e5"
, fg
=
"black"
)
label1.grid(row
=
3
, column
=
0
, sticky
=
W)
label1
=
tk.Label(root, font
=
(
'lato black'
,
15
,
'bold'
), text
=
"t To Currency : "
, bg
=
"#e6e5e5"
, fg
=
"black"
)
label1.grid(row
=
4
, column
=
0
, sticky
=
W)
label1
=
tk.Label(root, font
=
(
'lato black'
,
15
,
'bold'
), text
=
"t Converted Amount : "
, bg
=
"#e6e5e5"
, fg
=
"black"
)
label1.grid(row
=
8
, column
=
0
, sticky
=
W)
Label_1
=
Label(root, font
=
(
'lato black'
,
7
,
'bold'
), text
=
"
", padx=2, pady=2, bg="
Label_1.grid(row
=
5
, column
=
0
, sticky
=
W)
Label_1
=
Label(root, font
=
(
'lato black'
,
7
,
'bold'
), text
=
"
", padx=2, pady=2, bg="
Label_1.grid(row
=
7
, column
=
0
, sticky
=
W)
FromCurrency_option
=
tk.OptionMenu(root, variable1,
*
CurrenyCode_list)
ToCurrency_option
=
tk.OptionMenu(root, variable2,
*
CurrenyCode_list)
FromCurrency_option.grid(row
=
3
, column
=
0
, ipadx
=
45
, sticky
=
E)
ToCurrency_option.grid(row
=
4
, column
=
0
, ipadx
=
45
, sticky
=
E)
Amount1_field
=
tk.Entry(root)
Amount1_field.grid(row
=
2
, column
=
0
, ipadx
=
28
, sticky
=
E)
Amount2_field
=
tk.Entry(root)
Amount2_field.grid(row
=
8
, column
=
0
, ipadx
=
31
, sticky
=
E)
Label_9
=
Button(root, font
=
(
'arial'
,
15
,
'bold'
), text
=
" Convert "
, padx
=
2
, pady
=
2
, bg
=
"lightblue"
, fg
=
"white"
,
command
=
RealTimeCurrencyConversion)
Label_9.grid(row
=
6
, column
=
0
)
Label_1
=
Label(root, font
=
(
'lato black'
,
7
,
'bold'
), text
=
"
", padx=2, pady=2, bg="
Label_1.grid(row
=
9
, column
=
0
, sticky
=
W)
Label_9
=
Button(root, font
=
(
'arial'
,
15
,
'bold'
), text
=
" Clear All "
, padx
=
2
, pady
=
2
, bg
=
"lightblue"
, fg
=
"white"
,
command
=
clear_all)
Label_9.grid(row
=
10
, column
=
0
)
root.mainloop()
import
tkinter as tk
from
tkinter
import
*
import
tkinter.messagebox
root
=
tk.Tk()
root.title(
"Currency converter:GeeksForGeeks"
)
Tops
=
Frame(root, bg
=
'#e6e5e5'
, pady
=
2
, width
=
1850
, height
=
100
, relief
=
"ridge"
)
Tops.grid(row
=
0
, column
=
0
)
headlabel
=
tk.Label(Tops, font
=
(
'lato black'
,
19
,
'bold'
), text
=
'Currency converter :GeeksForGeeks '
,
bg
=
'#e6e5e5'
, fg
=
'black'
)
headlabel.grid(row
=
1
, column
=
0
, sticky
=
W)
variable1
=
tk.StringVar(root)
variable2
=
tk.StringVar(root)
variable1.
set
(
"currency"
)
variable2.
set
(
"currency"
)
def
RealTimeCurrencyConversion():
from
forex_python.converter
import
CurrencyRates
c
=
CurrencyRates()
from_currency
=
variable1.get()
to_currency
=
variable2.get()
if
(Amount1_field.get()
=
=
""):
tkinter.messagebox.showinfo(
"Error !!"
,
"Amount Not Entered.n Please a valid amount."
)
elif
(from_currency
=
=
"currency"
or
to_currency
=
=
"currency"
):
tkinter.messagebox.showinfo(
"Error !!"
,
"Currency Not Selected.n Please select FROM and TO Currency form menu."
)
else
:
new_amt
=
c.convert(from_currency, to_currency,
float
(Amount1_field.get()))
new_amount
=
float
(
"{:.4f}"
.
format
(new_amt))
Amount2_field.insert(
0
,
str
(new_amount))
def
clear_all():
Amount1_field.delete(
0
, tk.END)
Amount2_field.delete(
0
, tk.END)
CurrenyCode_list
=
[
"INR"
,
"USD"
,
"CAD"
,
"CNY"
,
"DKK"
,
"EUR"
]
root.configure(background
=
'#e6e5e5'
)
root.geometry(
"700x400"
)
Label_1
=
Label(root, font
=
(
'lato black'
,
27
,
'bold'
), text
=
"
", padx=2, pady=2, bg="
Label_1.grid(row
=
1
, column
=
0
, sticky
=
W)
label1
=
tk.Label(root, font
=
(
'lato black'
,
15
,
'bold'
), text
=
"t Amount : "
, bg
=
"#e6e5e5"
, fg
=
"black"
)
label1.grid(row
=
2
, column
=
0
, sticky
=
W)
label1
=
tk.Label(root, font
=
(
'lato black'
,
15
,
'bold'
), text
=
"t From Currency : "
, bg
=
"#e6e5e5"
, fg
=
"black"
)
label1.grid(row
=
3
, column
=
0
, sticky
=
W)
label1
=
tk.Label(root, font
=
(
'lato black'
,
15
,
'bold'
), text
=
"t To Currency : "
, bg
=
"#e6e5e5"
, fg
=
"black"
)
label1.grid(row
=
4
, column
=
0
, sticky
=
W)
label1
=
tk.Label(root, font
=
(
'lato black'
,
15
,
'bold'
), text
=
"t Converted Amount : "
, bg
=
"#e6e5e5"
, fg
=
"black"
)
label1.grid(row
=
8
, column
=
0
, sticky
=
W)
Label_1
=
Label(root, font
=
(
'lato black'
,
7
,
'bold'
), text
=
"
", padx=2, pady=2, bg="
Label_1.grid(row
=
5
, column
=
0
, sticky
=
W)
Label_1
=
Label(root, font
=
(
'lato black'
,
7
,
'bold'
), text
=
"
", padx=2, pady=2, bg="
Label_1.grid(row
=
7
, column
=
0
, sticky
=
W)
FromCurrency_option
=
tk.OptionMenu(root, variable1,
*
CurrenyCode_list)
ToCurrency_option
=
tk.OptionMenu(root, variable2,
*
CurrenyCode_list)
FromCurrency_option.grid(row
=
3
, column
=
0
, ipadx
=
45
, sticky
=
E)
ToCurrency_option.grid(row
=
4
, column
=
0
, ipadx
=
45
, sticky
=
E)
Amount1_field
=
tk.Entry(root)
Amount1_field.grid(row
=
2
, column
=
0
, ipadx
=
28
, sticky
=
E)
Amount2_field
=
tk.Entry(root)
Amount2_field.grid(row
=
8
, column
=
0
, ipadx
=
31
, sticky
=
E)
Label_9
=
Button(root, font
=
(
'arial'
,
15
,
'bold'
), text
=
" Convert "
, padx
=
2
, pady
=
2
, bg
=
"lightblue"
, fg
=
"white"
,
command
=
RealTimeCurrencyConversion)
Label_9.grid(row
=
6
, column
=
0
)
Label_1
=
Label(root, font
=
(
'lato black'
,
7
,
'bold'
), text
=
"
", padx=2, pady=2, bg="
Label_1.grid(row
=
9
, column
=
0
, sticky
=
W)
Label_9
=
Button(root, font
=
(
'arial'
,
15
,
'bold'
), text
=
" Clear All "
, padx
=
2
, pady
=
2
, bg
=
"lightblue"
, fg
=
"white"
,
command
=
clear_all)
Label_9.grid(row
=
10
, column
=
0
)
root.mainloop()
·
11 min read
· Updated
jul 2022
· Web Scraping
· Application Programming Interfaces
· Finance
Disclosure: This post may contain affiliate links, meaning when you click the links and make a purchase, we receive a commission.
A currency converter is an app or tool that allows you to quickly convert from one currency to another. We can easily find such tools for free on the Internet. This tutorial will make a real-time currency converter using several methods utilizing web scraping techniques and APIs.
This tutorial will cover five different ways to get the most recent foreign exchange rates, some of them parse the rates from public web pages such as X-RATES and Xe, and others use official APIs for more commercial and reliable use, such as Fixer API and ExchangeRate API, feel free to use any one of these.
Feel free to jump into the method you want to use:
- Scraping X-RATES
- Scraping Xe
- Scraping Yahoo Finance
- Using ExchangeRate API
- Using Fixer API
To get started, we have to install the required libraries for all the methods below:
$ pip install python-dateutil requests bs4 yahoo_fin
Scraping X-RATES
In this section, we will extract the data from the x-rates.com website. If you go to the target web page, you’ll see most of the currencies along with the most recent date and time. Let’s scrape the page:
import requests
from bs4 import BeautifulSoup as bs
from dateutil.parser import parse
from pprint import pprint
The following function is responsible for making a request to that page and extracting the data from the tables:
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
The above function takes the currency and the amount as parameters and returns the exchange rates of most currencies along with the date and time of the last update.
The time of the last update is in a span
tag that has the class of ratesTimestamp
. Notice we use the parse()
function from dateutil.parser
module to automatically parse the string into a Python DateTime object.
The exchange rates are located in two tables. We extract them using the find_all()
method from the BeautifulSoup object and get the currency name and the exchange rate in each row in the tables, and add them to our exchange_rates
dictionary that we will return. Let’s use this function:
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)
Excellent, we use the built-in sys
module to get the target currency and the amount from the command line. Let’s run this:
$ python currency_converter_xrates.py EUR 1000
The above run is trying to convert 1000 Euros to all other currencies. Here is the output:
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}
That’s about 1127.07 in USD at the time of writing this tutorial. Notice the last updated date and time; it usually updates every minute.
Scraping Xe
Xe is an online foreign exchange tools and services company. It is best known for its online currency converter. In this section, we use requests and BeautifulSoup libraries to make a currency converter based on it.
Open up a new Python file and import the necessary libraries:
import requests
from bs4 import BeautifulSoup as bs
import re
from dateutil.parser import parse
Now let’s make a function that accepts the source currency, target currency, and the amount we want to convert, and then returns the converted amount along with the exchange rate date and time:
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)
At the time of writing this tutorial, the exchange rate is located in the third paragraph on the HTML page. This explains the soup.find_all("p")[2]
. Make sure to change the extraction whenever a change is made to the HTML page. Hopefully, I’ll keep an eye out whenever a change is made.
The latest date and time of the exchange rate is located at the second parent of the exchange rate paragraph in the HTML DOM.
Since the exchange rate contains string characters, I made the get_digits(
) function to extract only the digits and dots from a given string, which is helpful in our case.
Let’s use the function now:
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}")
This time, we get the source and target currencies as well as the amount from the command-lines, trying to convert 1000 EUR to USD:
$ python currency_converter_xe.py EUR USD 1000
Output:
Last updated datetime: 2022-02-01 13:04:00+00:00
1000.0 EUR = 1125.8987 USD
That’s great! Xe usually updates every minute too, so it’s real-time!
Scraping Yahoo Finance
Yahoo Finance provides financial news, currency data, stock quotes, press releases, and financial reports. This section uses the yahoo_fin
library in Python to make a currency exchanger based on Yahoo Finance data.
Importing the libraries:
import yahoo_fin.stock_info as si
from datetime import datetime, timedelta
yahoo_fin
does an excellent job of extracting the data from the Yahoo Finance web page, and it is still maintained now; we use the get_data()
method from the stock_info
module and pass the currency symbol to it.
Below is the function that uses this function and returns the converted amount from one currency to another:
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
We pass "1m"
to the interval
parameter in the get_data()
method to extract minute data instead of daily data (default). We also get minute data of the previous two days, as it may cause issues on the weekends, just to be cautious.
The significant advantage of this method is you can get historical data by simply changing start_date
and end_date
parameters on this method. You can also change the interval
to be "1d"
for daily, "1wk"
for weekly, and "1mo"
for monthly.
Let’s use the function now:
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}")
Running the code:
$ python currency_converter_yahoofin.py EUR USD 1000
Output:
Last updated datetime: 2022-02-01 13:26:34
1000.0 EUR = 1126.1261701583862 USD
Using ExchangeRate API
As mentioned at the beginning of this tutorial, if you want a more reliable way to make a currency converter, you have to choose an API for that. There are several APIs for this purpose. However, we have picked two APIs that seem convenient and easy to get started.
ExchangeRate API supports 161 currencies and offers a free monthly 1,500 requests if you want to try it out, and there is an open API as well that offers daily updated data, and that’s what we are going to use:
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
The above function requests the open API and returns the exchange rates for all the currencies with the latest date and time. Let’s use this function to make a currency converter function:
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
As usual, let’s make the main code:
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}")
Running it:
$ python currency_converter_erapi.py EUR USD 1000
Output:
Last updated datetime: 2022-02-01 00:02:31+00:00
1000.0 EUR = 1120.0 USD
The rates update daily, and it does not offer the exact exchange number as it’s an open API; you can freely sign up for an API key to get precise exchange rates.
Using Fixer API
One of the promising alternatives is Fixer API. It is a simple and lightweight API for real-time and historical foreign exchange rates. You can easily create an account and get the API key.
After you’ve done that, you can use the /convert
endpoint to convert from one currency to another. However, that’s not included in the free plan and requires upgrading your account.
There is the /latest
endpoint that does not require an upgrade and works in a free account just fine. It returns the exchange rates for the currency of your region. We can pass the source and target currencies we want to convert and calculate the exchange rate between both. Here’s the function:
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
Below is the function that uses the /convert
endpoint in case you have an upgraded account:
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
Let’s use either function:
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}")
Before running the script, make sure to replace API_KEY
with the API key you get when registering for an account.
Running the script:
Last updated datetime: 2022-02-01 15:54:04
1000.0 EUR = 1126.494 USD
You can check the documentation of Fixer API here.
Conclusion
There are many ways to make a currency converter, and we have covered five of them. If one method does not work for you, you can choose another one!
Finally, if you’re a beginner and want to learn Python, I suggest you take the Python For Everybody Coursera course, in which you’ll learn a lot about Python. You can also check our resources and courses page to see the Python resources I recommend on various topics!
You can get the complete code for all the files here.
Learn also: Webhooks in Python with Flask.
Happy coding ♥
View Full Code
Read Also
Comment panel
Have you ever tried to offer a product, a service, or simply wanted to display prices in different currencies? Then you know how hard it can be to provide up-to-date and accurate exchange rates.
This is where currency exchange APIs come in. An exchange API helps you handle your forex rate conversions. In this example, we will look at how to integrate a currency API into a simple Python application using the Flask web framework and a bit of Javascript for the front-end styling so you can build your own currency converter.
Step-by-step guide on how to create a currency converter in Python
First, we will set up our development stack:
- Python 3 (> 3.7)
- Flask
- Javascript (Node)
- Yarn (npm install –global yarn)
- Vite
- Tailwind CSS
- postcss
- autoprefixer
- free currencyapi.com API key
Step 1: Initializing our front-end project
To get started, we need to initialize a Vite project in our development workspace:
yarn create vite currency-converter --template vanilla
Step 2: Styling setup (optional)
Styling is optional, but if you choose to follow this step, we recommend using Tailwind CSS. Autoprefixer & postcss further enable a smooth development experience. Therefore, we need to install these packages:
yarn add -D tailwindcss postcss autoprefixer
Now we can initialize tailwind. This creates a config file (tailwind.config.js):
We now need to adapt this newly created config to work with our Vite project setup:
module.exports = { content: [ './main.js', './index.html', ], theme: { extend: {}, }, plugins: [], }
To include Tailwind CSS, add the following lines at the top of your style.css:
@tailwind base; @tailwind components; @tailwind utilities;
Next, we need to create a config file named postcss.config.js in our root directory for postcss. We, therefore, add:
module.exports = { plugins: [ require('tailwindcss'), require('autoprefixer') ] }
Step 3: Starting vite
We can now start vite in dev mode to serve our files with hot reloading:
Step 4: Preparing our HTML
Next, we want to adapt the default landing page. To do so, we open the index.html and build a form. We will need the following elements:
- A wrapper for our input <form id=”currency_converter”>t
- An input for our base currency: <input id=”base_currency_input”>
- A base currency selection <select id=”currency”>
- A submit button <button type=”submit”>
- A response container <div id=”result”>
Here is what our implementation of the index.html looks like:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <link rel="icon" type="image/svg+xml" href="favicon.svg" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Currency converter example</title> </head> <body class="bg-gradient-to-b from-cyan-800 to-slate-800 min-h-screen py-5"> <form id="currency_converter" class="mx-auto w-full max-w-sm bg-white shadow rounded-md p-5 space-y-3 text-sm"> <div class="flex items-center space-x-5"> <label for="base_currency_input">Amount:</label> <input type="tel" id="base_currency_input" name="base_currency_input" placeholder="1" value="" class="grow border-slate-300 border rounded-md py-2 px-4 text-sm" required /> </div> <div class="flex items-center space-x-5"> <label for="currency">Currency:</label> <select name="currency" id="currency" class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"> <option selected value="USD">USD</option> <option value="EUR">EUR</option> <option value="CHF">CHF</option> </select> </div> <button type="submit" class="bg-slate-800 text-white rounded-md py-2 px-4 mx-auto relative block w-full">Convert </button> </form> <div id="result" class="mx-auto my-5 w-full max-w-sm bg-white shadow rounded-md relative overflow-hidden text-sm empty:hidden divide-y divide-dotted divide-slate-300"> </div> <script type="module" src="/main.js"></script> </body> </html>
Step 5: Handling the form submission in JavaScript
In our main.js, we send the currency amount (`base_currency_input`) and the currency (`base_currency`) to our backend. We will receive a list of all currencies and the corresponding values in the response.
import './style.css' const currencyConverter = document.getElementById('currency_converter'); const baseCurrencyInput = document.getElementById('base_currency_input'); const baseCurrency = document.getElementById('currency'); const resultContainer = document.getElementById('result'); currencyConverter.addEventListener('submit', (e) => { e.preventDefault(); fetch(`http://localhost:6001/convert?` + new URLSearchParams({ 'base_currency_input': baseCurrencyInput.value, 'currency': baseCurrency.value })) .then(response => response.json()) .then(data => { var result = '<div class="space-y-1 px-5 py-3 border-2 rounded-md">'; for (let entry of data) { result += `<div class="flex items-baseline justify-between"><span class="font-medium">${entry.code}:</span><span>${entry.value}</span></div>`; } resultContainer.innerHTML = result; }); });
Step 6: Preparing the backend application
Now, we create a new folder, ie: `backend-application` inside the `currency-converter` folder:
Note: The commands are valid for macOS/Linux; for Windows, please check here.
mkdir backend-application cd backend-application python3 –m venv venv . venv/bin/activate pip install Flask currencyapicom
Step 7: Creating the backend app
In the last step, we simply add a new file called `main.py`:
from flask import Flask, request, jsonify from currencyapicom import Client from config import CURRENCYAPI_KEY app = Flask(__name__) @app.route("/convert", methods=['GET']) def convert(): currency_input = request.args.get('base_currency_input', '') currency = request.args.get('currency', 'USD') if currency_input and currency in ['USD', 'EUR', 'CHF']: api_client = Client(CURRENCYAPI_KEY) response = api_client.latest(currency) response = jsonify([{'value': response['data'][x]['value'] * float(currency_input), 'code': x} for x in response['data'].keys()]) response.headers.add("Access-Control-Allow-Origin", "*") return response
We can run the application with a few simple commands (we bind the port to 6001 to avoid conflict with other apps):
export FLASK_APP=main flask run –port 6001
In the last step, we need to create a `config.py` file, including the currencyapi.com API key. You can get it free and learn more about the API in the documentation.
And that’s it!
Up-to-date and accurate
With these few steps, you can now build your own currency converter using Python and display accurate and up-to-date prices in different currencies. There are many use cases for a currency converter; whether you use it for e-commerce stores, analytics, or spreadsheets, we hope this tutorial will guide you through the process.
from
tkinter
import
*
root
=
Tk()
variable1
=
StringVar(root)
variable2
=
StringVar(root)
variable1.
set
(
"currency"
)
variable2.
set
(
"currency"
)
def
RealTimeCurrencyConversion():
import
requests, json
from_currency
=
variable1.get()
to_currency
=
variable2.get()
api_key
=
"Your_Api_Key"
main_url
=
base_url
+
"&from_currency ="
+
from_currency
+
"&to_currency ="
+
to_currency
+
"&apikey ="
+
api_key
req_ob
=
requests.get(main_url)
result
=
req_ob.json()
Exchange_Rate
=
float
(result[
"Realtime Currency Exchange Rate"
]
[
'5. Exchange Rate'
])
amount
=
float
(Amount1_field.get())
new_amount
=
round
(amount
*
Exchange_Rate,
3
)
Amount2_field.insert(
0
,
str
(new_amount))
def
clear_all():
Amount1_field.delete(
0
, END)
Amount2_field.delete(
0
, END)
if
__name__
=
=
"__main__"
:
root.configure(background
=
'light green'
)
root.geometry(
"400x175"
)
headlabel
=
Label(root, text
=
'welcome to Real Time Currency Convertor'
,
fg
=
'black'
, bg
=
"red"
)
label1
=
Label(root, text
=
"Amount :"
,
fg
=
'black'
, bg
=
'dark green'
)
label2
=
Label(root, text
=
"From Currency"
,
fg
=
'black'
, bg
=
'dark green'
)
label3
=
Label(root, text
=
"To Currency :"
,
fg
=
'black'
, bg
=
'dark green'
)
label4
=
Label(root, text
=
"Converted Amount :"
,
fg
=
'black'
, bg
=
'dark green'
)
headlabel.grid(row
=
0
, column
=
1
)
label1.grid(row
=
1
, column
=
0
)
label2.grid(row
=
2
, column
=
0
)
label3.grid(row
=
3
, column
=
0
)
label4.grid(row
=
5
, column
=
0
)
Amount1_field
=
Entry(root)
Amount2_field
=
Entry(root)
Amount1_field.grid(row
=
1
, column
=
1
, ipadx
=
"25"
)
Amount2_field.grid(row
=
5
, column
=
1
, ipadx
=
"25"
)
CurrenyCode_list
=
[
"INR"
,
"USD"
,
"CAD"
,
"CNY"
,
"DKK"
,
"EUR"
]
FromCurrency_option
=
OptionMenu(root, variable1,
*
CurrenyCode_list)
ToCurrency_option
=
OptionMenu(root, variable2,
*
CurrenyCode_list)
FromCurrency_option.grid(row
=
2
, column
=
1
, ipadx
=
10
)
ToCurrency_option.grid(row
=
3
, column
=
1
, ipadx
=
10
)
button1
=
Button(root, text
=
"Convert"
, bg
=
"red"
, fg
=
"black"
,
command
=
RealTimeCurrencyConversion)
button1.grid(row
=
4
, column
=
1
)
button2
=
Button(root, text
=
"Clear"
, bg
=
"red"
,
fg
=
"black"
, command
=
clear_all)
button2.grid(row
=
6
, column
=
1
)
root.mainloop()