前提・実現したいこと
VBAでWebスクレイピングのコードを作成しています。
順序としては以下の順序でコードを組み立てています。
0. HTTPリクエストを投げて目標のページのHTMLソースを取得
0. HTMLソースから表部分の要素を取得
0. 各行のテキストをイミディエイトウィンドウに表示
発生している問題・エラーメッセージ
HTMLDocumentからgetElementByIdでtable要素を取得できません。
正確には、ステップイン実行で1行ずつ実行するとtable要素を取得できるのですが、普通に実行すると取得できません。
※1ページに複数のテーブルが存在し目的のtableタグにIdが設定されているので、getElementByIdを使用しています。
該当のソースコード
大変申し訳ないのですが、質問事項に関係なさそうな部分のソースコード(ワークシート操作など)は省いております。
VBA
1Option Explicit 2 3'******************************* 4'* 関数名:Performer 5'* 機 能:ボタン押下時にVBAを実行 6'* 概 要: 7'******************************* 8Sub Performer() 9 On Error GoTo Escape 10 11 Dim link As String 12 link = ThisWorkbook.Worksheets("Sheet1").Cells(1, 2).Value 13 Dim htmlDoc As HTMLDocument 14 Dim objHtmlTable As HTMLTable 15 Dim objHtmlTableRow As HTMLTableRow 16 Dim btn As Integer 17 18' HTMLDocumentを取得 19 Set htmlDoc = GetHtmlDoc(link) 20 21' 表部分のHTMLソースを取得 22 If Not IsNull(htmlDoc.getElementById("sortabletable1")) Then 23 Set objHtmlTable = htmlDoc.getElementById("sortabletable1") 24 Else 25 Call Err.Raise(213, "Performer", "指定の要素が見つかりませんでした") 26 End If 27 28 For Each objHtmlTableRow In objHtmlTable.getElementsByTagName("tbody")(0).getElementsByTagName("tr") 29 Debug.Print objHtmlTableRow.innerText 30 Next objHtmlTableRow 31 32 btn = MsgBox("処理完了", vbOKOnly + vbInformation, "終了") 33 34 Exit Sub 35 36Escape: 37 38 btn = MsgBox("処理失敗" & Chr(10) & Chr(10) & _ 39 Err.Number & Chr(10) & _ 40 Err.Source & Chr(10) & _ 41 Err.Description, vbOKOnly + vbInformation, "終了") 42 43End Sub 44 45 46'-------------------------------------------------------- 47'* 関数名:GetHtmlDoc 48'* 機 能:指定のURLのHTMLソースをHTMLDocument形式で取得する 49'* 補 足: 50'-------------------------------------------------------- 51Function GetHtmlDoc(ByVal in_URL As String) As HTMLDocument 52 On Error GoTo Escape 53 54 Dim httpReq As XMLHTTP60 55 Set httpReq = New XMLHTTP60 56 Dim tmp_htmlDoc As Object 57 Set tmp_htmlDoc = New HTMLDocument 58 59 httpReq.Open "GET", in_URL 60 httpReq.send 61 62 Do While httpReq.readyState < 4 63 DoEvents 64 Loop 65 66 tmp_htmlDoc.write httpReq.responseText 67 68 Set GetHtmlDoc = tmp_htmlDoc 69 70 Set httpReq = Nothing 71 Set tmp_htmlDoc = Nothing 72 73 Exit Function 74 75Escape: 76 Set httpReq = Nothing 77 Set tmp_htmlDoc = Nothing 78 Call Err.Raise(Err.Number, Err.Source, Err.Description) 79 80End Function
試したこと
- 番号リスト問題個所の特定①
普通に実行した際にエラーが発生したのは
「For Each objHtmlTableRow In objHtmlTable.getElementsByTagName("tbody")(0).getElementsByTagName("tr")」
の部分で、ローカルウィンドウを見るとobjHtmlTableがNothingだということがわかりました。
0. 番号リスト問題個所の特定②
objHtmlTableにオブジェクトをセットする部分
「Set objHtmlTable = htmlDoc.getElementById("sortabletable1")」
にブレークポイントを置いてステップイン実行してみたら、objHtmlTableに値が入りイミディエイトウィンドウにも
目的のデータが表示されました。
何度か試してみて、
- 普通にVBAを実行するとobjHtmlTableにオブジェクトがセットされず後の処理でエラーが発生する
- ステップイン実行だとobjHtmlTableにオブジェクトがセットされる
ということはわかったのですが、この事象の解決ができずにおり、皆さんのお知恵を拝借したく思います。
なお、他に提供してほしい情報などございましたらお知らせください。対応可能な範囲で提供させていただきます。
補足情報(FW/ツールのバージョンなど)
Excelはこちらを使用しています。
Microsoft® Excel® 2016 MSO (16.0.14326.20384) 32 ビット
ちなみに、スクレイピングに使用しているサイトはこちらです。
https://azurlane.wikiru.jp/index.php?%A5%AD%A5%E3%A5%E9%A5%AF%A5%BF%A1%BC%A5%EA%A5%B9%A5%C8
自分がプレイしていて大きな表があるのを知っていたのでスクレイピングにはピッタリかな~と思いましてw
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/09/26 10:34
2021/09/26 13:36