ここから本文です

【Excel VBA 初学者からの質問です No.19】VBAでのスクレイピング。特定のIDを持っ...

vba********さん

2018/3/2417:02:10

【Excel VBA 初学者からの質問です No.19】VBAでのスクレイピング。特定のIDを持ったDivタグ内の要素のみ調査するにはどのようにすればよいのでしょうか。

2月の初めから継続的に取り組んだVBAも、いよいよIE制御に取り掛かる段階までやってきました。が、html内のエレメントの場所を指定するのに苦労しています。

<div class="" id="TargetID">


<table>
<tbody>

- 中略 -

<tr>
<td class="TargetClass">TargetText1</td>
<th>許可</th>
<td class="TargetClass">TargetText2</td>
</tr>

- 中略 -


</tbody>
</table>


</div>

たとえば、上記のようなID属性 (= "Sample")を携えた範囲を考えるとき、最終的に取得したいのはTargetText1及び2なのですが、現状では特定のDivタグの内部を範囲指定する方法が分からず、書籍に載っていた

For i = 0 to Doc.all.Length -1

If Doc.all(i).innerText="許可 " Then

TargetText1 = Doc.all(i-1)...

End If

Next i

ドキュメントの先頭からすべての要素を調べ上げる方法で対処しています。

(IDタグ内の<td Class = TargetClass>が範囲内に一つのみ存在するならば「GetElemntByID.GetElementsByClassName.InnerText」で重ねれば対応できるのですが、今回は該当しません)

しかし、これではあまりに生産性が悪く、安定性を欠くので、

①ID名に"TargetID"を持つDivタグの範囲内を全て検索
②範囲内の任意の<th>タグのinnerTextが"許可"となっているのならば
③その一つ手前のタグのClass名が"TargetClass"である場合に限ってタグ内のテキストを取得する → TargetText1
③その一つ後ろのタグのClass名が"TargetClass"である場合に限ってタグ内のテキストを取得する → TargetText2

といったように変更をかけてあげたいのです。

しかし、いかんせんインターネットでの情報が乏しく、どのように手をつければよいのか見当つかずで、このたび皆さまにご相談をさせていただく運びとなりました。

各要素をhtmlドキュメントから特定するというその都度の対処が必要になりそうな技術ではありますが、基本的なことをご指導いただけるようであれば大変に幸いに思います_ _

また、ドキュメント内の全要素を検索対象に

For i = 0 to Doc.all.Length

If Doc.all(i).ClassName = "TargetClass" Then

としたところ、エラーが返ってきてしまったのですが、そんなプロパティは存在しない、ということなのでしょうか…

毎回馬鹿な質問ばかりで恐縮な限りですが、お力添えのほどをどうか何卒よろしくお願い申し上げます。

---
2018年の2月から、目下独りでExcelのVBAを学習しています。
面倒くさがりな性格の為に、手順を踏まず興味のあるところから手をつけているのですが、皆さまの無償のご厚意に報いるよう全力で事にあたります。
お手数をおかけしますが、どうか何卒お力添えのほどをよろしくお願い申し上げますm(__)m

・後に続く方が目的の質問に辿り着きやすいように、一投稿につき1テーマを質問させていただく予定です。
・今後頻繁に利用することが見込まれる為に、ご挨拶などは定型文にて失礼させていただいております。誠に恐縮ながら、どうかご理解のほどをお願い申し上げます(..)

この質問は、活躍中のチエリアン・専門家に回答をリクエストしました。

閲覧数:
88
回答数:
3

違反報告

ベストアンサーに選ばれた回答

web********さん

リクエストマッチ

2018/3/2418:28:21

<table>~~</table>
テーブルデータですよね?

テーブルデータであれば何列目の何行目の形式(ExcelVBAでのCells指定と同じ)でデータは取り出せますが・TargetText1・TargetText2の位置は毎回変わっているのでしょうか?


<tr>
<td class="TargetClass">TargetText1</td>
<th>許可</th>
<td class="TargetClass">TargetText2</td>
</tr>

<tr>(テーブル列)タグ内で<td>(テーブルデータ)に挟まれた<th>(テーブルヘッダー)ってなにか妙な表示ですね?

  • web********さん

    2018/3/2419:51:29

    テーブル内の・TargetText1・TargetText2の位置が不定の場合

    Dim Tr As HTMLTableRow
    For Each Tr In GetElemntByID.GetElementsByTagName("table")(0).Rows
    If InStr(Tr.innertextInStr, "許可") > 0 Then
    TargetText1 = Tr.Cells(0)
    TargetText2 = Tr.Cells(2)
    End If
    Next

    だいぶ簡略化していますが

  • その他の返信を表示

返信を取り消しますが
よろしいですか?

  • 取り消す
  • キャンセル

質問した人からのコメント

2018/3/29 23:02:46

今回も皆さまのご協力のおかげで問題の解決に至りました。
新しいプロパティやオブジェクト型の確認手段など、この場で教えていただかなければ知り得ないことが山のようにあり、どんなにありがたいか言葉で言い表すことはできません。開発者ツールでHTMLを閲覧するたび溜息しか出なかったのですが、今では以前より遥かに理解することができています。これも、ひとえに皆さまのご厚意のおかげです。本当にありがとうございます

ベストアンサー以外の回答

1〜2件/2件中

並び替え:回答日時の
新しい順
|古い順

red********さん

2018/3/2420:31:57

以下のような感じで …

' divタグを抽出
for each oDiv in Doc.getElementsByTagName("div")
if oDiv.className = "TargetID" then

' Thタグを抽出
for each oTh in oDIv.getElementsByTagName("th")
' Thタグの直前のノードが”TargetClass”かを判定
if oTh.previousSibling.className = "TargetClass" then
sTarget1 = oTh.previousSibling.innerText
end if
' Thタグの直後のノードが”TargetClass”かを判定
if oTh.nextSibling.className ="TargetClass" then
sTarget2 = oTh.nextSibling.innerText
end if
next

end if
next

返信を取り消しますが
よろしいですか?

  • 取り消す
  • キャンセル

プロフィール画像

カテゴリマスター

hot********さん

2018/3/2417:42:58

>たとえば、上記のようなID属性 (= "Sample")を携えた範囲を考えるとき、

ではなくプログラムの方の

<div class="" id="TargetID">

の中の

<td class="TargetClass">文字列</td>

の"文字列"部分を取得します。


Sub sample()
Dim ie As Object
Dim elm As Object

Set ie = CreateObject("InternetExplorer.Application")
ie.Visible = True
ie.Navigate "目的のURL"
Do While ie.Busy Or ie.ReadyState <> 4: DoEvents: Loop

For Each elm In ie.document.getElementById("TargetID").getElementsByClassName("TargetClass")
Debug.Print elm.innerText
Next
ie.Quit

End Sub

この質問につけられたタグ

みんなで作る知恵袋 悩みや疑問、なんでも気軽にきいちゃおう!

Q&Aをキーワードで検索:

Yahoo! JAPANは、回答に記載された内容の信ぴょう性、正確性を保証しておりません。
お客様自身の責任と判断で、ご利用ください。
本文はここまでです このページの先頭へ

「追加する」ボタンを押してください。

閉じる

※知恵コレクションに追加された質問は選択されたID/ニックネームのMy知恵袋で確認できます。

不適切な投稿でないことを報告しました。

閉じる