Nokogiriを使ってみる

あるサイトでは、電子書籍で発売した漫画の一覧を観ることができる。
そのサイトを見るのが日課だったのだけど、正直毎日確認するのが面倒くさいと思ってた。
そこで、いい感じに一覧を取得できないか調べたところ、いわゆるスクレイピングなどでよく使われるNokogiriを使ってみることにした。

実際に書いたコードはこちら。

require 'yaml'
require 'open-uri'
require 'nokogiri'

list = YAML.load_file("list.yaml")

list['siteurl'].each do | url |
  doc = Nokogiri::HTML(open(url).read)
  puts "=== Info === "
  p doc.title
  doc.xpath('//h2[@class="entry-title"]').each do | node |
    puts node.text
  end
end

見て分かるように大変シンプルなコードで簡単に取得できた。

取得できた情報はこんな感じ。

=== Info ===
絢爛たるグランドセーヌ 第01-06巻 [Kenrantaru Grande Seene vol 01-06]
Ultraman 第01-08巻
ディメンションW 第01-10巻 [Dimension W vol 01-10]
ねじ巻き精霊戦記 天鏡のアルデラミン 第01巻 [Nejimaki Seirei Senki – Tenkyou no Alderamin vol 01]
生徒会副会長矢上さゆりは頑張っている! 第01巻 [Seitokai Osayagami Sayuri wa Ganbatte Iru! vol 01]
黒崎くんの言いなりになんてならない 第01-07巻 [Kurosaki-kun no Iinari ni Nante Naranai vol 01-07]
ソードアート・オンライン プログレッシブ 第01-05巻 [Sword Art Online – Progressive vol 01-05]
木根さんの1人でキネマ 第01-02巻 [Kine-san no 1-ri de Cinema vol 01-02]

頻繁にアクセスしてバンされたら嫌だなぁと思って、サイトURLはyamlでリストを管理することにした。
最初ソースを全部取得するのはすぐにできたのだけど、その後にどのように書いたら特定のタグの値を取得できるかがわからなかった。
このソースを見て分かるように、xpathというメソッドで指定している。
pathは”//”で指定して書いてくので、ちょっと独特だなと感じたけど、理解すればそこまででも無い。
このままだとサイトにアクセスしてるのと同じレベルなので、次はSlack通知するようにしたい。

atcoder041のABCを解いた

いつもやってるatcoderの問題シリーズ。

今回は最新のabc041を解いてきた。

問題はこちら。

A問題の回答

s, i = STDIN.read.split(?\n)
i = i.to_i - 1
puts s[i]

改行コード区切りで縦に並んだ文字列をそれぞれ変数に入れる。
iという数字を整数の型にセットして、1引く。
文字列sのi番目を表示させる。

B問題の回答

A, B, C = STDIN.gets.split(" ").map(&:to_i)
X = A * B * C
Y = (10**9) + 7
puts X % Y

スペース区切りで変数にセットし、整数の型にセットする。
AとBとCを積算する。
Yは指定された数字10の9乗足す7を計算している。
そして最後にX割るYの余りを出している。

C問題の回答

N = STDIN.read.split("\n").map(&:to_s)
hash = {}
i = 1.to_i
N[1].split(/ /).each do | val |
  hash[i] = val.to_i
  i = i + 1
end
 
A = Hash[ hash.sort_by { | _, v | -v } ]
 
A.map { | key, value | puts key }

改行区切りで縦に変数に文字列としてセットする。
hashを宣言する。
iに1を整数としてセットする。
変数Nの2行目の値をスペース区切りで、hashにセットする。その際にkeyは整数で1から足していく。
hash.sort_byを使って、valueをsortする。※配列をソートすると、順番が変わるのでkeyを並べることはできない。結果は123のようになってしまう。
最後にhashのkeyだけを取り出している。

いつもこの手の文字列の変数セットに悩む。

S
A1,A2,A3... An

このような標準入力があって、Anを配列に入れたい場合はみなさんどうしているのだろうか。
上記方法以外になにかあるのだろうか。なんかこう1行目だけを無視して、2行目をいきなりhashに入れるみたいなことができないのだろうか。
私は分からずに、いつも一旦変数に入れて、string関数で抽出するようにしている。最近はこれが定着しつつあるけど正しいのかわからない。

来週のRubyの勉強会で聞いてみよう。
もし教えたくてムズムズした人がいたら是非教えてほしいです。

真剣にOasobiなgemを作った

こんにちは、いなむーです。

最近、会社でRubyでクライアントコマンドなツールを作るにはThorを使うと良いというのを教えていただきました。
そこで、せっかくなのでThorを使ったクライアントコマンドツールを作りたいと思って、早速作ってみました。
それが、こちら。

このgemは、Macのhomebrewでインストールできるor元々インストールされているコマンドをまとめたものです。
なので、Macでhomebrewが使えることが前提のツールです。
slコマンドとかご存知の方も多いと思いますが、その辺を一つ一つインストールしていると何が入っていたか忘れると思います。
その辺のおもしろコマンドシリーズを一括でインストールしたり、アンインストールできるようにしてしまおうと思って作ったgemです。

$ bundle exec bin/oasobi install

こんな感じでインストールができます。

$ bundle exec bin/oasobi help

使えるコマンド一覧が表示されます。

$ bundle exec bin/oasobi sl

slが走ります。

正直中身は大したものではありません。
※インストールしてしまえば、そのままコマンド打った方が色々できますし…^^;

ただ、私がここでやりたかったのは
– gemの作り方を知る
– yamlでリスト管理する
– Thorでクライアントコマンド的に使う
ということでしたので、そのへんが一通りできたので目的は達成できたかなと思います。

これから実用的なツールを作るにあたって、良い勉強になったので色々作っていきたいです。

以上。