東京に設置したPCで録画したファイルをIISでWebサーバ立てて、wgetでまとめてダウンロードしようとしたら日本語ファイル名が--restrict-file-name=nocontrolを指定しても文字化けしてしまう。--restrict-file-name=asciiならURLエンコードされたままのファイル名になるが、日本語1文字が9バイト(%EF%BC%9Cなど)になるのでサブタイトルなどが含まれる番組名がファイル名に含まれているとファイル名の最大文字数制限である255バイト÷9バイト=28文字を簡単に超えてしまって保存できない。
てな訳でwgetでダウンロードする要領で、--spiderを付けて実際にはダウンロードしないようにして、-ndで勝手に保存先ディレクトリも作らないようにして、-Sでhttpヘッダを出力して更新日時を確認出来るようにして、これらの出力を-oで一時ファイルに保存し、FOR文で順次読み込みながら処理するようにしてみた。
「--」で始まる行からURLを取得、「 Last-Modified: 」で始まる行から更新日時を取得して月を数字表記に変換、「Removing 」で始まる行からファイル名を取得してnkfでURLエンコードを解除、index.htmlならダウンロードしない、historyディレクトリの同名ファイルの更新日時が同じならダウンロードしない、wgetでURLからダウンロード、touchで更新日時を書き換え、URLエンコードを解除したファイル名でdownloadディレクトリに保存、historyディレクトリに同じファイル名、更新日時で0バイトのファイルを作成。これを繰り返す。
@ECHO OFF IF NOT EXIST download MKDIR download IF NOT EXIST history MKDIR history wget -o sample.log --spider -S -nd -r -l 1 -np --restrict-file-name=ascii http://sample.com/ FOR /F "usebackq delims=" %%I IN (sample.log) DO ( SET LN="%%~I" CALL :SUB ) EXIT /B :SUB SET LN="%LN:"=%" IF "%LN:~1,2%"=="--" SET URL="%LN:~26,-1%" IF "%LN:~1,17%"==" Last-Modified: " SET LM="%LN:~30,4%%LN:~26,3%%LN:~23,2%%LN:~35,2%%LN:~38,2%.%LN:~41,2%" IF NOT "%LN:~1,9%"=="Removing " EXIT /B IF "%LN:~10,-2%"=="index.html" EXIT /B ECHO "%LN:~10,-2%"> sample.tmp FOR /F "usebackq eol=* delims=" %%I IN (`^"nkf --url-input sample.tmp^"`) DO SET FN="%%~I" FOR %%I IN ("Jan=01" "Feb=02" "Mar=03" "Apr=04" "May=05" "Jun=06" "Jul=07" "Aug=08" "Sep=09" "Oct=10" "Nov=11" "Dec=12") DO CALL SET LM=%%LM:%%~I%% FOR %%I IN ("history\%FN:~1,-1%") DO IF "%%~tI"=="%LM:~1,4%/%LM:~5,2%/%LM:~7,2% %LM:~9,2%:%LM:~11,2%" EXIT /B ECHO %FN% wget -O sample.tmp %URL% IF ERRORLEVEL 1 EXIT /B touch -t %LM:~1,-1% sample.tmp MOVE /Y sample.tmp "download\%FN:~1,-1%" touch -t %LM:~1,-1% "history\%FN:~1,-1%" EXIT /B
Last-ModifiedじゃなくDateしか返さないとかLast-Modifiedのフォーマットが違うWebサーバの場合は合わせて書き換えてやらないとダメかも。あと、更新日時が世界標準時で日本標準時じゃないから9時間ずれる件とか、バッチファイルで取得できる更新日時には秒が含まれないので無視してる件とか、ホスト側のディレクトリ階層を再現したい場合はどうするかとか、色々手直ししてやるとより快適に使えるかも知れない。
とりあえず、自分が使いやすいように手直ししたwgetsub v0.0.8を作ってみた。