mk-mode BLOG

このブログは自作の自宅サーバに構築した Debian GNU/Linux で運用しています。
PC・サーバ構築等の話題を中心に公開しております。(クローンサイト: GitHub Pages

ブログ開設日2009-01-05
サーバ連続稼働時間
Reading...
Page View 合計
Reading...
今日
Reading...
昨日
Reading...

Ruby - Web サイト(HTML)差異チェックスクリプト!

[ プログラミング ] [ Ruby ]

こんばんは。

以前、 Web サイト(HTML) の前回取得した HTML との差異をチェックする簡単な Bash スクリプトを紹介しました。

今回は Ruby で作成してみました。(紹介するほどのものでもありませんが)

当方、何かと Ruby で処理している一連の流れがあるのですが、その中で HTML 差異チェックだけ Bash に任せていたのが気になっていたもので。

0. 前提条件

  • Linux Mint 17(64bit), CentOS 7.0(64bit), 6.6(32bit) での作業を想定。
  • Ruby 2.1.5-p273 での作業を想定。

1. Ruby スクリプト作成

以下のような簡単な Ruby スクリプトを作成。

  • エンコーディングは “UTF-8” に統一。
  • 一応ボットになるので、ユーザエージェントをその旨が分かるように設定。
    また、何らかの理由でチェック対象 Web サイトに迷惑がかかるようなことが発生した場合に連絡が取れるようメールアドレスも記載している。
  • 保存している HTML と新たに取得した HTML を比較し、差異があれば新たに取得した HTML を保存用に退避する。
    さらに、退避した HTML を過去遡って確認できるよう、タイムスタンプ付ファイル名でも保存する。
check_html.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#! /usr/local/bin/ruby
# coding: utf-8
#= Checking HTML difference
#
# date          name            version
# 2014.12.11    mk-mode         1.00 新規作成
#
# Copyright(C) 2014 mk-mode.com All Rights Reserved.
#---------------------------------------------------------------------------------
# 引数 : なし
#---------------------------------------------------------------------------------
#++
require 'kconv'
require 'open-uri'
require 'openssl'
require 'timeout'

class CheckHtml
  # クラス定数
  URL     = "http://www.********.com/********/"     # <= チェック対象ページの URL
  DIR     = "/path/to/data"                         # <= 取得 HTML 格納ディレクトリ
  FILE_L  = "#{DIR}/last.html"                      # <= 前回取得 HTML
  FILE_C  = "#{DIR}/current.html"                   # <= 今回取得 HTML
  TIMEOUT = 15                                      # <= タイムアウト設定(単位:秒)
  UA      = "mk-mode Bot (Ruby/#{RUBY_VERSION}, Administrator: ********@********.com)"
                                                    # <= ユーザエージェント

  # 主処理
  def exec
    # 前回取得 HTML
    read_html_last

    # 今回取得 HTML
    get_html_current

    # 今回取得 HTML ファイル保存
    save_html_current

    # 今回取得 HTML == 前回取得 HTML なら終了
    return if @html_c == @html_l

    # 今回取得 HTML を前回取得 HTML としてファイル保存
    save_html_last

    # 今回取得 HTML をタイムスタンプ付ファイル名(YYMMDD_HHMMSS.html)としても保存
    save_html_timestamp
  rescue => e
    $stderr.puts "[#{e.class}] #{e.message}"
    e.backtrace.each{ |bt| $stderr.puts "\t#{bt}" }
    exit 1
  end

private

  # 前回取得 HTML
  def read_html_last
    @html_l = File.exists?(FILE_L) ? File.open(FILE_L, "r").read.chomp : ""
  rescue => e
    raise
  end

  # 今回取得 HTML
  def get_html_current
    timeout(TIMEOUT) do
      @html_c = open(
        URL,
        {"User-Agent" => UA, :ssl_verify_mode => OpenSSL::SSL::VERIFY_NONE}
      ) do |f|
        f.read
      end.chomp.toutf8
    end
  rescue => e
    raise
  end

  # 今回取得 HTML ファイル保存
  def save_html_current
    File.open(FILE_C, "w") { |f| f.puts @html_c }
  rescue => e
    raise
  end

  # 今回取得 HTML を前回取得 HTML としてファイル保存
  def save_html_last
    File.open(FILE_L, "w") { |f| f.puts @html_c }
  rescue => e
    raise
  end

  # 今回取得 HTML をタイムスタンプ付ファイル名(YYMMDD_HHMMSS.html)としても保存
  def save_html_timestamp
    file_name = "#{DIR}/#{Time.now.strftime("%y%m%d_%H%M%S")}.html"
    File.open(file_name, "w") { |f| f.puts @html_c }
  rescue => e
    raise
  end
end

# 実行
CheckHtml.new.exec if __FILE__ == $0

2. cron 登録

以下のように cron 登録。
(以下は5分ごとにチェックする設定)

/etc/cron.d/check_html
1
*/5 * * * * root /path/to/check_html.rb > /dev/null 2>&1

3. 動作確認

cron により定期的にチェックされ、HTML に差異があればタイムスタンプ付きのファイルが保存されることを確認する。


当方の場合、Web スクレイピングしようと考えた場合に、実際どのような HTML が発行される可能性があるのかを事前に調査するために使用しています。

以上。

Comments