なか日記

一度きりの人生、楽しく生きよう。

PowerShell:だるやなぎ様が書いた記事の数を数えてみた

だるやなぎ様(@)が面白そうなことしてたのでPowerShellに書き換えてみました。

手頃なアイキャッチ画像がなかったので、だるやなぎ様のを使わせて頂きました。

書き換えたのがこれ*1。 もっとPowerShellらしい書き方があるんでしょうが、今のラベルでは仕方ありません。

$date = New-Object DateTime(2007,4,1)
$list = @()

# 2008年まではシステムが旧かったので、
# http://www.forest.impress.co.jp/article/ 以下に過去ログがあるらしい
while ($date -le (New-Object DateTime(2008,12,1))){
    $list += "http://www.forest.impress.co.jp/article/{0}.html" -f $date.ToString("yyyyMM")
    $date = $date.AddMonths(1)
} 

# おニューなシステムの過去ログの URL を足す
while ($date -le ([DateTime]::Now)){

    $list += "http://www.forest.impress.co.jp/backno/top/index{0}.html" -f $date.ToString("yyyyMM")
    $date = $date.AddMonths(1)
}

# システム変更時に UTF-8 にすべきって主張しておけばよかった
$encoding = [System.Text.Encoding]::GetEncoding("Shift_JIS")

# だるやなぎ様の記事を保持しておくリスト
$article=@()

$webClient = New-Object System.Net.WebClient
$webClient.Encoding = $encoding

# 過去ログページの解析
# 全部拾いに行っちゃうと叱られるといけないので、今月分だけ
$list[-1] | %{
    $backNo = $webClient.DownloadString($_)

    $regex=[regex]"""/[^""]+\.html"""
    $regex.Matches($backNo) |
    #ダイジェストニュース、アップデート、バックナンバーは読み飛ばす
    ?{ $_ -notmatch "digest" } | 
    ?{ $_ -notmatch "update" } | 
    ?{ $_ -notmatch "backno" } | %{
        $url="http://www.forest.impress.co.jp"+$_.value -replace '"',''
        $contents = $webClient.DownloadString($url)
        
        # リンク切れとかあるかもしれん
        trap { Write-Host "例外発生:$url"; continue }

        # ニュースやレビュー記事の場合、著者名を拾う
        if($contents -match "柳 英俊"){ $article += $url }
    }
}

# 重複している記事があるので重複を取り除く
$result = $article | Sort-Object -Unique

#たくさん記事を書いた翌々月は奢ってもらおう
$result
Write-Host $result.Count"件の記事が見つかりました。"

おお、PowerShellではDistinct(Linq)使えんやん・・・とか思ってしまいましたが、別の方法がありました。頭の切り替えがいりますなぇ。

*1: 全記事見に行くと時間がかかるので「$list[-1]」とすることで最終月(今月)の記事のみ解析する様にしてます