前回までの取り組みで、欲しかった機能はほとんど実装した。ただし、まだ無駄な処理が残っているので、若干修正して高速化を図る。すでに日常的に使えるレベルのスクリプトにはなっているので、後は実際に使っていく中で調整していけばよいだろう。

無駄な処理を考える

まず、前回の成果物を確認しておこう。Microsoft Edgeのヘッドレスモードを中心に、ヘッドレスモードでは取得できないコンテンツをcurlで取得するPowerShellスクリプト「netcat.ps1」だ。

#!/usr/bin/env pwsh

#========================================================================
# URLで指定されたリソースを取得
#========================================================================

#========================================================================
# 引数を処理
#   -URL url        WebリソースのURL
#   -Agent agent    リクエストで使うエージェントを指定
#========================================================================
Param(
    [Parameter(Mandatory=$true)][String]$URL = "",
    [String]$Agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"
)

#========================================================================
# Webリソース取得に利用するアプリケーション
#========================================================================
$msedge='C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe'
$curl='C:\Windows\System32\curl.exe'

#========================================================================
# Webリソースの種類を取得
#========================================================================
$ContentType=(& $curl       --location              `
                -A $Agent               `
                -Ss -I                  `
                $URL                    |
        Select-String   "^Content-Type:")

#========================================================================
# どの方法でWebリソースを取得するかを判断
#========================================================================
switch -Wildcard ($ContentType)
{
    #================================================================
    # HTMLコンテンツ: なるべくWebブラウザのヘッドレスモードを使用
    #================================================================
    '*text/html*' {
        #========================================================
        # Microsoft Edgeを使って取得
        #========================================================
        $method='msedge'
    }
    #================================================================
    # それ以外のコンテンツは curl を使って取得
    #================================================================
    default {
        #========================================================
        # curlを使って取得
        #========================================================
        $method='curl'
    }
}

#========================================================================
# Webリソースを取得
#========================================================================
switch ($method)
{
    #================================================================
    # Microsoft Edgeを使って取得
    #================================================================
    'msedge'
    {
        $o1='--headless'
        $o2='--dump-dom'
        $o3='--enable-logging'
        $o4='--user-agent="$agent"'

        $tmpf=New-TemporaryFile
        Start-Process   -FilePath $msedge           `
                -RedirectStandardOutput $tmpf       `
                -ArgumentList $o1,$o2,$o3,$o4,$URL  `
                -Wait
        Get-Content $tmpf
        Remove-Item $tmpf
    }

    #================================================================
    # curl を使って取得
    #================================================================
    'curl'
    {
        & $curl     --location              `
                -A $Agent               `
                -get $URL
    }
}

このスクリプトの処理の本質的な部分は、次のようになる。

  1. curlでWebサーバからレスポンスヘッダを取得し、対象コンテンツの種類を取得する
  2. 種類がtext/htmlであればMicrosoft Edgeのヘッドレスモードで、それ以外の場合にはcurlでコンテンツを取得する

つまり、Webサーバとの通信が最低でも2回は発生していることになる。場合によってはこの処理は無駄だ。

例えば、URLの最後が「.html」になっていればHTMLだろうし、「.pdf」になっていればPDFだろう。わざわざWebサーバにコンテンツの種類を問い合わせるのは無駄だ。このようにURLからコンテンツの種類が明確にわかる場合には、Webサーバに問い合わせることなく種類を確定するようにする。これでWebサーバへの通信回数を減らすことができるので、処理の高速化を実現できる。

コンテンツ種類の判定処理を改良する

この記事は
Members+会員の方のみ御覧いただけます

ログイン/会員登録(無料)

会員サービスの詳細はこちら