Level 4 テスト・データベースの構築
テスト用のデータベースを構築する。最低でも1万件以上、大きさにして、10MB以上1GB以下の大きさのテスト・データベースを生成する必要がある。 これらを手で入力することは不可能である。プログラムを作成し、乱数、または、WWW上のデータなどを利用しながら、テスト・データベースを作成する。 ヒント: 最初からデータベースにするのではなく、一度、テキスト(CSVなどか?)としてテストデータを生成する方が良い。そして、そのテキストを読み込んで、データベースに insert するプログラムを作成する。
ヤマダ電機の通信販売ページから、データを抽出する事にした。入力データは、ヤマダ電機の商品ID、商品名、会社名、型番(CDはJAMコード)、値段、ポイント、定価を抽出し、全てのデータが揃っている商品のみ、データベースに登録する。
データの抽出は、AVデジカメ館、家電健康館、パソコン館、文具オフィス館、CDDVD館から抽出する。それ以外のカテゴリは、条件に合ったデータを得る期待値が低いため、除外した。CDDVD館においても、DVDに関しては、期待値が低かったので同じく除外した。データの抽出においては、文字列の扱いに優れているjavaを用いて行った。
おおまかな流れとしては、あらかじめ作成したindexファイルを参照し、それぞれのカテゴリへwgetで読み込み、それを解析し、商品リストをwgetで読み込み、解析する。無効なデータの抽出も多く予想されるので、目標取得件数を120%の12万件と定めた。
実際に取得したデータは138,540件で、うち有効なデータ107,049件の入力を試みた。しかし、商品名が長すぎるといった、我々の定義したテーブルに格納不可能なデータも含まれているので、実際はこれより少なくなる事が予想される。データの取得ルーチン
目標とするデータを取得するために、いくつかのステップに分けて説明する。使用したプログラムは、web_get.java、Function.java、yamada_data.javaである。
取得したデータをlist_analysis.javaを用いて、sqlへ入力用に変換し、入力した。上のデータをINSERT INTO item_deji VALUES(1351078014,'MS-PD','SONY',19800,2376,'オープンプライス','MSXM2GS');といった形に変換した。
ステップ1 まず、YAMADA電機のインデックスページから、使用するカテゴリのみをファイルに書き込む。これについては手動で作成した。青い枠で囲った部分がカテゴリ名である。
ファイルには以下のようにして書き込んだ。
AV・デジカメ館 http://www.yamada-denkiweb.com/contents.php/category/10/ 家電・健康館 http://www.yamada-denkiweb.com/contents.php/category/11/ パソコン館 http://www.yamada-denkiweb.com/contents.php/category/12/ステップ2 次に、先に作成したファイルを参照しながらリンクをたどる。左の画像は、AV・デジカメ館のリンクをたどったら現れる。
ここで重要なのは、2度手間をかけないように、青の四角でかこった部分を除外する事である。この部分は、赤で囲った部分のデータを並び替えただけなので、不要である。
まず、htmlファイル中に、<!-- カテゴリーリスト Start -->といったフレーズが出ると、解析を開始する。プログラム中では、web_get.filter1(String root,String uri,String to);で行っている。rootはダウンロードしたページのURLで、uriは、ダウンロードしたファイルの保存先、toは書き出し先を指している。
写真の青い部分は、この場合、『機種からデジカメを選ぶ』といった文字が出てきたら、次のカテゴリまでスキップする。このような文字は、<td colspan="4" valign="top" class="t12l">タグで始まるので、これを用いて判別している。基本的に、uriはtempファイルとして保存し、toは、作業ディレクトリ/カテゴリ名.list、として保存される。
データの保存形式を以下に記す。
##roothttp://www.yamada-denkiweb.com/contents.php/category/10/ ##category:デジタルカメラ 500万画素デジカメ /item/list.php/category/10/315/16/ 600万画素デジカメ /item/list.php/category/10/315/17/ 700万画素デジカメ /item/list.php/category/10/315/18/ 800万画素デジカメ /item/list.php/category/10/315/19/ ##category:衛星放送機器・アンテナ BSアンテナ /item/list.php/category/10/81/10/ BSチューナー /item/list.php/category/10/81/11/ BSデジタルチュー /item/list.php/category/10/81/12/ステップ3
作業ディレクトリ/カテゴリ名.listを参照し、さらに下ると、左の画面に出る。左の画面は、AVデジカメ館の500万画素の商品リスト、家電健康館の冷蔵庫の商品リスト、CDDVD館のソウル/RandBの商品リストのページである。商品リストのページには、この3パターンが存在する。
この3種類のページそれぞれに対して、自動で判別する機能は装備していない。なので、手動での切り替えでプログラムを実行した。 web_get.filter2(String base,String category,String from,String to,boolean bool);を再帰的に実行してリンクを辿っていった。 baseはベースアドレスで、ホームページのURLが書かれている。categoryにはカテゴリ名、fromはファイル読み込み先、toは書き出し先、boolはリンクを辿るかどうかである。一般的に、toは作業ディレクトリ/カテゴリ名/サブカテゴリ名xx.list として保存される。
このページでは、<!-- 商品情報 START -->がキーワードとなっていて、ページ中にこれを発見した場合、web_get.filter2_analysis(BufferedReader br,String category,String write,my_file_writer file_write));でパターン1を、filter2_analysisaでパターン2、filter2_analysisaaでパターン3を解析している。
データの保存形式例を以下に記す。
##category:デジタルカメラ 会社名 :キャノン 商品名 :Canon500万画素デジタルカメラIXYDIGITAL60 型番 :IXYDIGITAL60 商品番号:3150692019 特価 :38,800円 ポイント:9,700 定価 :オープンプライス 会社名 :カシオ 商品名 :CASIOEXILIMZOOM500万画素EX-Z500シルバー 型番 :EXZ500S 商品番号:3150676019 特価 :35,200円 ポイント:7,744 定価 :オープンプライス ##category:キャンプ・スキー用品 会社名 : 商品名 :スキー 型番 :RDメンズタートル 商品番号:9972426016 特価 :990円 ポイント:99 定価 :オープンプライス
在庫テーブルのデータを追加する。在庫テーブルのITEM_IDは上で追加したデー タに対応していなければならないため、商品テーブルからITEM_IDを読み込む必 要がある。在庫の数はとりあえず全て100個にした。下記にデータを追加するphp プログラムを示す。
ソース : zaiko.php
<?php define('USER','SYSTEM'); define('PASS','XXXXX'); define('DB',''); //Oracleデータベースに接続 $con=oci_connect(USER,PASS,DB); /*SQL文を生成 TABLE_NAMEは商品テーブル名を変更して実行する。※デバッグのため*/ $sql="select ITEM_ID from TABLE_NAME"; /*SQLの実行*/ $stmt=oci_parse($con,$sql); oci_execute($stmt,OCI_DEFAULT); /*指定した商品テーブルのITEM_IDを受け取る*/ $i=0; while(oci_fetch($stmt)){ $data[$i++]=oci_result($stmt,"ITEM_ID"); } /*在庫テーブルにデータを追加する*/ for($i=0;$i<count($data);$i++){ $sql="insert into stock values(".$data[$i].",100)"; $stmt2=oci_parse($con,$sql); if(!oci_execute($stmt2,OCI_DEFAULT)){ oci_rollback($con); }else{ oci_commit($con); } } //Oracleデータベースと切断する。 oci_close($con); ? >データを追加した後下記のSQL文を実行してデータがちゃんと格納されているか 確認する。
SQL> select count(ITEM_ID) from stock; COUNT(ITEM_ID) -------------- 104964 SQL>上記のようにちゃんと追加されていることが確認できた。 データは全部で10万4千件以上追加されていて1レコード約220byteなので 実験条件の"最低でも1万件以上、 大きさにして、10MB以上1GB以下の大きさのテスト・データベースを生成する必 要がある。"をクリアしている。
level3 index Level5