2012年5月19日土曜日

Powershellで青空文庫から欲しい作品を一括取得する

Awk好き技術者の書いたPowerShell

背景

 最近は少し大人になったのか日本の古い小説を読みたいなと思うことがあります。中学高校時代にはもちろんある程度は読んでいたのですが、 元来国語が苦手だったので以降一切読んでませんでした。
 ということで、青空文庫からある作者の作品をダウンロードするスクリプトを書いてみました。
param( [Parameter(Mandatory=$true)][String]$author)
$aozoraListExt_SJIS_URI= "http://www.aozora.gr.jp/index_pages/list_person_all_extended.zip"

function Unzip-Files([string]$zip,[string]$dest)
{
    $shellApplication = new-object -com shell.application 
    $zipPackage = $shellApplication.NameSpace($zip) 
    $destinationFolder = $shellApplication.NameSpace($dest) 

    # CopyHere vOptions Flag # 4 - Do not display a progress dialog box. 
    # 16 - Respond with "Yes to All" for any dialog box that is displayed. 
    $destinationFolder.CopyHere($zipPackage.Items(),20) #zipファイルを指定のフォルダに解凍
}

function Download-AozoraFile([string]$uri)
{
    $zipfile = [System.IO.Path]::GetTempFileName() |
        Rename-Item -NewName { $_ -replace 'tmp$', 'zip' } –PassThru
        #拡張子がzipでないとshell.applicationでエラーになるため拡張子変更
    $unzipDestination = $zipfile -replace '.zip',''
    mkdir $unzipDestination >$null

    (New-Object System.Net.WebClient).DownloadFile($uri,$zipfile)
    Unzip-Files $zipfile $unzipDestination
    gci $unzipDestination  |
        %{ cat $_.PSPath  -encoding String } #SJISからUTF8に変換

    rm -r $zipfile,$unzipDestination >$null
}

mkdir $author >$null 2>&1 #作者名でフォルダ作成
"#全作品リスト取得中"
Download-AozoraFile $aozoraListExt_SJIS_URI|
    convertFrom-csv | #作品リストの読み込み
    ? {($_.姓+$_.名 -eq $author) -and ($_.テキストファイルURL -match "^http.*\.zip$")} |
    % {
        $outputFile=$author + "\" + $_.作品名 + ".txt"
        Download-AozoraFile $_.テキストファイルURL > $outputFile
        $outputFile
    }

解説

  • 青空文庫のサイトには全作品に関するcsvがダウンロードできるので、そのファイルから作者名で作品を絞込み、該当するテキスト版の作品ファイルをそれぞれダウンロードしています。
  • Powershellにはzip/unzipの機能がないために、Windowsの機能を使用しました。なんでないんでしょうね。
  • PowershellのconvertFrom-csvやimport-csvの制約として、文字コードがUTF8前提となっているのでSJISからコード変換しています。
  • 一時ファイルは[System.IO.Path]::GetTempFileName()で作成できましたが、一時ディレクトリは自分で名前を作りました。なにかよい方法がないかな。
  • 書き捨てのスクリプトなので異常系など考えていませんので悪しからず。


感想

 苦戦したものの、メインのところはなんとか頑張ってパイプラインで処理するようにできました。(作品リスト取得以降は絞り込みやデータのダウンロードなどすべて並列に処理するので結構早いです。
 今回は作者名で作品のtxt版を一括ダウンロードしましたが、青空文庫の作品リストには作品や著者のカナや英名、底本に関する情報、入力者や公開日や作者の生年没年なども記載されています(もちろんXHTML版のURIもあり)ので、色々な使い方があると思います。
 あとOut-GridViewコマンドレット(PS3では拡張されているらしい)を使って作品一覧を表示したり、Write-Progressコマンドレットでダウンロード状況を表示したりできますが、いまひとつパッとした使い方が思いつかなかったので止めておきました。

0 件のコメント:

コメントを投稿