ボートレース競走結果 収集クローラ作成⑤ ~webページ作成~

概要

web上からデータベースのデータにアクセスするための簡単な動的webページを作成した。
言語は、php
webserverには、apache
を使用した。
クローラの全体像については、こちらを参照 全体の概要:

Webserver構築

apacheを使用した。
このwebサイトを参考に構築した。

ソースコード説明

SQL問い合わせ入力画面
フォームの情報をポストメソッドで送った。

<html>

<head>
   <meta charset="utf8">
   <title>Boatrace_crawrer</title>
</head>

<body>
<h2>
Boatrace_crawrer<br/>
</h2>
<h4>
問い合わせ
</h4>

<form method="post" action="webpage_sample.php">
    query:<br />
    <input type="text" name="query" size=100/><br/>
    <input type="submit" value="実行"/>
</form>

</body>
</html>

f:id:maru-taka:20170913085739p:plain
実行画面


入力画面で入力しポストメソッドで送った問い合わせを実行する。

<html>

<head>
<meta charset = "utf-8"/>
<title>Boatrace_crawrer</title>
</head>

<body>

<?php

        print "<p><a href=\"getquery.php\">query画面へ</a></p>";
    //設定ファイルの読み込み
    require_once("config.php");

        ini_set("mysqli.default_socket","/tmp/mysql.sock");

    //MySQLへの接続
    $link = mysqli_connect($dbserver,$user,$password,$dbname)
        or die("MySQL unconected");

    //文字コード設定
    mysqli_set_charset($link, "utf8")
        or die("can't link code");

    //問い合わせ
    $query = $_POST["query"];

    $result = mysqli_query($link,$query)
        or die("fail implements of query!");

    $rows = mysqli_num_rows($result);
    print "<p>該当件数は" . $rows . "件でした。<br />";

    print "<p>問い合わせ結果";
    print "<ul>";
    while ($row = $result->fetch_assoc()) {
        print "<li>";
        print_r($row);
        print "</li>";
    }
    print "</ul>";

    mysqli_free_result($result);

    mysqli_close($link);
?>
</body>
</html>

f:id:maru-taka:20170910065824p:plain
実行画面

localhost127.0.0.1

MySQLでは、接続の際にサーバをlocalhostで指定するのと127.0.0.1で指定するのでは、挙動が異なる。
具体的には、localhostを指定した場合には、UNIXドメインソケットを用いて通信を行い、127.0.0.1では、TCP/IP通信を用いて通信が行われる。
今回は、ini_set関数を用いてlocalhostUNIXドメインソケットを用いて通信を行った。

ini_set("mysqli.default_socket","/tmp/mysql.sock");

うまく設定できていないと次のようなエラーメッセージが表示される。

Warning: mysqli_connect(): (HY000/2002): No such file or directory in /.../webpage_sample.php on line 19
MySQL unconected%

参考webサイト

ボートレース競走結果 収集クローラ作成④ ~データベースアクセス~

概要

 このブログでは、スクレイピングでとってきたデータをデータベースに登録する部分について説明する。
 今回は、MySQLRubymysqlライブラリを用いてアクセスした。
クローラの全体像については、こちらを参照

なぜMySQLを選んだか

 MySQLを選んだ理由は、まず金銭的に厳しいので、OSSを使用することを決めた。
 次に、ボートレースの結果のようなレース結果、選手データ、直前情報などのたくさんの種類の複雑な情報を扱うのに適していると考え、RDBMSを選択した。
 最終的にMySQLPostgreSQLで、迷ったが、過去に使用した経験があったためとっつきやすかったためMySQLを使用することに決めた。

db-study.com academy.gmocloud.com

データベース定義

race_idを主キーにした。 race_idは単純に開催場の番号*1、ラウンド、日時を結合しただけ。また第3正規形にした。
 round_infoは、そのラウンド固有の水面天候状況、払い戻しなどの情報をを格納する。race_infoは、それぞれの艇のレース結果を格納する設計になっている。

/*use test;*/
use boat;

