16 декабря 2014 г.

Python 3: Извлекаем данные о ежедневных курсах валют с сайта ЦБ РФ

В этой статье хочу рассмотреть пример скрипта на языке программирования Python3, который извлекает данные о текущем курсе валют с официального сайта Центрального Банка РФ и сохраняет их в отдельном файле, который в дальнейшем можно открыть с помощью LibreOffice Calc и применить к ним всю его мощь.

Пример больше интересен тем, что в нём используется парсинг XML-файла.

Сам скрипт находится здесь. Условно, скрипт решает три задачи:

  1. Скачивает XML-файл с курсами валют с сайта ЦБ РФ;
  2. Анализирует (парсит) XML-файл и извлекает оттуда информацию о курсах валют в нужной нам форме;
  3. Сохраняет полученную информацию в текстовом файле в виде значений, разделённых запятыми (CSV).

1-й этап

Сайт Центрального Банка РФ позволяет получать данные в виде XML-файлов. Подобнее об этом здесь.

В нашем примере мы получаем данные о ежедневных курсах валют, которые находятся по адресу http://www.cbr.ru/scripts/XML_daily.asp.

Для скачивания XML-файла с сайта ЦБ РФ используется модуль urllib.request:

import urllib.request
url = "http://www.cbr.ru/scripts/XML_daily.asp"

Открываем URL и считываем его:

webFile = urllib.request.urlopen(url)
data = webFile.read()

Далее нам надо сохранить данные в файл на жестком диске. По задумке файл должен иметь такое же название, как и конец URL-адреса, но с расширением .xml. Для этого сначала по слэшам разбивается весь URL-адрес и извлекается его концовка.

UrlSplit = url.split("/")[-1]

Затем концовка отсеченной части URL-адреса (XML_daily.asp) заменяется на xml:

ExtSplit = UrlSplit.split(".")[1]
FileName = UrlSplit.replace(ExtSplit, "xml")

Теперь открывается(или создается) на жестком диске файл, в который записываются информация, полученная с интернет страницы:

with open(FileName, "wb") as localFile:
    localFile.write(data)

И в конце выполняется закрытие веб-станицы:

webFile.close()

На этом первый этап завершен.

2-й и 3-й этапы

Парсинг XML-файла осуществляется с помощью стандартного модуля xml:

from xml.dom import minidom

Открываем для парсинга скачанный файл:

doc = minidom.parse(FileName)

Извлекаем дату из корневого элемента, которая прописана в качестве его первого атрибута:

root = doc.getElementsByTagName("ValCurs")[0]

XML-код этого элемента выглядит так:

<ValCurs Date="16.12.2014" name="Foreign Currency Market">

Теперь создаем строку с датой, которая позже будет записана в выходной файл в качестве заголовка:

 date = "Текущий курс валют на {date}г. \n".format(date=
root.getAttribute('Date'))

Создадим еще одну строку, которая также будет записана в выходной файл и будет служить строкой таблицы с названиями столбцов (каждый столбец отделен от другого точкой с запятой ;):

head = "Идентификатор; Номинал; Название валюты; Сокращение; 
Курс (руб) \n"

Следующий кусок кода объединяет в себе два этапа. Сначала получаем все данные по валютам:

currency = doc.getElementsByTagName("Valute")

Затем открываем файл, в который будут записываться данные. Открывается он также с помощью менеджера контекста With ... as:

with open("exchange.txt","w") as out:

Записываем раннее подготовленные строки с датой и заголовками столбцов:

out.write(date)
out.write(head)

Извлекаем данные по каждой валюте и записываем их в удобной для нас форме:

for rate in currency:
    sid = rate.getAttribute("ID")
    charcode = rate.getElementsByTagName("CharCode")[0]
    name = rate.getElementsByTagName("Name")[0]
    value = rate.getElementsByTagName("Value")[0]
    nominal = rate.getElementsByTagName("Nominal")[0]
    str = "{0}; {1}; {2}; {3}; {4} \n".format(sid,
    nominal.firstChild.data, 
    name.firstChild.data, charcode.firstChild.data, 
    value.firstChild.data)
    out.write(str)

Все, скрипт готов. Запускаем его командой python3 daily_rate.py и ищем в папке со скриптом файл exchange.txt.

Открываем CSV в LibreOffice и Google Документах

По сути у нас получился CSV-файл, который представляется собой таблицу, столбцы которой отделяются точкой с запятой, а строки - строками. LibreOffice Calc отлично понимает такие файлы (говорят, гораздо лучше чем Exсel).

Достаточно просто открыть наш файл exchange.txt с помощью LibreOffice Calc. Появится диалоговое окно, в котором необходимо поставить галочку напротив Точка с запятой и обязательно снять галочку напротив Запятая, так как запятая используется в качестве разделителя десятичных знаков в столбце с курсом валют.

Теперь можно использовать всю мощь LibreOffice Calc для дальнейшего анализа и построения графиков.

С таким же успехом CSV-файлы понимают и Google Документы.

Смотрите также:

Источники