前提・実現したいこと
ウェブスクレイピングのツールをExcelVBAを使用して作成しています。
class属性の取得部分がうまく機能せず困っています。
前提として、ExcelVBAで実装する必要があります。
このスクレイピングにはブラウザを使用していません。いわゆるDOM操作のみで完結させています。速度やサイト側の条件でその必要があります。
こちらでの質問は初めてでして、無作法がありましたらご容赦ください。
発生している問題・エラーメッセージ
VBAを通常実行すると、class属性の取得ができません。ところが、コードウィンドウでステップ実行するとうまく取得できます。
なので構文のエラー等はないと思っています。走らせると取得できない理由がわかりません。
該当のソースコード
全体は非常に長いので、該当の機能部分を載せます。これは私が定義したクラスのメソッドとして機能します。(クラスモジュール内です)
このメソッドは指定する名称(KeyWord)のclass属性を掴んできて返す機能です。
Public Function GetClassElements(resDataNo As Long, KeyWord As String) As Variant 'ForEachコールバック Dim El As Variant '配列バッファ Dim bufV() As Variant 'データ数初期化 resDataNo = 1 '(※2)ここで止めてもうまくいきます(後述) '全要素ループしてClassNameを評価 For Each El In hDOC.all '(※1)この部分にいくつかのアプローチ(後述) Debug.Print El.ClassName '←チェック用に入れてみました 'クラス名を比較 If El.ClassName = KeyWord Then '←問題の部分 '結果配列再宣言 ReDim Preserve bufV(1 To resDataNo) '値セット Set bufV(resDataNo) = El 'データ数+1 resDataNo = resDataNo + 1 End If Next El 'データ数修正 resDataNo = resDataNo - 1 '戻り値セット GetClassElements = bufV Set El = Nothing End Function
試したこと
※1の部分に、DoEventsとSleep(50~500くらいまで試しました)をそれぞれ単独、又は一緒に入れてみましたが、結果は変わりませんでした。
また、このメソッドを外部から呼び出す部分に、
DoEvents Variant型 = 当クラス.GetClassElements(resN,KeyWord)
等してみましたが、改善されませんでした。
また、Class属性の取得部分(問題の部分)で、
El.getAttribute("ClassName") = KeyWord '←全てNullが返される El.getAttribute("class") = KeyWord '←同上
上記のようにも試しました。
補足情報(FW/ツールのバージョンなど)
まず、このクラスはHTMLをウェブから取得して、内部に保持するクラスです。そのデータ本体は hDoc です。コンストラクタは定義していません。
HTMLの取得部分は同クラス内の別のメソッドで、
Public Function OpenURL(ByVal strURL As String) As Boolean On Error GoTo Err_OpenURL '関数値初期化 OpenURL = False 'Documentオブジェクト生成 Set hDOC = CreateObject("htmlfile") 'サイトデータの格納先 Dim objHTML As Object 'XMLHTTPオブジェクトを生成 Set objHTML = CreateObject("MSXML2.XMLHTTP") 'URL読み込み With objHTML 'URL読み込み .Open "GET", strURL, False .send '安全用のWait Do While .readyState <> 4 DoEvents Loop 'DOM操作を行える様に変換 hDOC.write .responseText End With '成功 OpenURL = True 'エラー終了 Err_OpenURL: Set objHTML = Nothing End Function
となります。hDocを操作する他のメソッドは全て正常に機能していますので、HTMLの取得自体はうまくいっていると考えています。
チェック用に入れた、Debug.Print El.ClassName の部分を確認したところ、
コードを走らせた(通常実行)場合→全て""が返されているようでした。
コードウィンドウでステップ実行した場合→正しくすべてのClass属性の名前が返されていました。
ステップ実行時にうまくいくという部分ですが、※2の部分でコードを中断し、その後最後まで走らせた場合もうまく取得できていました。
いろいろ調べてみましたが、お手上げです。どなたかご教示いただけると助かります。
環境
Win10 64bit
Excel2019 64bit
回答1件
あなたの回答
tips
プレビュー