--- title: Yahoo!ファイナンスのページから外国為替情報を取得し、DBに登録する author: kazu634 date: 2009-09-26 url: /2009/09/26/_1335/ wordtwit_post_info: - 'O:8:"stdClass":13:{s:6:"manual";b:0;s:11:"tweet_times";i:1;s:5:"delay";i:0;s:7:"enabled";i:1;s:10:"separation";s:2:"60";s:7:"version";s:3:"3.7";s:14:"tweet_template";b:0;s:6:"status";i:2;s:6:"result";a:0:{}s:13:"tweet_counter";i:2;s:13:"tweet_log_ids";a:1:{i:0;i:4797;}s:9:"hash_tags";a:0:{}s:8:"accounts";a:1:{i:0;s:7:"kazu634";}}' categories: - mysql - Perl ---

日本円が、各国の通貨に対してどの程度の価値を持っているかを自動で取得できるようにしてみました。

MySQLのテーブルの準備

今回はMySQLで次のようなデータベースとテーブルを準備しました。

mysql> use money;
Database changed
mysql> desc JPY;
+-------+-------------+------+-----+---------+----------------+
| Field | Type        | Null | Key | Default | Extra          |
+-------+-------------+------+-----+---------+----------------+
| id    | int(11)     | NO   | PRI | NULL    | auto_increment |
| date  | datetime    | YES  |     | NULL    |                |
| USD   | float(10,7) | YES  |     | NULL    |                |
| AUD   | float(10,7) | YES  |     | NULL    |                |
| GBP   | float(10,7) | YES  |     | NULL    |                |
| CAD   | float(10,7) | YES  |     | NULL    |                |
| CHF   | float(10,7) | YES  |     | NULL    |                |
| EUR   | float(10,7) | YES  |     | NULL    |                |
+-------+-------------+------+-----+---------+----------------+
8 rows in set (0.00 sec)
mysql>

perlのスクリプト

今回作成したのは、次のようなスクリプトです。

# === Libraries ===
use strict;
use warnings;
use Perl6::Say;
use YAML;
use URI;
use Web::Scraper;
use Encode;
use utf8;
use DBI;
use POSIX 'strftime';
# === Main part ===
my $scraper = scraper {
process '//table[@class="yjS"]/tr[2]', 'JPY' => scraper {
process '//td[2]', 'USD' => 'TEXT';
process '//td[3]', 'AUD' => 'TEXT';
process '//td[4]', 'GBP' => 'TEXT';
process '//td[5]', 'CAD' => 'TEXT';
process '//td[6]', 'CHF' => 'TEXT';
process '//td[7]', 'EUR' => 'TEXT';
};
};
my $result = $scraper->scrape( URI->new("http://quote.yahoo.co.jp/m3") );
# print encode( 'utf8', YAML::Dump($result) );
# データベースへの接続
my $dbh =
DBI->connect( 'dbi:mysql:dbname=money', 'root', 'musashi',
{ RaiseError => 1, AutoCommit =>  } );
# ステートメントハンドラの作成
# my $sth = $dbh->prepare("SELECT address FROM renoir WHERE address LIKE ?;");
my $sth = $dbh->prepare(
"INSERT INTO JPY(date, USD, AUD, GBP, CAD, CHF, EUR) VALUES (?, ?, ?, ?, ?, ?, ?);"
);
# MySQLの日付時刻型( datetime型 )
my $current_datetime = strftime( "%Y-%m-%d %H:%M:%S", localtime );
# ステートメントハンドラの実行
# もしプレースホルダを用いていれば、引数を指定する
# 例: $sth->execute("$query%");
$sth->execute(
$current_datetime,         $result->{'JPY'}->{'USD'},
$result->{'JPY'}->{'AUD'}, $result->{'JPY'}->{'GBP'},
$result->{'JPY'}->{'CAD'}, $result->{'JPY'}->{'CHF'},
$result->{'JPY'}->{'EUR'}
);
# ステートメントハンドラの解放
$sth->finish;
# データベースハンドラの解放
$dbh->disconnect;

実行結果

kazu634@srv634% perl 200909252353_money.pl                                ~/work/tmp_perl/scrap [6573]
---
JPY:
AUD: 77.790160
CAD: 82.107192
CHF: 87.145080
EUR: 131.633856
GBP: 142.961824
USD: 89.620000

MySQLで確認してみます:

mysql> SELECT * FROM JPY\G
*************************** 1. row ***************************
id: 1
date: 2009-09-26 11:31:16
USD: 89.6200027
AUD: 77.7901611
GBP: 142.9618225
CAD: 82.1071930
CHF: 87.1450806
EUR: 131.6338501
1 row in set (.00 sec)