Конвертер валют — это приложение, позволяющее быстро переводить одну валюту в другую по курсу. Такие инструменты массово доступны в интернете, воспользоваться ими можно бесплатно. В этой статье мы разберем, как создать конвертер валют на 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».