いろいろなデジカメで撮ったままのサンプル画像を集める

各社・各機種のデジカメで撮った写真を資料として集める必要があって、それ用のスクリプトを書いてみた。それが下のもの。

デジカメ Watchの「新製品レビュー」のバックナンバーを辿って、画像へのリンクを抽出する。
このままだと、本来欲しいもの以外の画像(デジカメの外観など)も含んでしまうが…それは画像をダウンロードしてきてからファイルサイズで選別すれば良いかな。
(おおよそ、500KB未満の画像は画面での表示用に加工済みであると見なせる)

import java.io.BufferedWriter
import java.io.FileWriter
import java.net.URL
import scala.io.Source

val writer = new BufferedWriter(new FileWriter("urls.txt"))
try {
    findAll { url =>
        writer.write(url.toString)
        writer.newLine
    }
} finally {
    writer.close
}
exit

// 以下は関数定義

def findAll(callback: URL => Unit) {
    for (year <- 2004 to 2010) {
        val url = new URL("http://dc.watch.impress.co.jp/docs/review/index%d.html".format(year))
        val html = Source.fromURL(url, "MS932").mkString
        val rTitle = """<div class="title">\s*<a href="([^"]+)">([^<]+)""".r
        val matches = rTitle.findAllIn(html)
        for (m <- matches) {
            var url :: title :: _ = matches.subgroups
            title = """(】)\s+""".r.replaceAllIn(title.trim, "$1")
            if (title contains "【新製品レビュー】") {
                println("=" * 80)
                println(title)
                println(url)
                findInArticle(new URL(url), callback)
            }
        }
    }
}

def findInArticle(url: URL, callback: URL => Unit) {
    val html = Source.fromURL(url, "MS932").mkString
    val rLink = """<a href="([^"]+)"[^>]*><(img|IMG) """.r
    val matches = rLink.findAllIn(html)
    for (m <- matches) {
        val s :: _ = matches.subgroups
        if (s endsWith ".html") {
            val imgPageUrl = new URL(url, s)
            println("- " + imgPageUrl)
            findInImgPage(imgPageUrl, callback)
        }
    }
}

def findInImgPage(url: URL, callback: URL => Unit) {
    val html = Source.fromURL(url, "MS932").mkString
    val rImg = "<(?:img|IMG)(?: id=\"main_image\")? (?:src|SRC)=\"([^\"]+\\.(?:jpg|JPG))\"".r
    val matches = rImg.findAllIn(html)
    for (m <- matches) {
        val s :: _ = matches.subgroups
        val imgUrl = new URL(url, s)
        println("  - " + imgUrl)
        callback(imgUrl)
    }
}