WEBスクレイピングPowerShell併用術(たとえばVBAでIEを操作するとして)

環境
Windows10
Powershell5.1
#概要
　私はInternetExplorerでwebスクレイピングをするとなったら、たとえPowerShellで開発をしないときであっても、必ずPowerShellISEを立ち上げて他の開発環境と併用しています。
　IEを使うならWindowにデフォルトで入っているPowerShellも使えるはずです。
　PowerShellを併用すれば、サクサクWebスクレイピングできることを保証します。

#対話型シェルで値の取得、取り直しが楽々、しかも履歴が残ってくれる

　たとえば、ExcelVBAやVBSで開かれているウインドウの中から目的のWebをピックアップするとします。
　会社でIEベースの業務システムや資格情報のいる社内Webを使用していて、それをスクレイピングする場合は、いろいろな制約からこのような方法が無難です。
　一度取得してしまえばあとはいかようにもできますしね。
　私だと、Shell.applicationを用いてこんな感じです。

```vb:ExcelVBA
Sub ieWindow()
    Dim shell as object
    Set shell = CreateObject("shell.application") 
    Dim ie as object
    Dim IsIeExists as boolean
    IsIeExists = False
    Dim win as object
        For Each win In shell.Windows
```
ここから、こんな感じでウィンドウを取得したいわけです。

```vb:ExcelVBA
                If win.locationname = "〇〇" Then
                    Set ie = win
                    IsIeExists = True
                    Exit For
                end if
```
通常なら、この後こんな感じでちょっと書き換えてローカルウインドウでwinsの値を見たり

```vb:ExcelVBA
Sub ieWindow()
    Dim shell as object
    Set shell = CreateObject("shell.application") 
    Dim ie as object
    Dim IsIeExists as boolean
    IsIeExists = False
    Dim wins as object
    wins=shell.Windows
stop
```
debug.printでlocationnameに決め打ちしたりして一覧を出したりするのですが

```vb:ExcelVBA
Sub ieWindow()
    Dim shell as object
    Set shell = CreateObject("shell.application") 
    Dim ie as object
    Dim IsIeExists as boolean
    IsIeExists = False
    Dim wins as object
         For Each win In shell.Windows
               If win.Name = "Internet Explorer" Then
                   Debug.Print win.locationName
               end if
         next win
 ```
こういうときに限ってlocationnameではなくlocationURLじゃないとページを特定できずにもう一度取得しなおしたり、InternetExplorerに絞るの忘れてURL取りに行ってエラーが出たり、Stopの多用でExcelが固まったり、前に出したローカルウインドウの値が見たくなったり・・・さっそくつまづきがちです（あくまで私の場合）。

　そこで、PowerShellです。
　PowerShell ISEを開いて以下のコードを実行します。

```powershell:powershell5.1 
$shell=new-object -comobject shell.application
$ieWindows=$shell.windows()|where-object{$_.name -match "Internet Explorer"}
$ieWindows|Select-Object *
```

<img width="900" alt="2020-05-17 (6).png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/622636/619d7e3a-0973-02b1-950a-9913b8edeb2f.png">
　これですべてのウインドウの全てのプロパティとメソッドが表示されて、しかも窓に残ってくれます。
　もしExcelに何らかのエラーが生じたとしても、

```powershell:powershell5.1 
$shell=new-object -comobject shell.application
$shell.windows()|Select-Object *
```
こんな風に一つ前に戻って値を表示するだけで、
<img width="900" alt="2020-05-30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/622636/34f0f418-0082-411d-9540-37e6939bfdef.png">
あ、エクスプローラーのlocationURL拾ってエラー出たんだなって分かります。

#webページのHTMLをまるごと取り出せる
　ページを取得したら、後はページを移動したりタグを取り出したり、いうまでもなく、WebページのHTMLを何度も確認することになります。
　そこで、またPowerShellの出番です。むしろここからがオブジェクト渡しのPowerShellの真骨頂です。

```powershell:powershell5.1 
$shell=new-object -comobject shell.application
$ieWindows=$shell.windows()|where-object{$_.name -match "Internet Explorer"}
$ieWindows.document.body|select-object *
```
　これで、開かれている全てのIEのページの全HTMLがまるごと表示されます！
（もちろん、不要なWebページは閉じた方が見やすいです）。
　F12ではHTMLの一部が表示されないことがありますが、PowerShellはいつも安定してHTMLを見せてくれます。
　そして、一度出したデータはコンソールに残り、パソコンを落とすまで履歴に残ります。
　さらに、Webページを移動したら、先ほどのコードをもう一度実行するだけで新しいページのHTMLが表示されます（なのでISEにコードを残すのをおすすめします）。

　もちろん、PowerShellでHTMLを読むのでVBAでStopを多用する必要がなくなり、Excelが固まるリスクが下がるのはいうまでもありません。
　サクサクWebページのタグ解析が進み、たとえば下記のようなコードを書き進められます。

```vb:ExcelVBA
Sub ieWindow()
    Dim shell
    Set shell = CreateObject("shell.application")
    Dim ie
    Dim IsIeExists As Boolean
    IsIeExists = False
    Dim win
        For Each win In shell.Windows
            If win.Name = "Internet Explorer" Then
                If win.locationname = "〇〇" Then
                    Set ie = win
                    IsIeExists = True
                    Exit For
                End If
            End If
        Next
        If IsIeExists = False Then
            MsgBox "ウインドウを取得できませんでした"
            Exit Sub
        End If
    Dim htmldoc
    Set htmldoc = ie.Document
    MsgBox htmldoc.getElementsByName("text")(0).Value 'textをメッセージ表示
    htmldoc.getElementsByName("text")(0).Value = "テスト" 'textにテストと入力
End Sub
```
#まとめ
IEのスクレイピングでPowerShellを併用すれば

        1.開発の見通しが立てやすい
        2.HTMLの取得,読み直しが楽々
        3.HTMLを読む負担をPowerShellに逃がすことで開発環境が固まりにくくなる
ということで、非常におすすめです。

　できれば、モニターを２つにして片方をPowerShellにしてHTMLを読みつつ開発を進めるのがいいと思います。