すごいPowerShell WEBスクレイピングが簡単!

Windows PowerShell

Windows PowerShell

すごいPowerShell

PowerShellとは

2023年11月、PowerShellスクリプトでWEBスクレイピングをやってみました。PowerShellは、ちょっと癖がありますけどすごく強力です。

PowerShellは、Microsoftが開発したスクリプト言語です。とほほのPowerShell入門サイトに解説があります。

【参考】とほほのPowerShell入門

【参考】とほほのPowerShell入門

 

PowerShellでは、利用可能なコマンドのことをコマンドレット(cmdlet)と呼びます。コマンドレットは、「動詞-名詞」という命名規則になっています。例えば、「Get-Item」というように「どうする-何を」という形式になっているため慣れれば理解しやすいです。

PowerShellのバージョン確認

Windowsのスタートメニューから統合開発環境「PowerShell ISE」を起動します。

PowerShell

PowerShell

コマンドラインから「$PSVersionTable」と入力すると、バージョンテーブルを表示します。

PowerShell Version

PowerShell Version

「$PSVersionTable.PSVersion」と入力すると、バージョン番号のみを表示します。


PS E:\> $PSVersionTable

Name                           Value                                                                   
----                           -----                                                                   
PSVersion                      5.1.19041.3693                                                          
PSEdition                      Desktop                                                                 
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}                                                 
BuildVersion                   10.0.19041.3693                                                         
CLRVersion                     4.0.30319.42000                                                         
WSManStackVersion              3.0                                                                     
PSRemotingProtocolVersion      2.3                                                                     
SerializationVersion           1.1.0.1                                                                 


PS E:\> $PSVersionTable.PSVersion

Major  Minor  Build  Revision
-----  -----  -----  --------
5      1      19041  3693    



PS E:\> 

統合開発環境「PowerShell ISE」

統合開発環境「PowerShell ISE」(Windows PowerShell Integrated Scripting Environment )は、Windows PowerShellのスクリプト作成から実行、デバッグを行うためのツールです。

Windows PowerShell ISE

Windows PowerShell ISE

左下段に実行ウィンドウ、右側にコマンドウィンドウ、左上段にスクリプトウィンドウがあります。

  • 実行ウィンドウは、コマンドレットを入力して実行して実行結果を表示します。
  • コマンドウィンドウは、各コマンドレットのヘルプや引数入力フォームを表示することができます。
  • スクリプトウィンドウは、スクリプトを入力します。上部の実行ボタン(▶)を押すことで実行できます。

PowerShellの簡単なスクリプト

WEBスクレイピングとは

WEBスクレイピングとは、WEBサイトから特定の情報を自動的に抽出することです。

PowerShellでは、Invoke-WebRequestコマンドレットで簡単にWEBページにアクセスしてHTMLをパースすることができます。

プログラム仕様

簡単な例として 「bit目次の索引」からTITLEタグを抽出してみます。

このサイトには、3つの索引(題名、著者、単語)があります。
それぞれのHTMLは、”indexttl.html”、”indexaut.html”、”indexkey.html”です。

このサイトから、TITLEタグを抽出します。

PowerShellスクリプトの実行結果

スクリプト名を「get_title.ps1」とします。
最初に実行結果を示します。


PS E:\> E:\ps\get_title.ps1
http://my-web-site.iobb.net/~yuki/bit/
   indexttl.html  =====>  索引(題名) | bit目次
   indexaut.html  =====>  索引(著者) | bit目次
   indexkey.html  =====>  索引(単語) | bit目次

PS E:\> 

PowerShellスクリプト

このPowerShellスクリプトを下記に示します。


###===  WEB タイトル取得 ===
function get_title($url) {
    $title_text = "???"
    #== Get HTML
    try {
        $response = Invoke-WebRequest -Uri $url  -TimeoutSec 5
    } catch {
       Write-Host "??? Error ",$url
       return($title_text)
    }
    $oHtml = $response.ParsedHtml
    # TITLE タグ
    $elements = $oHtml.getElementsByTagName("title")
    foreach($elm in $elements) {
        $title_text = $elm.outerText
        $title_html = $elm.outerHTML
        Write-Debug $title_html
    }
    return($title_text)
}
###  Main
#$debugPreference = "Continue"
#
$url_ary = @("indexttl.html" , "indexaut.html" , "indexkey.html")
$url_base = "http://my-web-site.iobb.net/~yuki/bit/"

