あーるPG - 社会人のデジタル生活

日曜プログラマになろうかなーと思った30代理系社会人の、キャリアアップや趣味(特にデジタル情報)の記録。らーめんとビールが好き。

Webサイトの更新を監視してメール通知する

必要に迫られて、特定の監視サイトを監視するスクリプトを作りました。
環境はLinux。面倒を省くため、system()でLinuxコマンドをバシバシ呼び出すし、定期実行はcronに任せます。

サイトの一部を抽出することを”スクレイピング”というそうです。
ただ、Webで儲けようとする方々の間では、”スクレイピング”=悪質なコピペサイトということになってるようです。
http://www.suzukikenichi.com/blog/best-ways-to-beat-scrapers-at-the-moment/
確かに人気サイトから情報を自動で集めて公開していれば人気も出るかもしれませんね。
軋轢を生まないよう十分注意しましょう。

#!/usr/bin/ruby
require 'fileutils'
$KCODE = "EUC"

#特定のURLからソースを取ってきて、過去のものと比較して更新があったらメールするスクリプト

$target_url       = "http://headlines.yahoo.co.jp/hl"
$current_dir      = "~/bin/scraping/"    #crontabに登録する予定なので.
$backup_filename  = "backup.txt"
$diff_filename    = "diff.txt"
$header_filename  = "head.txt"
$log_filename     = "log.txt"
$temp_filename    = "temp.txt"
$to_mailaddress   = "hoge@hoge.com"      #メール送付先.
$mail_subject     = "yahoo_scraping_news"
$log_maxsize      = (10 * 1024 * 1024)    #毎分呼ぶと、1年で1.6MBぐらい.


#----------------------------------

#・Current Dirを変える.
FileUtils.cd($current_dir)

#・ファイルが足りない場合、作成する.
if not (File.exist?($header_filename)) then
    File.open($header_filename, "w").write("").close
end

#・エラーログファイルを用意
if (File.exist?($log_filename) and File.size($log_filename) > $log_maxsize) then
    # filesizeが大きくなりすぎたら新規作成.
    log_fd = File.open($log_filename, "w", 0644)
else
    log_fd = File.open($log_filename, File::WRONLY|File::CREAT|File::APPEND, 0644)
end
log_fd.write("%s " %[Time.now.strftime("%Y/%m/%d %X")]) #nowの出力は日本人に読みづらい

#・特定のURLからソースを取ってくる.
cmd = "wget %s" % [$target_url]
system(cmd)
# エラー処理.
if not (File.exist?(File.basename($target_url)))then
    exit
else 
    log_fd.write("get ")
end

#・ターゲットファイルの重要部分だけ切り出す
writeflag = false
output = File.open($temp_filename, "w", 0644)
File.read(File.basename($target_url)).each{|f|
    # 書き込み終了.
    if f =~ /<!-- /list_ya -->/ then
        writeflag = false
    end

    # 書き込み中.
    if writeflag == true then 
        f.gsub!(/\<[^\>]+\>/,'')
        output.write(f)
    end
    
    # 書き込み開始.
    if f =~ /<!-- list_ya -->/ then
        writeflag = true
    end
}
output.close #ちゃんとcloseしましょう.

#・ターゲットを置き換え
FileUtils.mv($temp_filename, File.basename($target_url))

#・バックアップファイルが無ければ、そのままコピーする.
if (File.exist?($backup_filename))then
    log_fd.write("exist ")

    # ・過去のものと比較する.
    if (! FileUtils.cmp(File.basename($target_url), $backup_filename)) then
        log_fd.write("diff ")
        # ・更新があったらdiffを取ってメールする.
        cmd = "diff -a -B -b -w %s %s > %s" % [$backup_filename, File.basename($target_url), $diff_filename]
        system(cmd)
        
        cmd = "cat %s %s|mail -s \"%s\" %s" % [$header_filename, $diff_filename, $mail_subject, $to_mailaddress]
        system(cmd)
        
    end
end

# ・バックアップファイルを上書き.
FileUtils.mv(File.basename($target_url), $backup_filename)

log_fd.write("\n")