【VBScript(WSH)】エラーの回避方法『オブジェクトがありません』

【VBScript(WSH)】エラーの回避方法『オブジェクトがありません』

【VBScript(WSH)】エラーの回避方法『オブジェクトがありません』

VBSでスクレイピング組んでれば必ず遭遇するであろうエラー『オブジェクトがありません』

エラー:オブジェクトがありません。:’objIE.Document.getElementByName(…)(…)’
コード:800A01A8
ソース:Microsoft VBScript 実行時エラー

いやいや、存在するかしないかで場合分けしたいんだって!
存在してればレコードはあるから取得して、存在してなかったらスキップしたいのよ。

と思っていても意図した動きになったりならなかったり。
と言う事で、ここら辺まとめてみます。

意図した動きをさせるためのチェックポイント

動的サイト内に下のようなHTMLがあったとします。

さて、検索したらレコード件数がゼロ。その時、動的サイトは大別すると下の3パターンになっていると思います。

■タイプ1:一部のタグ(olとかtableなど)を残して値が消えている

■タイプ2:レコード情報が(olとかtableなどの)タグごと消えている

■タイプ3:無いよと言う値が挿入されている

スクレイピングの際はこの中のどのパターンかを把握しておきます。
タイプに合わない形で分岐を書いていると「オブジェクトが無い」と怒られます。

どうすればいいか答え的なもの

考え方は2つです。

  1. 検索レコードのオブジェクトを存在確認して分岐する
  2. エラーオブジェクトの存在確認をして分岐する

そしてやってはいけない事(エラーの元凶)は次の2つです。

  1. 検索レコードにテキストがあるかを存在確認して分岐する
  2. エラーオブジェクトのテキストがあるか確認して分岐する

オブジェクトそのものの存在確認をする場合は【有無】で分岐できますが、オブジェクト内の値で分岐しようとした場合は『オブジェクトの存在が大前提』となります。
なので[ objIE.Document.getElementsByTagName(“li”).innerText ]などと書いた場合、タイプ1-3全てで liタグは存在しないのにテキストを取ろうとしている=「オブジェクトがありません」とエラーが出てきてしまいます。

オブジェクトが無いってどういう事?

例として【タイプ1:一部のタグ(olとかtableなど)を残して値が消えている】で見ていきます。

正しく動くIF分岐script

こんなのはNGです。

タイプ1の場合、<li>も<li>に囲まれたテキストも存在しません。

その為、EmptyやNULLで存在確認をしようとすると、そもそものliタグが存在していない為「オブジェクトが無い」と怒られる事になります。

存在確認の鍵は【 IsObject / IsEmpty / IsNull 】を使いこなすこと

私もしばらく戸惑っていましたが、VBScriptでスクレイピングを書こうとした場合、この3つの違いを理解している事は大切です。

  • IsObject(変数):変数がobjectか否かを確認。変数が存在しない場合はオブジェクトではないと回答
  • IsEmpty(変数):変数に値が入っているかを確認(入っていない場合がTRUE)。NULLの場合、NULLという値が入っているのでFALSEが返る。TRUEとなるのはEmptyで初期化されている場合のみ。変数が存在しない場合はobjectNothingのエラーが出る。
  • IsNull(変数):変数にNULLが入っているかを確認(NULLの場合がTRUE)。初期化した値(変数=Empty)の場合FALSEが返る。変数が存在しない場合はobjectNothingのエラーが出る。

具体的に見てみましょう。

IsObjectの動作

こんなスクリプトを実行してみます。

メッセージボックスで出てくる値は【FALSE / 真 / 否】です。NothingでもオブジェクトとしてセットされていればTRUEを返します。

IsEmptyの動作

IsObjectと同じくこんなスクリプトを実行してみます。

この答は【FALSE / 偽 / 正】です。ちなみに、オブジェクトをEmptyで初期化する事は出来ません。[ Set objTEST = Empty ]と書くと「オブジェクトがありません」と怒られます。

IsNullの場合

同じ方法でこんなスクリプトを実行します。

この答は【TRUE/ 偽 / 否】です。[ Set objTEST = NULL]と書いた場合もEmpty と同じく「オブジェクトがありません」と怒られます。

まとめ

ここまでを表にするとこんな感じ。

変数 = NULL 変数 = Empty 変数 = “” Set 変数 = Nothing 備考
IsNull() TRUE FALSE FALSE FALSE 変数がobjectの時は無条件でFALSE。
空文字 ”” もNULLでは無いためFALSE。
スクレイピングではまず使い道はない。
IsEmpty() FALSE TRUE FALSE FALSE 初期化されているかを判別する。
つまりは、Flag的使い方が可能。
何かの処理で値が入ればそれを軸に分岐を組める。
IsObject() FALSE FALSE FALSE TRUE オブジェクトか否かを判断する。
スクレイピングでは存在確認で使いどころが多い。
変数に値が入っていてもオブジェクトでなければFALSE。

ClassNameで抽出した値が存在しているかを確認するのはIsObjyect一択。