今回、QueryTableオブジェクトを使用してサイトの表をExcelのシートに取り込もうとしたのですが、Yahoo!(ファイナンス)のサイトからは表(サイトの中央の大きな表)をそのままの形で抽出できたにも関わらず、OddsPortal と云うサイトの表(これも中央の表)は取り込みができず、表の内容とは無関係な幾つかの文字列が取り込まれただけでした。
マクロは以下の通りです(プロパティは最小限を掲載)。
Sub Table抽出比較()
Dim strgURL As String
'Yahoo!(ファイナンス)
strgURL = "URL;" & "https://info.finance.yahoo.co.jp/ranking/?kd=1&m …
'OddsPortal(サッカーのJ1リーグ)
' strgURL = "URL;" & "https://www.oddsportal.com/soccer/japan/j1-leagu …
With ActiveSheet.QueryTables.Add(Connection:=strgURL, _
Destination:=ActiveSheet.Range("A1"))
.WebFormatting = xlWebFormattingNone
.WebSelectionType = xlAllTables
.Refresh BackgroundQuery:=False
End With
End Sub
OddsPortalの表のHTML要素(目的のテーブルの前後だけ)は次のようになっています。
<div id="tournamentTable" style="display: block;">
<table class " table-main" id="tournamentTable"> ← ここが目的のテーブル
省略
</div>
なお、念の為、以下の情報も書き添えておきます。
selector : #tournamentTable
full Xpath : /html/body/div[1]/div/div[2]/div[6]/div[1]/div/div[1]/div[2]/div[1]/div[6]/table
Xpath : //*[@id="tournamentTable"]
環境 : Windows10 Excel19(64bits)
OddsPortalのサイトはQueryTableオブジェクトには適していないのでしょうか?
ご存知の方、教えて頂ければ幸いです。
宜しくお願いします。
A 回答 (2件)
- 最新から表示
- 回答順に表示
No.2
- 回答日時:
>Debug.Print htmlDoc.getElementsByTagName("tournamentTable")(0).innerText
変数やオブジェクトの宣言等、細かい部分は記載がないので、上記の一行に限って言えば、
getElementsByTagNameはHTMLのタグを取得するものですから、HTMLのタグでないもの「tournamentTable」を取得しようとしても、できないと思われます。
getElementsByTagNameを使うのであれば、HTMLのタグであるものを指定する必要があります。例えば
htmlDoc.getElementsByTagName("table")(0).innnerText
※添え字の「0」が正しいかは不明
あるいは「tournamentTable」を活かすのであれば、「tournamentTable」はidですから、例えば
htmlDoc.getElementById("tournamentTable")(0).innnerText
※添え字の「0」が正しいかは不明
※getElementByIdはgetElementsByIdではないことに注意
という記述になるのではないかと思います。
goomaniaさん、丁寧なる回答を有り難うございました。
>getElementsByTagNameはHTMLのタグを取得するものですから、HTMLのタグでないもの「tournamentTable」を取得しようとしても、できないと思われます。
→ これについては前回の投稿でも書いたように、ダメモトで一応挿入しておいたものです。
>例えば
htmlDoc.getElementsByTagName("table")(0).innnerText
→ これについては "table"、" table-main" 等とし、且つ、添字を(0)、(1)、(2)と変えてはみたのですが、表とは無関係な文字列しか得る事はできませんでした。
このサイトでは1つの表しか存在しないので (0) で取り敢えずは良いのかとは思います。
>あるいは「tournamentTable」を活かすのであれば、「tournamentTable」はidですから、例えば
htmlDoc.getElementById("tournamentTable")(0).innnerText
→ 上記のコードも以前に試してみたのですが、「オブジェクトが必要です。」とのエラーメッセージが出てしまいます。"tournamentTable"を見つけられなかったのでしょう。
これも、添字を(0)、(1)、(2)と変えてみても同じでした。
また、Elementsとすると「オブジェクトは、このプロパティまたはメソッドをサポートしていません。」とのエラーメッセージが出てしまいます。
fujillinさんが指摘されていましたが、基本的にはHTMLのid重複の文法違反に原因があるのかもしれません。
以上の通りですが、また何か気づいた事があればご指導下さい。
P.S. マクロの細かい部分は残念ながら文字数オーバーでご提示できませんが、次ぎの機会にでも記述できればと考えています。
No.1
- 回答日時:
こんにちは
QueryTableの仕様は存じませんが、指定URLでリクエストをしてそのソースから抽出するものではないでしょうか?
ご提示の2番目のURLのシースを見てみるとわかると思いますが、ソースの時点では表の部分は
<div id="tournamentTable"></div>
となっており、内容が記されていない状態です。
テーブルの下の方を見るとページングがされているので、内容は後から読み込まれているものと推測できます。
まぁ、
><div id="tournamentTable" style="display: block;">
><table class " table-main" id="tournamentTable">
というHTMLも、id重複の文法違反になちゃってますけれど…
もしも、QueryTableがソースから抽出する仕組みになっているのなら、これが原因と推測できます。
内容を取得したいのであれば、後から読み込む仕組みと同様のリクエストを行うか(←サーバ側が受け付けるかどうかは不明)、あるいはブラウザを操作して、一旦表示させてからDOM操作で内容を取得するかではないかと思いますけれど…
(↑ テストしていないので、推測ですけれど)
fujillinさん、迅速なる回答と的確なご指摘を有り難うございました。
矢張り、OddsPortal 側に問題があるようですね。
小生、QueryTableを使ったのは初めてなので、これについては殆んど理解できていません。
お示ししたマクロは殆んど Webからのコピぺです。
従って、御指摘の「後から読み込む仕組みと同様のリクエストを行う」のは残念ながら手を付けることはできません。
また、「ブラウザを操作して、一旦表示させてからDOM操作で内容を取得する」点についてはあまり対処したくない方法なのです。
と云うのも、今回の目的はデータ取得の高速化を狙っており、この方法は適していないように思います(これについて「質問」で触れなかった事をお詫びします)。
現在はSeleniumBasicとChromeのコンビで以下のようなマクロで目的のテーブルを完全な形で取得できているのですが、Chromeが一つの表を取り込むのに数秒(Chromeの立ち上がり時間を除く)を要し、1サイト当たり2ページの表を100サイト超を巡回すると、データの編集を含めた所要時間が10数分となってしまいます。
Driver.Get (URL)
Driver.FindElementByXPath("//*[@id=""tournamentTable""]/tbody").AsTable().ToExcel (Worksheets("sheet1").Cells(1, 1))
そこで他に高速化の手段は無いかと探して辿り着いたのが QueryTableだった次第です。
次善の策としてはHTTPリクエスト(これも全く理解していません)を使った以下のマクロなのですが、当然ながらデータの取り込みができていません(最後の行は完全にNG、文字超過の為、他のコード省略)。
httpReq.Open "GET", URL
Debug.Print htmlDoc.getElementsByTagName("tournamentTable")(0).innerText
勝手を言って申し訳ないのですが、もし、fujillinさんがお解りであればこれについてもコメントを頂ければ有り難いのですが、宜しくお願いします。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
- ・ゆるやかでぃべーと タイムマシンを破壊すべきか。
- ・歩いた自慢大会
- ・許せない心理テスト
- ・字面がカッコいい英単語
- ・これ何て呼びますか Part2
- ・人生で一番思い出に残ってる靴
- ・ゆるやかでぃべーと すべての高校生はアルバイトをするべきだ。
- ・初めて自分の家と他人の家が違う、と意識した時
- ・単二電池
- ・チョコミントアイス
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
cnt <= (others => '0'); の意...
-
safariで見るとページ上部に余...
-
css リンクの色が全部変わって...
-
質問です。 新規登録ボタンが全...
-
CSSメニューボタンのセンター配置
-
htmlの文字が縦書きになる
-
現行の日本国憲法の古い所を教...
-
smallにtext-allignが効かない
-
htmlのolやulなどlistにtitleや...
-
【ヒトの神秘】美男美女から何...
-
複数のボタンを等間隔に、かつ...
-
ある要素の中身を全部グレーア...
-
HTML属性での「""」 「''」違い
-
含む含まないという概念自体の...
-
HRタグ 枠線を透明にするには?
-
W3Cのソースコードの検証サービ...
-
widthやheightの数値に単位(px...
-
<table>の高さ固定。情報増加時...
-
css初心者 フレックスボックス...
-
画像イメージの上下左右、欲し...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
cnt <= (others => '0'); の意...
-
質問です。 新規登録ボタンが全...
-
ASP.NETでプレーンなページに文...
-
pythonでのカーソル移動がずれる
-
VBAでの素数の求め方
-
Excel VBAでのIE操作でクリック...
-
safariで見るとページ上部に余...
-
プログラマーの方に質問です。 ...
-
秀丸で複数行コメントアウトを...
-
行頭から全角で3文字位さげた...
-
正規表現
-
VBA : QueryTableでのスクレイ...
-
CSSでの2段組レイアウトでdiv#c...
-
入れ子になっているhtmlのXPath...
-
検索結果がツリー状に表示され...
-
smartyについて
-
Firefoxで別ページのアンカーリ...
-
vbaでieを操作しようとしていま...
-
ずっと悩んでます。特定タグを...
-
CSSのdivタグの名称には決まり...
おすすめ情報