Write-Host $url_base
foreach ($url in $url_ary) {
    $url_adr = $url_base + $url
    $title = get_title $url_adr
    Write-Host "  " $url " =====> " $title
}
関数 get_title($url)

function get_title($url) {
}

関数 get_title($url)は、引数で指定したWEBサイトにアクセスしてTITLEタグの内容を返します。


    try {
        $response = Invoke-WebRequest -Uri $url  -TimeoutSec 5
    } catch {
       Write-Host "??? Error ",$url
       return($title_text)
    }

try { 処理 } catch { エラー処理 } は、処理中にエラーが発生したときにエラーを捕らえてエラー処理を行います。
105行目の「Invoke-WebRequest -Uri $url」で指定したWEBページにアクセスして、WEB情報を$responseに格納します。


$oHtml = $response.ParsedHtml

WEBページのHTML情報を取得して$oHtmlに格納します。


$elements = $oHtml.getElementsByTagName("title")

HTML情報からTITLEタグを検索して$elementsに格納します。
TITLEタグなので基本的には1個だけです。しかし、他のタグ(例えば、DIVタグ)の場合は、複数個検出する可能性があります。


    foreach($elm in $elements) {
        $title_text = $elm.outerText
        $title_html = $elm.outerHTML
        Write-Debug $title_html
    }

foreach文で$elementsの要素数だけ繰り返します。
ひとつの要素$elmについて、

  • タグ内のテキスト(outerText)を$title_textに格納
  • HTMLテキスト(outerHTML)を$title_htmlに格納
  • $title_htmlをデバッグ用に出力

    return($title_text)

TITLEタグ内のテキスト$title_textを戻り値とします。

メイン処理

#$debugPreference = "Continue"

変数$debugPreferenceは、デバッグ情報の制御です。コメントアウトしているので、デバッグ情報は無効です。コメントを外すと、Write-Debugでデバッグ情報を表示します。


$url_ary = @("indexttl.html" , "indexaut.html" , "indexkey.html")

配列$url_aryに3つの文字列を格納します。@(○ , ○ , ○)は、配列を作成します。


$url_base = "http://my-web-site.iobb.net/~yuki/bit/"

変数$url_baseにWEBページのURLベースを格納します。


Write-Host $url_base

変数$url_baseを表示します。


foreach ($url in $url_ary) {
    $url_adr = $url_base + $url
    $title = get_title $url_adr
    Write-Host "  " $url " =====> " $title
}

foreach文で$url_aryの要素数だけ繰り返します。
ひとつの要素$urlについて、

  • $url_adrに$url_baseと$urlを連結した文字列を格納
  • 関数get_title を引数$url_adrで呼び出し、戻り値を$titleに格納します。
  • Write-Host文で$urlと$titleを表示します。

ここで関数呼び出しに注意してください。引数を括弧で囲む必要はありません。また、もし引数が複数個あればカンマで区切らず並べるだけです。カンマで区切ると配列を作成することになります。

デバッグ情報について

変数$debugPreferenceは、下記に示すような値を設定します。

設定値 動作
Continue デバッグメッセージを表示して実行を継続する
SilentlyContinue デバッグメッセージは表示されず、中断することなく実行する
Inquire デバッグメッセージを表示し、続行するかどうか確認する
Stop デバッグメッセージを表示し、実行を停止する

変数$debugPreferenceのコメントアウトを外すと、Continueとなりますので、下記のような実行結果となります。


PS E:\> E:\ps\get_title.ps1
http://my-web-site.iobb.net/~yuki/bit/
デバッグ: <TITLE>索引(題名) | bit目次</TITLE>
   indexttl.html  =====>  索引(題名) | bit目次
デバッグ: <TITLE>索引(著者) | bit目次</TITLE>
   indexaut.html  =====>  索引(著者) | bit目次
デバッグ: <TITLE>索引(単語) | bit目次</TITLE>
   indexkey.html  =====>  索引(単語) | bit目次

PS E:\> 

Write-Debug文でデバッグ情報を表示できました。

強力なPowerShell

PowerShellスクリプトは、とても強力です。
他のプログラミング言語を知っていれば、比較的容易にプログラミング可能だと思います。