社内SEの話

日々起きたことの記録用

【Poweshell】Webからファイルを一括ダウンロードする

↓プログラミングで副業を考えたらこちら↓

Powershell,Downloader,Invoke-WebRequest

コンソールからファイルをダウンロードするには

Webに公開されているファイルを一括でダウンロードするコマンドを紹介します。

PS1ファイルを作ってそこからダウンロードしてもいいのですが、頻繁にあるわけではないので、コンソールだけで解決させます。

今回は最小で2行で解決できます。

注意

大量のファイルを一括でダウンロードしようとするとサーバー側に負荷がかかるので、注意しましょう。

またサイトによってはダウンロードを禁止している場合もあります。

利用規約をよく読んでからダウンロードしましょう。

URLを配列で指定

$links = @("http://image/img01.jpg"
,"http://image/images.jpg"
,"http://image/gazou.jpg")

ファイルをダウンロードするコマンド

Invoke-WebRequest URL -OutFile ファイル名

ファイル名の取得

配列から抽出した変数をSplitで分割し、配列の最後をファイル名にしています。

$link.Split('/')[-1]

配列のインデックスで-1にすれば最後を指定できます。

ダウンロードしたいフォルダでPowershellを起動

ForEachでダウンロード

foreach ($link in $links){
    Invoke-WebRequest $link -OutFile $link.Split('/')[-1]
}

ワンライナーで実行(パイプ)

$links | ForEach-Object { Invoke-WebRequest $_ -OutFile $_.Split('/')[-1] }

ワンライナーで実行(省コード化)

$links.ForEach({Invoke-WebRequest $_ -OutFile $_.Split('/')[-1]})

ForEachはパイプオブジェクトの他にメソッドでも用意されています。

これは知っておくと更に短いコードで記述ができるので、覚えておくと活躍の機会があります。

ワンライナーで実行(さらに省コード化)

$links | % {iwr $_ -o  $_.Split('/')[-1] }

iwrInvoke-WebRequestエイリアスです。
またForEach-Objectエイリアス%なので可読性を下げて省コード化させる場合はパイプでつなげたForEach-Objectのほうがコード自体は短くなります

ファイル名をインデックスで保存する場合

$links.ForEach({Invoke-WebRequest $_ -OutFile "$($links.IndexOf($_)).jpg" })

インデックス番号を取得するには $配列.IndexOf($変数)とするとループした時の現在の番号を取得できます。

こうすると0.jpg、1.jpgとファイルが保存されます。

更に0埋めしたい場合は$links.IndexOf($_).ToString("000")としてあげます

$links.ForEach({ Invoke-WebRequest $_ -OutFile "$($links.IndexOf($_).ToString("000")).jpg" })

001.jpgとファイル名が連番で保存されます。