Глава 5 Finance::Quote - придание модулю Sberbank полезных функций
Чтобы сделать что-то полезное, зайдем на сайт Сбербанка на страничку с котировками ОМС. Текст странички сохраняем на диск. Файл с котировками в формате xls аналогично. Начнем разбираться с последним.
Для работы с excel файлами используется модуль SpreadsheetcRead. Все тонкости работы с excel нам не нужны, достаточно с первой странички получить значение из ячейки с известным адресом. Делается это следующим образом:#!/usr/bin / perl
use Spreadsheet :: Read;
my Sxls = ReadData("dml002. xls ") ;
print " Ixls — > [I){ \'Al ’}\\n " ;
Этот код выведет первую ячейку, с первой страницы.
Нам надо существенно больше. Найти котировки счетов и вытащить цену покупки/продажи. Но простота обращения с модулем облегчит нам задачу. Теперь надо разобраться со страничкой. Если взглянуть на реализации других модулей для Finance: :Quote, то можно понять, что люди предпочитают HTMLaTableExtract. Нам же только вытащить ссылку с первой строчкой, так что сойдут и более простые методы. Котировки в Сбербанке идут по месяцам. Страница для января 2009 года это:
http ://sbrf.ru/ru/valkprev/archive_l/index .php ?yearI14=2009&monthll4=01
Получаемая страница содержит котировки с датами, идут они в обратном порядке. Пример HTML кода с котировками:
31 января 2009 года (с 00 часов 00 мин.)
Для отбора нам понадобится регулярное выражение. Наверно это самый сложный для понимания кусок, но к счастью, писать регулярные выражения существенно проще, чем читать. Итак, на основе предыдущего текста:
) (\\d{2>) (?:\\_\\d + )?\\.xls)
" [~\\(]*\\(. + (\\d{2}) . + (\\d{2>)
Еще один кусок кода. Пора объединить все это в единое целое. В модуле Finance::Quote::Sberbank находим метод sberbank. Сейчас он имеет следующий вид:
sub sberbank { my Squoter = shift ; my @stocks =
}
Для получения текста страничек нам понадобится user agent.
К счастью, он есть у нас, итак, первая строка:my $ua = Squoter->user_agent;
Теперь можно и запросить страничку.
my Syear = 2009; ту Smon = 1;
ту Surl = " http ://sbrf . ru/ru/valkprev/archive_ I/index . php ? year 114=${ year}&monthll4=${mon} " ; my Sresponse = Sua->request (GET Surl);
Важно стараться сделать какую-никакую, но обработку ошибок, в случае с запросом странички, стоит проверить успешность операции. А если неуспешно, нам надо правильно выставить статусы ошибок. Статусы ошибок записываются в @stocks следующим образом:
unless (Sresponse —>is_success) { foreach my Sstock (@stocks) {
Sinfo{Sstock, "success"} = 0;
Sinfo { Sstock , "errormsg"} = "HTTP failure";
}
return wantarray() ? %info : \\%info;
}
Т.е. для каждого запрашиваемого инструмента ставим статус success = О и errormsg = HTTP failure. Какая-то обработка ошибок. Теперь надо разобрать содержимое на предмет интересующих нас ссылок:
my Slink =
ту Scontent = Sresponse —>content;
if (Scontent =~ /request (GET Surl); unless ( !response—>is_success ) { foreach my !stock (@stocks) {
Sinfo{!stock , "success"} = 0;
Sinfoj !stock , "errormsg"} = "HTTP failure";
}
return wantarrayQ ? %info : \\%info ;
}
!content = !response—>content;
Загружаем его как xls-файл:
my $xls = ReadData(Scontent);
Теперь нам надо найти начало котировок ОМС. Это место начинается со строки, определяемой следующим регулярным выражением:
/\\d+\\. Котировки продажи и покупки драгоценных металлов в обезличенном виде/
Пробегаем примитивным поиском:
my Sstart = I;
while ( Sxls — > [1]{" ASstart"} \\~ /\\d + \\. Котировки продажи и покупки драгоценных металлов в обезличенном виде/ && Sstart < 100) {
Sstart++;
}
Определим хэш значений для поиска, в соответствии с определенными выше кодами для различных ОМС:
ту %тар = (
’Золото’ => ’SBRF.AU’ ,
’Серебро’ => ’SBRF.AG’ ,
’Платина’ => ’SBRF.PT’ ,
’Палладий’ => ’SBRF.PD’
);
Начиная с этого момента нам осталось только пробежать по оставшимся строкам в файле, найти наши котировки и заполнить соответствующие части в info:
while ( Sxls — >[1]{" ASstart" }) {
Sstart++;
my Sname = Sxls-> [1]{" ASstart"}; if (Sname) {
my Sstock = $map{$name}; next unless (Sstock);
Sinfo { Sstock , "symbol"} = Sstock;
SinfojSstock, "name"} = !name;
Sinfo{Sstock , "currency"} = "RUB";
Sinfo { Sstock , "method"} = "sberbank";
Sinfo { Sstock , "bid"} = Sxls — > [1] { " ESst art "};
Sinfo{ Sstock , "ask"} = Sxls — >[1]{"DSstart "};
Sinfo{Sstock, "last"} = SinfojSstock, "bid"};
Squoter->store_date(\\%info , Sstock, {today => 1}); Sinfo{Sstock, "success"} = I;
}
}
Теперь осталось только сделать тесты. Здесь на помощь приходит модуль TestuMore.
Открываем t/Finance-Quote-Sberbank.t и пишем там такое:use encoding ’utf8 ’;
use Test:: More;
plan tests => 5;
use_ok (’ Finance :: Quote ’) ;
use_ok ( ’ Finance :: Quote :: Sberbank ’) ;
my Squoter = Finance :: Quote—>new(" Sberbank ") ;
ok(defined Squoter , "created");
my %info = Squoter —>fet ch (" sberbank " , "SBRF.PD"); ok(%info , "fetched");
ok( Sinfo {"SBRF.PD" , "name"), "palladium");
Запускаем тесты в терминале и если все получилось, то видим следующее:
kilork@pantogan: ~ / Desktop /test / Finance—Quote—Sberbank! make test
cp lib/Finance/Quote/Sberbank .pm blib / lib/Finance/Quote/ Sberbank.pm
PERL_DL_N0NLAZY=1 /usr/bin/ perl "-MExtUtils :: Command: :MV!"
"-e" "test_harness (0 , ’blib / lib ’ , ’ blib/arch ’) " t/*.t t/Finance-Quote-Sberbank . . . . ok All tests successful .
Files=I, Tests=5, I wallclock secs ( 1.05 cusr + 0.06
csys = 1.11 CPU)
Это хорошо, теперь можно смело делать make install и запускать GnuCash с загрузкой нашего свежего модуля:
kilork@pantogan:~/Desktop / test/Finance—Quote—Sberbank! make install
Manifying blib /man3/Finance :: Quote :: Sberbank . 3pm Installing /home/kilork/perl/share/perl/5.8.8/Finance/ Quote/Sberbank .pm
Installing /home/kilork/perl/гнап/тапЗ/Finance :: Quote :: Sberbank.3pm
Writing /home/ kilork/perl/lib/perl / 5.8.8 / auto/Finance / Quote/Sberbank/. packlist
Appending installation info to /home/kilork/perl/lib/perl /5.8.8/perllocal .pod
kilork@pantogan:~/Desktop / test/Finance-Quote-SberbankS FQ_LOAD_QUOTELEr="—defaults Sberbank" gnucash gnc . bin—Message: main: binreloc relocation support was disabled at configure time.
Found Finance :: Quote version 1.15
Заходим в редактор цен, жмем "Получить котировки", убеждаемся, что все получилось (5.1).
| ||||
|