create table round_info(
        race_id varchar(12) not null,/*place + round_no + day*/
        primary key(race_id),
        place varchar(8),
        round_no int,
        day varchar(10),
        
        /*気象条件*/
        temp float(3,1),
        sky varchar(8),
        wind int,
        water_temp float(3,1),
        wave int,

        /*払い戻し*/
        3tan_kumi varchar(10),
        3tan_money int,
        3tan_pop int,
        3puku_kumi varchar(10),
        3puku_money int,
        3puku_pop int,
        2tan_kumi varchar(10),
        2tan_money int,
        2tan_pop int,
        2puku_kumi varchar(10),
        2puku_money int,
        2puku_pop int,
        kaku1_kumi varchar(10),
        kaku1_money int,
        kaku1_pop int,
        kaku2_kumi varchar(10),
        kaku2_money int,
        kaku2_pop int,
        kaku3_kumi varchar(10),
        kaku3_money int,
        kaku3_pop int,
        tan_kumi varchar(10),
        tan_money int,
        fuku1_kumi varchar(10),
        fuku1_money int,
        fuku2_kumi varchar(10),
        fuku2_money int, 

        /*決まり手*/
        kimarite varchar(12),

        /*返還*/
        return_money varchar(1)

) engine=InnoDB;

create table race_info(
        race_id varchar(12),
        boat_no varchar(1),
        primary key(race_id,boat_no),
        race_rank varchar(1),
        racer_no varchar(4),
        race_time varchar(8),
        course varchar(1),
        st_time varchar(4),

        foreign key(race_id) references round_info(race_id)
) engine=InnoDB;

データベースアクセス

スクレイピングでとってきたデータを成型してデータベースに入れていく。
冗長なので、一例を記載している。

#データベースアクセス
connection = Mysql::connect("localhost", "username", "password", "databasename")

# 文字コードをUTF8に設定
connection.query("set character set utf8")

.
.

puts("insert into race_info(race_id, boat_no, race_rank, racer_no, race_time, course, st_time) values(\"#{query[1]+query[0]+query[2]}\", \"#{boat1[1]}\", \"#{boat1[0]}\", \"#{boat1[2]}\", \"#{boat1[5]}\", \"#{course[0]}\", \"#{st_time[0]}\" )")

.
.

# コネクションを閉じる
connection.close

手間取ったところ

データを挿入するのにとても長いSQL文を書いた。
これを書いてちゃんとデータがあってるか確認するのが大変だった。

