適材適所

PowerShellやVBAなどプログラミング系の話多めで

【PowerShell】ウェブの画像を一括ダウンロードする【スクレイピング】

このサイトの画像、癒される~。

自分のパソコンに保存しておきたい!!

でもこんなにたくさんの画像を一個一個ダウンロードするの大変だ・・・

そんなときはPowerShellの出番です。

PowerShellを使ってウェブ上の画像を一括でダウンロードする方法を紹介いたします。

Invoke-WebRequestコマンドレットを使う

Invoke-WebRequestコマンドレットを使うことで簡単にウェブ上の画像をダウンロードすることができます。

Invoke-WebRequestコマンドレットのoutFileパラメータを使うことで結果をファイルに保存、つまりダウンロードすることができます。

こちらがそのワンライナー。

 
(Invoke-WebRequest https://www.irasutoya.com/).images|foreach{Invoke-WebRequest $_.src -outFile .\$($_.src.split('/')[-1])}

一度、対象のウェブサイトに対してInvoke-WebRequestを実行してデータを読み取ります。返ってくるのはMicrosoft.PowerShell.Commands.HtmlWebResponseObject型です。

その中にあるimagesプロパティが画像のurlになります。

f:id:shinmai_papa:20210911142949p:plain

このimagesプロパティの中身はPSCustomObjectです。そのプロパティの一つであるsrcが画像のURLになります。srcプロパティを対象にforeachを使って再度、Invoke-WebRequestを実行しています。もちろんoutFileパラメータを忘れてはいけません。

f:id:shinmai_papa:20210911142956p:plain

関数にしてみる

いちいち画像の保存先のフォルダを作成したりするのが面倒だったので、関数化してみました。対象のURLと画像の保存先のフォルダ名を指定します。フォルダが指定されなかった場合は、処理時間とURLのホスト名を組み合わせた名前のフォルダをデスクトップに勝手に作成します。

参考

 
function Get-Image
{
    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true,Position=0,HelpMessage="画像取得先のURLを入れてください。")]
        [string]$url,
        [Parameter(Position=1)][string]$Directory
    )
    begin
    {
        if($Directory -eq ''){
            $folder=-join((Get-Date -Format 'yyyyMMddhhmmss'),"_",([uri]$url).host)
            $desktop=[System.Environment]::GetFolderPath("Desktop")
            $Directory=New-Item $(join-path $desktop $folder) -ItemType Directory
        }elseif(!(Test-Path -Path $Directory))
        {
            New-Item -Path $Directory -ItemType Directory -Force
        }
    }
    process
    {
        (Invoke-WebRequest $url).images|foreach{Invoke-WebRequest $_.src -outFile "$(join-path  $Directory $($_.src.split('/')[-1]))" }
    }
    end{}
}

注意点

サイトによってはスクレイピング対策として、一般的なウェブブラウザからのアクセスではないということでエラーになる場合があります。

エラー処理については全く組み込んでないのであしからず。

すべて自己責任で使用をお願いします。

終わりに

Invoke-WebRequestコマンドレットを使って画像をダウンロードする方法を紹介しました。ちまちま画像をダウンロードするのは大変なので、必要に応じて使ってみてください。

Invoke-WebRequestコマンドレットはスクレイピングの強い味方です。しかし先ほども述べた通り、エラーになる場合もありますのでその辺りご注意ください。

また、スクレイピングという行為自体についても賛否ありますので、ご使用の際はくれぐれも自己責任でお願いします。

というわけで、ここまでお読みいただき、ありがとうございました。

[参考]VBAで同じことをやった記事

www.tekizai.net