Несколько слов о том, как работает импорт валют на сайте infolavka.ru.
Раздел с информацией о курсах валют — один из моих любимых (с технической точки зрения). Мы отображаем актуальные курсы 130 валют и ведем историю 100 валют, начиная с 1998 года (когда-нибудь откроем и более раннюю).
Самое интересное — импорт курсов. Ситуация простая: есть две с половиной сотни стран, у которых полторы сотни разных валют, и соответственно, много банков-эмитентов. Банки самые разные, и далеко не у всех имеются веб-сервисы для того, чтобы автоматически получать обновления курсов. Из сотни валют мы нашли только 14 банков, которые удобны для скриптов.
Разумеется, даже в этих 14 случаях формат данных ни разу не повторяется. Одни банки предлагают XML (с уникальной структурой), другие — RSS-потоки, третьи публикуют данные в CSV, четвертые — в текстовых таблицах. Некоторые банки размещают данные в PDF или просто HTML, но мы их сейчас не читаем. Самый необычный формат доставки, которым мы пользуемся, — у банка Казахстана: он рассылает данные по электронной почте.
Моя первая версия скрипта-фетчера, собирающего информацию из двух или трех банков, пользовалась только XML-экспортом. Несколько XSLT-файлов преобразовывали XML из разных форматов в единый, который затем парсился перлом.
На втором подходе к задаче появились отдельные модули, импортирующие конкретный банк:
use Infolavka::Tools::Money::Fetch::BYR;
use Infolavka::Tools::Money::Fetch::CAD;
use Infolavka::Tools::Money::Fetch::CHF;
use Infolavka::Tools::Money::Fetch::CZK;
use Infolavka::Tools::Money::Fetch::EEK;
use Infolavka::Tools::Money::Fetch::EUR;
use Infolavka::Tools::Money::Fetch::ILS;
use Infolavka::Tools::Money::Fetch::LTL;
use Infolavka::Tools::Money::Fetch::LVL;
use Infolavka::Tools::Money::Fetch::RUB;
use Infolavka::Tools::Money::Fetch::RON;
use Infolavka::Tools::Money::Fetch::GEL;
use Infolavka::Tools::Money::Fetch::IRR;
use Infolavka::Tools::Money::Fetch::KZT;
Скрипт импорта обходит банки и обновляет соответствующие таблицы в базе данных. Если запрос на какой-то из банков сбоит, используются данные, полученные в последний удачный раз:
for my $code (@codes) {
warn "Fetching exchange rates for $code...\n";
my $fetcher =
eval "new Infolavka::Tools::Money::Fetch::$code";
my $data =
$fetcher->fetch_current // get_last_available($code);
warn "ok\n" if defined $data;
push @{$items{$code}}, @$data if defined $data
}
(Обратите внимание, как Леша применил оператор defined-or.)
Итог работы можно видеть на страницах с курсами за текущий день в виде чисел или на отдельных страницах в виде графика с историей курса.
Отдельное удовольствие доставляет возможность играться с имеющимися данными и отображать их в разных видах, например, в виде облака валют (есть еще куча задумок).
Комментировать