Как написать конвертер валют на python

Конвертер валют — это приложение, позволяющее быстро переводить одну валюту в другую по курсу. Такие инструменты массово доступны в интернете, воспользоваться ими можно бесплатно. В этой статье мы разберем, как создать конвертер валют на Python.Мы рассмотрим различные способы получения актуального курса обмена валют. Некоторые из них связаны с парсингом общедоступных веб-страниц, другие — с использованием официальных API (эти данные более надежны и пригодны для коммерческого использования).

Всего мы рассмотрим пять способов получения курса:

  1. Парсинг X-RATES
  2. Использование сервиса Xe
  3. Парсинг платформы Yahoo Finance
  4. Использование ExchangeRate API
  5. Использование 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 (эти данные более надежны и пригодны для коммерческого использования).

Всего мы рассмотрим пять способов получения курса:

  1. Парсинг X-RATES
  2. Использование сервиса Xe
  3. Парсинг платформы Yahoo Finance
  4. Использование ExchangeRate API
  5. Использование Fixer API

Вы можете изучить все пять способов и выбрать тот, который вам понравится больше всего.

Для начала не забудьте установить необходимые библиотеки для всех методов, которые мы будем использовать. Запустите следующую команду:

$ pip install python-dateutil requests bs4 yahoo_fin

Итак, теперь мы готовы, давайте приступать!

Как написать программу для обмена валют в Python

Парсинг X-RATES

В этом разделе мы будем извлекать данные с сайта x-rates.com. Если вы перейдете на целевую веб-страницу, вы увидите большинство валют мира с курсом, определенным на текущий момент.

Давайте сначала очистим страницу. Сделать это можно следующим образом:import requestsfrom bs4 import BeautifulSoup as bsfrom dateutil.parser import parsefrom pprint import pprint

python logo

Следующая функция отвечает за выполнение запроса к странице и извлечение данных из таблиц:

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 (эти данные более надежны и пригодны для коммерческого использования).

Всего мы рассмотрим пять способов получения курса:

  1. Парсинг X-RATES
  2. Использование сервиса Xe
  3. Парсинг платформы Yahoo Finance
  4. Использование ExchangeRate API
  5. Использование Fixer API

Вы можете изучить все пять способов и выбрать тот, который вам понравится больше всего.

Для начала не забудьте установить необходимые библиотеки для всех методов, которые мы будем использовать. Запустите следующую команду:

$ pip install python-dateutil requests bs4 yahoo_fin

Итак, теперь мы готовы, давайте приступать!

Как написать программу для обмена валют в Python

Парсинг 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

How to Predict Stock Prices in Python using TensorFlow 2 and Keras

How to Extract YouTube Data using YouTube API in Python

How to Extract Google Trends Data in Python

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() 

Понравилась статья? Поделить с друзьями:
  • Как написать кому то на почту
  • Как написать кому софье или софии
  • Как написать кому подарок
  • Как написать компот на английском
  • Как написать композицию стихотворения