読者です 読者をやめる 読者になる 読者になる

woshidan's blog

そんなことよりコードにダイブ。

htmlファイルからデータを取得してrakeファイルを作る

 昨日、

テスト用データを用意するのに疲れた。rakeファイル使ったり、rakeファイルに入れるデータを用意したりしてたら少し手間だったのでそれでやや満足して作業を中断したり

とか書いてましたが、

htmlファイルからデータを取得して登録用のrakeファイルを出力するプログラムを書いてみました。

 

データ取得用のhtmlの元はhttp://yakkun.com/data/zukan_ex4.htmからお借りしました。

 

前提

  • htmlファイルは表示用のデータをどこかのセクションにまとまって持っており、そこでは一定の構造で同種のデータが繰り返し出力されている
  • rakeファイルはmake_test_dateメソッドの引数であるtask_nameという名前のタスクを一つ持っていて、その中でひたすらcreate!で取得したデータを登録するとする
  • Railsのプロジェクトのデータベースに登録するオブジェクトはPage(name:string, introduction:string)とし、make_test_dataメソッドには、Pageの持つ属性名の配列['name','introduction']をdate_columnとして渡している

 

実装

make_test_data(html_path, object_name, data_column, task_name)

html_pathはhtmlファイルのパス。

今回はhtmlファイルは事前にデータが乗っているhtmlをダウンロードしてきているとします。

object_nameはデータベースに登録するオブジェクトの名前で、data_columnはそのオブジェクトの属性の名前の配列です。task_nameはデータベースに登録するときのタスクの名前。

 

これら引数を渡すと最終的にはhtmlファイルに載っているデータをdata_columnにはいっている値をキーとするハッシュに加工して最終的にそのハッシュの配列を取得します。

そのハッシュの配列を使ってobject_nameで指定したオブジェクトを登録するためのrakeファイルをこのプログラムのあるディレクトリにtask_name.rakeという名前で生成します。

出来上がったtask_name.rakeをRailsのlib/tasksに入れて、rake db:task_nameと入力したら

取得したデータがデータベースに登録できます。

 

get_file_contents(html_path)

html_pathで指定したファイルを開いてその内容を返します。

複数のファイルからデータを取得したい場合はここを書き換えるのだと思います。

 

trim_file(html_file)

get_file_contentsで取得したファイルの中身を受け取って、データを取らない範囲を取り除きます。

以下のコードでは、データを取る範囲の直前、直後の文字列をcontents_start_pattern,contents_end_patternに指定して.scanメソッドでその間の部分を取得するようにしています。

これはhtmlファイルによって書き換える必要があります。

 

get_raw_records(contents)

contentsはデータがはいっている部分のhtml。

これは一定の方法で繰り返し表記されているデータを、装飾用のタグなどを取り除いて各列のデータだけを抽出して列ごとに配列を作ります。

最後に、その列ごとの配列を同じ行のデータを一つにまとめた配列にして返します。

このとき、行ごとに各列のデータを入れる順番はdata_columnに書いたものと同じにします。

これはhtmlファイルや登録したいデータの形式によって書き換える必要があります。

 

数字が複数桁並んでる場合の取得にミスってるので書き直す必要が……笑。

 

convert_to_records(raw_records, data_column)

raw_recordsはget_raw_records(contents)の戻り値。

これの配列の各列をdata_columnの値と対応づけて、配列の配列をハッシュの配列に直す。

特にraw_recordsやdata_columnの値で処理を変える必要はありません。

 

make_rake_task(records, object_name, data_column, task_name)

rakeファイルを作成する。特に引数の値やdata_columnの列の数によって処理を変える必要はありません。

start_pattern,end_patternやcreate_patternを書き換えてやれば他のデータベースに入れる用のファイルにも書き換えられると思います。

 

で実際に、

make_test_data('./data.html', 'Page', ['name','introduction'], 'guide')

と実行して出来上がったもの(guide.rake)

 

書いた後で難なのだけど、こうして出来上がったデータをrakeタスクで登録することってあるのでしょうか……。

データベースに保存しやすいcsvxmlで出力したほうがいいのでは、と書き終わったあとで思いました。

その場合は、make_rake_taskの代わりにmake_xmlでも書けばいいんですね。はい。

 

そしてintroductionじゃなくてdescriptionとか他にもっといい名前あるよなー。

 

わーい、ポケモン図鑑だー笑