connection.query("insert into round_info(race_id, place, round_no, day, temp, sky, wind, water_temp, wave, kimarite, return_money, 3tan_kumi, 3tan_money, 3tan_pop, 3puku_kumi, 3puku_money, 3puku_pop, 2tan_kumi, 2tan_money, 2tan_pop, 2puku_kumi, 2puku_money, 2puku_pop, kaku1_kumi, kaku1_money, kaku1_pop, kaku2_kumi, kaku2_money, kaku2_pop, kaku3_kumi, kaku3_money, kaku3_pop, tan_kumi, tan_money, fuku1_kumi, fuku1_money, fuku2_kumi, fuku2_money)  
values(\"#{query[1]+query[0]+query[2]}\", \"#{prace_name(query[1])}\", #{query[0].to_i}, \"#{query[2]}\", #{weather_s[0]}, \"#{weather_s[1]}\", #{weather_s[2]}, #{weather_s[3]}, #{weather_s[4]}, \"#{win_tec[0]}\", \"#{return_money[0]}\", \"#{p3tan[1]}\", #{p3tan[2].to_i}, #{p3tan[3].to_i}, \"#{p3puku[1]}\", #{p3puku[2].to_i}, #{p3puku[3].to_i}, \"#{p2tan[1]}\", #{p2tan[2].to_i}, #{p2tan[3].to_i}, \"#{p2puku[1]}\", #{p2puku[2].to_i}, #{p2puku[3].to_i}, \"#{pkaku[1]}\", #{pkaku[2].to_i}, #{pkaku[3].to_i}, \"#{pkaku[4]}\", #{pkaku[5].to_i}, #{pkaku[6].to_i}, \"#{pkaku[7]}\", #{pkaku[8].to_i}, #{pkaku[9].to_i}, \"#{ptan[1]}\", #{ptan[2].to_i}, \"#{ppuku[1]}\", #{ppuku[2].to_i}, \"#{ppuku[3]}\", #{ppuku[4].to_i} )")

*1:ボートレースの開催場には、電話投票用に番号が振られている。

ボートレース競走結果 収集クローラ作成③ ~スクレイピング~

概要

ここでは、RubyのNokogiriを用いたボートレース競走結果のスクレイピングについて説明する。
クローラの全体、開発環境について:

Nokogiriのインストール

Nokogiriのインストールは、別途ブログを書いているので、そちらを参照してほしい。

スクレイピングで得るデータ

最初に、どのwebページからどの情報を持ってくるかとその実装に手をつけた。
競走データと言ってもボートレースには、様々な情報があるが今回は、レースの結果に関係する情報を集めた。 レースの結果ページから

  • 開催情報(場所、ラウンド、日時)
  • 進入コース
  • 着順
  • 選手の登録番号
  • レースタイム
  • スタートタイミング
  • 気象水面状況
  • 払い戻し金額

以上の情報を

結果|BOAT RACE オフィシャルウェブサイト

のようなページから取得することにした。

ソースコード説明

XPathCSSセレクタで、指定した情報を取り出すことができる。
XPathは、少し触ったことがあったので、そっちでやった。
adjust_data は、XPathとdoc(Nokogiri::HTML::Document)から 取得した情報をString配列にして返す関数。 後は、適切なXPathを使って、必要なデータを取得する。

#スペース、改行、タブ、全角を半角にして返す。スペース改行、複数タブ区切りで配列にする
def mtrim(text)
        text.gsub!(/\\n|\\r|\\t/," ")
        text.gsub!(/[[:space:]]/," ")
        text.tr!(" "," ")
        text.tr!('0-9a-zA-Z', '0-9a-zA-Z')
        text.gsub!(/\s+/,SEPALATER)
        text.gsub!(/^\t/,"")
        text.gsub!("\"","\'")
        text = text.split(SEPALATER)
        return text
end

#データを整える
def adjust_data(xpath,doc) 
  boat = doc.xpath(xpath)
  if boat.text != "" then
    boat.each do |boat|
      xpath = mtrim(boat.text)
    end
  else
    xpath = Array.new
  end
  return xpath
end

boat1 = adjust_data("//html/body/main/div/div/div/div[2]/div[4]/div[1]/div/table/tbody[1]",doc)

今回は、tbodyタグがいい感じにあったので、それを使った。

.
.
.
<tbody>
    <tr>
        <td class="is-fs14"></td>
        <td class="is-fs14 is-fBold is-boatColor5">5</td>
        <td class="is-p20-0">
            <span class="is-fs12">4237</span> 
            <span class="is-fs18 is-fBold">大峯   豊</span>
        </td>
        <td>1&#39;50&quot;9</td>
    </tr>
</tbody>

<tbody>
    <tr>
        <td class="is-fs14"></td>
        <td class="is-fs14 is-fBold is-boatColor4">4</td>
        <td class="is-p20-0">
            <span class="is-fs12">4150</span> 
            <span class="is-fs18 is-fBold">山田  雄太</span>
        </td>
        <td>1&#39;52&quot;1</td>
    </tr>
</tbody>

.
.
.

また開催情報(日付、場所、ラウンド)は、URLのクエリから取得した。

require 'uri'
#urlから場、ラウンド、日時を抜き出す。
query = get_url.query #URI::Generic#query
query.tr!('a-z',"")
query.tr!("=","")
query = query.split("&")

#ラウンド数の先頭に0(ex.02,12,09)
query[0] = format("%02d", query[0])

はじめは、rubyからshellのコマンドを呼び出し、その日の日付をえていたが、それでは、shell依存になってしまうので、Dateクラスを用いて、その日の日付を取得するように改良した。

#シェルver
=begin
#今
date = `date "+%Y%m%d"`
#適当に時間いじる
date = `env TZ=JST-30 date "+%Y%m%d"`
#puts mdate.class
mdate = date.to_i
puts mdate
=end

#ruby_ver
today = Date.today
date =  today.iso8601
date.tr!("-","")
mdate = date.to_i
puts date

Rubyコーディング規約について

 今回、開発をすすめるなかで、友人からRubyに目安となる標準のコーディング規約があることを初めて聞いた。
 コーディング規約は、実際のプロジェクトごとに決められそのプロジェクト内で守られる物と考えていた私には衝撃だった。
 今後は、その標準的なコーディング規約を意識して、コーディングしていきたいと思う。

ボートレース競走結果 収集クローラ作成② ~webページ巡回~

概要

このページでは、Anemoneを用いたwebページ巡回について説明する。
クローラの全体像については、こちらを参照

実際のコード解説

Anemone.crawlにクロールの起点となるURLを指定、dateはクロールする日付を入れるようになっている。
:depth_limitはリンクをたどる階層の深さ :delayはクロールする間隔を秒単位で設定

facus_crawlでクロールするurlを指定する。
ここで指定されていないのは、読み込みもしない on_pages_likeで正規表現に一致するurlに対して処理をする。
get_resultはNokogiriで使える形式のdocとURLから必要なデータを取り出す処理を行う。
ここに関しては、

https://www.amazon.co.jp/dp/toc/4797380357/ref=dp_toc?_encoding=UTF8&n=465392

といったサイトや書籍を参考にして作成した。

ソースコード

Anemone.crawl("https://www.boatrace.jp/owpc/pc/race/index?" + "hd=" + date , :depth_limit => 2, :delay => 1) do |anemone|
  anemone.focus_crawl do |page|
    page.links.keep_if { |link|
      link.to_s.match(/(\/raceresult)(.)*hd=#{mdate}$/)#実行時の日時のデータを取得
    }
  end

  anemone.on_pages_like(/\/raceresult/) do |page|
    puts "\n\n-------------------------------------------------------------------\n\n" 
    puts page.url.to_s
    #Nokogiri形式にしてget_resultに渡す
    get_result(page.doc,page.url)
  end
end

ボートレース競走結果 収集クローラ作成①

概要

はじめに

前のブログで言った、
ボートレースの競走データを蓄積する仕組み
がおよそ完成した。
ここでは、その製作過程を書いていく。

↓作ろうと思った動機など

完成した物の概要

最終的に作ったものの流れは、

  1. RubyのAnemoneを用いてwebページを巡回
  2. Nokogiriでスクレイピング
  3. その結果をMySQLでデータベースに登録
  4. webサイトを作りそのデータにアクセス

となっている。
④のwebサイトは簡易的な物で、ローカル環境内から動的なwebページを使ってデータベースにアクセスできるようにした。
以上の4項目それぞれについて説明していこうと思う。

robots.txt

今回、クローラを作成するにあたり調べたところ、それぞれのwebサイトには、クローラのアクセスを制限する為の情報があることが分かった。
その情報は、robots.txtという名前でサイトのルートディレクトリ直下に置かれている。
調べて見るとこれは、強制的にアクセスを制限するわけではなく、
主に検索エンジンのクローラが進んで参照し、効率よくリンクをたどる時の参考やアクセスして欲しくないところをサイト運営側が明記する為にあるらしい。
今回は一つのサイトしか見ないため、robots.txtを直接見て確認すると特にクローラのアクセスに
制限は、かけていないことが分かった。
https://www.boatrace.jp/robots.txt

参考
robots.txtとは | SEO用語集:意味/解説/SEO効果など [SEO HACKS]

完成したやつの適当な画像

スクレイピング結果を試しに出力 f:id:maru-taka:20170910065318p:plain

データベースに格納したとこ f:id:maru-taka:20170910062620p:plain

試しに作った適当なwebページ f:id:maru-taka:20170910065818p:plain f:id:maru-taka:20170910065824p:plain

開発環境一覧

Ruby

➜  ruby git:(master) ✗ ruby --version
ruby 2.4.1p111 (2017-03-22 revision 58053) [x86_64-darwin14]

Rubyのいろんなライブラリ

➜  ruby git:(master) ✗ gem list

*** LOCAL GEMS ***

anemone (0.7.2)
bigdecimal (default: 1.3.0)
bundler (1.15.4)
dbd-sqlite3 (1.2.5)
dbi (0.4.5)
deprecated (2.0.1)
did_you_mean (1.1.0)
io-console (default: 0.4.6)
json (default: 2.0.2)
mini_portile2 (2.2.0)
minitest (5.10.1)
net-telnet (0.1.1)
nokogiri (1.8.0)
openssl (default: 2.0.3)
power_assert (0.4.1)
psych (default: 2.2.2)
rake (12.0.0)
rdoc (default: 5.0.0)
robotex (1.0.0)
ruby-mysql (2.9.14)
sqlite3 (1.3.13)
sqlite3-ruby (1.3.3)
test-unit (3.2.3)
xmlrpc (0.2.1)

MySQL

➜  ruby git:(master) ✗ mysql --version
mysql  Ver 14.14 Distrib 5.7.19, for osx10.10 (x86_64) using  EditLine wrapper

Apache

➜  ruby git:(master) ✗ apachectl -v
Server version: Apache/2.4.16 (Unix)

php

➜  ruby git:(master) ✗ php -version
PHP 5.5.27 (cli) (built: Jul 23 2015 00:21:59)
Copyright (c) 1997-2015 The PHP Group
Zend Engine v2.5.0, Copyright (c) 1998-2015 Zend Technologies

zsh

➜  ~ zsh --version
zsh 5.4.1 (x86_64-apple-darwin14.5.0)

参考図書

rubyのクローラの本と言えばこれみたいなのがあるらしく
図書館で、借りてみるとすごいわかりやすかった。
クローラとは何かというところから実際の運用例まで示されていて
クローラ関係のことは、スクレイピングという言葉だけしか知らなかった私でも非常に読みやすい本だった。
プログラミングは、やったことあってクローラでなにか作りたいという人におすすめ。
未経験からはじめに手に取る本では、ないと思う。

Rubyによるクローラー開発技法 巡回・解析機能の実装と21の運用例 | 佐々木 拓郎, るびきち |本 | 通販 | Amazon

Nokogiriのインストールと練習

目次

Nokogiriのインストール

とりあえず入れてみないことにははじまらないということで、インストールしてみる。
「Nokogiri インストール」で検索するとなんだか一筋縄には行かなそうな感じ

記録残すの忘れてたので普通にもう一回やってみる。

動作環境

シェル

➜  nokogiriprac echo $SHELL
echo $SHELL
/usr/local/bin/zsh
➜  nokogiriprac /usr/local/bin/zsh --version
/usr/local/bin/zsh --version
zsh 5.4.1 (x86_64-apple-darwin14.5.0)
➜  nokogiriprac

OS

OS X Yosemite バージョン10.10.5

Homebrew

➜  nokogiriprac brew --version
brew --version
Homebrew 1.3.1
Homebrew/homebrew-core (git revision e097; last commit 2017-08-28)
➜  nokogiriprac

gem

➜  nokogiriprac gem --version
gem --version
2.6.11

消す作業

➜  nokogiriprac gem uninstall nokogiri
Remove executables:
    nokogiri

in addition to the gem? [Yn]  y
Removing nokogiri
Successfully uninstalled nokogiri-1.8.0
➜  nokogiriprac gem list

*** LOCAL GEMS ***

bigdecimal (default: 1.3.0)
did_you_mean (1.1.0)
io-console (default: 0.4.6)
json (default: 2.0.2)
mini_portile2 (2.2.0)
minitest (5.10.1)
net-telnet (0.1.1)
openssl (default: 2.0.3)
power_assert (0.4.1)
psych (default: 2.2.2)
rake (12.0.0)
rdoc (default: 5.0.0)
test-unit (3.2.3)
xmlrpc (0.2.1)
➜  nokogiriprac
➜  nokogiriprac brew uninstal libxml2
Error: Refusing to uninstall /usr/local/Cellar/libxml2/2.9.4_4
because it is required by libxslt, which is currently installed.
You can override this and force removal with:
  brew uninstall --ignore-dependencies libxml2
➜  nokogiriprac brew uninstal libxslt
Uninstalling /usr/local/Cellar/libxslt/1.1.29... (147 files, 3MB)
➜  nokogiriprac brew uninstall libxml2
Uninstalling /usr/local/Cellar/libxml2/2.9.4_4... (281 files, 10.5MB)
➜  nokogiriprac brew list
autoconf    mecab-ipadic    python      sqlite      zsh-completions
gdbm        openssl     readline    swi-prolog
gmp     openssl@1.1 ruby        vim
libyaml     pcre        scheme48    wget
mecab       perl        sl      zsh
➜  nokogiriprac

さあはじめよう

はじめにみるべきは、これ。

概要が書いてあって全体像が掴みやすい。
どうやらNokogiriを使うには、Libxml2Libxsltっていうやつがいるらしい
xsltだからxmlとかhtmlとかを解析する系の何かだろう。
とりあえずそれをインストール

Libxml2,Libxsltインストール
➜  nokogiriprac brew install libxml2 libxslt
==> Downloading https://homebrew.bintray.com/bottles/libxml2-2.9.4_4.yosemite.bottle.tar.gz
Already downloaded: /Users/taka/Library/Caches/Homebrew/libxml2-2.9.4_4.yosemite.bottle.tar.gz
==> Pouring libxml2-2.9.4_4.yosemite.bottle.tar.gz
==> Caveats
This formula is keg-only, which means it was not symlinked into /usr/local,
because macOS already provides this software and installing another version in
parallel can cause all kinds of trouble.

If you need to have this software first in your PATH run:
  echo 'export PATH="/usr/local/opt/libxml2/bin:$PATH"' >> ~/.zshrc

For compilers to find this software you may need to set:
    LDFLAGS:  -L/usr/local/opt/libxml2/lib
    CPPFLAGS: -I/usr/local/opt/libxml2/include


If you need Python to find bindings for this keg-only formula, run:
  echo /usr/local/opt/libxml2/lib/python2.7/site-packages >> /usr/local/lib/python2.7/site-packages/libxml2.pth
  mkdir -p /Users/taka/Library/Python/2.7/lib/python/site-packages
  echo 'import site; site.addsitedir("/usr/local/lib/python2.7/site-packages")' >> /Users/taka/Library/Python/2.7/lib/python/site-packages/homebrew.pth
==> Summary
🍺  /usr/local/Cellar/libxml2/2.9.4_4: 281 files, 10.5MB
==> Downloading https://homebrew.bintray.com/bottles/libxslt-1.1.29.yosemite.bottle.tar.gz
Already downloaded: /Users/taka/Library/Caches/Homebrew/libxslt-1.1.29.yosemite.bottle.tar.gz
==> Pouring libxslt-1.1.29.yosemite.bottle.tar.gz
==> Caveats
To allow the nokogiri gem to link against this libxslt run:
  gem install nokogiri -- --with-xslt-dir=/usr/local/opt/libxslt

This formula is keg-only, which means it was not symlinked into /usr/local,
because macOS already provides this software and installing another version in
parallel can cause all kinds of trouble.

If you need to have this software first in your PATH run:
  echo 'export PATH="/usr/local/opt/libxslt/bin:$PATH"' >> ~/.zshrc

For compilers to find this software you may need to set:
    LDFLAGS:  -L/usr/local/opt/libxslt/lib
    CPPFLAGS: -I/usr/local/opt/libxslt/include


If you need Python to find bindings for this keg-only formula, run:
  echo /usr/local/opt/libxslt/lib/python2.7/site-packages >> /usr/local/lib/python2.7/site-packages/libxslt.pth
  mkdir -p /Users/taka/Library/Python/2.7/lib/python/site-packages
  echo 'import site; site.addsitedir("/usr/local/lib/python2.7/site-packages")' >> /Users/taka/Library/Python/2.7/lib/python/site-packages/homebrew.pth
==> Summary
🍺  /usr/local/Cellar/libxslt/1.1.29: 147 files, 3MB
➜  nokogiriprac brew link --force libxml2
Linking /usr/local/Cellar/libxml2/2.9.4_4... 21 symlinks created

If you need to have this software first in your PATH instead consider running:
  echo 'export PATH="/usr/local/opt/libxml2/bin:$PATH"' >> ~/.zshrc
➜  nokogiriprac brew link --force libxslt
Linking /usr/local/Cellar/libxslt/1.1.29... 22 symlinks created

If you need to have this software first in your PATH instead consider running:
  echo 'export PATH="/usr/local/opt/libxslt/bin:$PATH"' >> ~/.zshrc
➜  nokogiriprac
Nokogiriインストール
➜  nokogiriprac gem install nokogiri
Fetching: nokogiri-1.8.0.gem (100%)
Building native extensions.  This could take a while...
Successfully installed nokogiri-1.8.0
Parsing documentation for nokogiri-1.8.0
Installing ri documentation for nokogiri-1.8.0
Done installing documentation for nokogiri after 14 seconds
1 gem installed
➜  nokogiriprac gem list
確認
➜  nokogiriprac nokogiri -v
# Nokogiri (1.8.0)
    ---
    warnings: []
    nokogiri: 1.8.0
    ruby:
      version: 2.4.1
      platform: x86_64-darwin14
      description: ruby 2.4.1p111 (2017-03-22 revision 58053) [x86_64-darwin14]
      engine: ruby
    libxml:
      binding: extension
      source: packaged
      libxml2_path: "/usr/local/lib/ruby/gems/2.4.0/gems/nokogiri-1.8.0/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.4"
      libxslt_path: "/usr/local/lib/ruby/gems/2.4.0/gems/nokogiri-1.8.0/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.29"
      libxml2_patches:
      - 0001-Fix-comparison-with-root-node-in-xmlXPathCmpNodes.patch
      - 0002-Fix-XPointer-paths-beginning-with-range-to.patch
      - 0003-Disallow-namespace-nodes-in-XPointer-ranges.patch
      libxslt_patches:
      - 0001-Fix-heap-overread-in-xsltFormatNumberConversion.patch
      - 0002-Check-for-integer-overflow-in-xsltAddTextString.patch
      compiled: 2.9.4
      loaded: 2.9.4
➜  nokogiriprac

使ってみよう

試しにから出場選手名を取得してみる。

boatrace結果

require 'open-uri'

require 'nokogiri'

doc = Nokogiri::HTML(open("https://www.boatrace.jp/owpc/pc/race/raceresult?rno=12&jcd=01&hd=20170827"))

p doc.title

nodes = doc.xpath("//span[@class='is-fs18 is-fBold']")

nodes.each do |node| 
  p node.text.tr!(" ","")
end

出力結果

➜  nokogiriprac ruby xpath.rb
"結果|BOAT RACE オフィシャルウェブサイト"
"萩原秀人"
"古澤光紀"
"河村了"
"川上聡介"
"荒井輝年"
"青木玄太"
➜  nokogiriprac

といった感じでとりあえず使ってみた。
参考

0xC2A0の消えないスペース

私がちょっと悩んだとこを簡単に書いておく 半角スペースは、htmlで「&nbsp; 」とかくことがあるらしい。
しかしこれは、0x20の半角スペースとは、異なる物である。
詳しくは、c2a0とか、&nbsp;とかで調べてみてほしい。

はじめてのものづくり

この夏作ろうと思ってる物

この夏
ボートレースの競走データを蓄積する仕組み
を作ろうと思っている。

作ろうと思った理由

なぜこれを作ろうかと思ったかを簡単に説明する。
先日のブログでも言った、手を動かす、とりあえずやってみる活動の一環でなにか作ろうと思った。
自分の趣味に関連するものの方がより楽しんで製作できると思ったのでボートレース関連にした。
ボートレースは、

  • モータ
  • 選手
  • 水面の様子
  • 枠番
  • 気象条件(天気、潮の満ち引き、風、気温、湿度など)

などといった様々な要因によって勝敗が決まる。

つまり、過去のデータを持っていることに大きな意味がある。
実際にボートレース場で予想をするときも出走表というデータ集をみて予想する。

大分、先の話だが定年退職した後、ボートレース場の近くに住みボートレースを楽しみたいと考えているがその時にも役立つだろう。
また、機械学習を用いて予想したり、webやAndroidiOSアプリで簡単にそのデータにアクセスできるようにしたりとさらに広げていくことも考えている。


問題点

しかし製作にあたり問題点も存在する。

  1. 技術力不足
  2. 著作権など

主に以上の二つである。
一つ目の技術力不足は、周りの友人や書籍など恵まれた環境にあるため自分次第である。
問題は、二つ目で、webで調べるといろいろ出てくるが一般の社会と関わっていく以上周りとの利害関係も意識しないといけない。
とりあえず個人的利用は、著作権侵害に当たらないっぽいので、公開する時にもっと詳しく調べることにして、製作をはじめていこうと思う。
これを期にそういった面も考えるきっかけにしたい。


さてどうしよう

webで調べているとどうやら作ろうとしているのは、クローラと呼ばれる物ということがわかった。

クローラ(Crawler)とは、ウェブ上の文書や画像などを周期的に取得し、自動的にデータベース化するプログラムである。「ボット(Bot)」、「スパイダー」、「ロボット」などとも呼ばれる。–Wikipediaより

クローラ、スクレイピングといった手がかりを元にとりあえずboatraceの公式サイト からデータを取り出すところを作ろうと思う。

読んでくれてる人にお願い

もしかしたら文章をみてばれてるかもしれませんが、完全に理解してない言葉も使ってしまっています。(例えば機械学習とか)
なので、使い方おかしいとかあれば、ぜひコメントで教えていただきたいです。
よろしくお願いします。