[[20220215103445]] 『WEBページよりVBAで値を取得したい』(jnk) ページの最後に飛ぶ

[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]

 

『WEBページよりVBAで値を取得したい』(jnk)

WEBページ:https://www.sapientica.com/success/

上記のサイトから、開成中学校 麻布中学校 武蔵中学校 桜蔭中学校 女子学院の合格者数を抽出したいです。
以下のコードで実行しても数値が0でしか返されません。
VBA初心者であり、知識不足だと思います。
どなたかご協力お願いします。

Sub Getサピ御三家()

    Dim html As String, msg As String
    Dim 中学() As String, l As Long, i As Long
    Dim http As Object

    中学 = Split("開成中学校 麻布中学校 武蔵中学校 桜蔭中学校 女子学院中学校 雙葉中学校")
    Set http = CreateObject("MSXML2.XMLHTTP")
    http.Open "GET", "https://www.sapientica.com/success/"
    http.send
    Do While http.readyState < 4
        DoEvents
    Loop
    html = http.responseText
    For i = LBound(中学) To UBound(中学)
        l = InStr(html, ">" & 中学(i) & "<")
        l = InStr(l, html, "<span class = badge>") + 3
        msg = msg & 中学(i) & ":" & vbTab & Val(Mid(html, l, 4)) & vbLf
    Next
    Set http = Nothing
    MsgBox msg
End Sub

< 使用 Excel:Excel2016、使用 OS:Windows10 >


 こうじゃないのかな。    
 Sub Getサピ御三家()
     Const myStr As String = "<span class=""badge"">"
     Dim html As String, msg As String
     Dim 中学() As String, l As Long, i As Long, l2 As Long
     Dim http As Object

     中学 = Split("開成中学校 麻布中学校 武蔵中学校 桜蔭中学校 女子学院中学校 雙葉中学校")
     Set http = CreateObject("MSXML2.XMLHTTP")
     http.Open "GET", "https://www.sapientica.com/success/", False 'Falseで同期処理となる
     http.send
     html = http.responseText
     For i = LBound(中学) To UBound(中学)
         l = InStr(html, ">" & 中学(i) & "<")
         l2 = InStr(l + 1, html, myStr) + Len(myStr)
         msg = msg & 中学(i) & ":" & vbTab & Val(Mid(html, l2, 4)) & vbLf
     Next
     Set http = Nothing
     Debug.Print msg 'イミディエイトウインドウに出力
 End Sub

(γ) 2022/02/15(火) 12:25


ご回答ありがとうございます。
実行するとうまく抽出されました。
まだ理解できていないので一旦自分で調べたりしてみます。
理解できない個所あればまた質問させてください。
本当にご協力ありがとうございます。
(jnk) 2022/02/15(火) 13:08

お疲れ様です。
上記回答頂いたコード自分なりに調べたり考えたのですが以下がわかない点と自分の考えている大まかな流れになります。
VBA今月より勉強始めたレベルですので、レベル低いですがご容赦ください。

流れ理解確認
・中学という変数に調べたい文字列を配列として格納
・http変数にウェブページの情報を格納
・ウェプページ内で配列内の文字列開始位置を調べる
この後のコードが理解できていません、、、

l2 = InStr(l + 1, html, myStr) + Len(myStr)
上記の説明&流れに関してどなたか再度ご教授お願い致します。
(jnk) 2022/02/16(水) 15:56


+1には合理性はありません。
同じ文字列を検索する時の慣習が残ってしまったものです。
そこだけですよね、わかりにくいのは。

(γ) 2022/02/16(水) 16:22


ご回答ありがとうございます。

l2 = InStr(l + 1, html, myStr) + Len(myStr)
こちらのコードって+ Len(myStr)で数値の値取得しているのでしょうか?
すいません何度も質問、理解力なく、、
(jnk) 2022/02/16(水) 16:51


 では少し補足説明します。
       <dt class="list-sname">開成中学校</dt>
       <dd class="list-sgoukaku"><span class="badge">282</span></dd>
 というようなHTMLソースがありますね。

 ・最初に">開成中学校<"にマッチする位置を調べ
 ・その次に、その位置(+1は不要だった)を検索の開始位置とし、
   myStr(つまり、<span class="badge">)を検索します。
 ・l2 = InStr(l + 1, html, myStr) + Len(myStr)の
   InStr(l + 1, html, myStr)は、
   <span class="badge">の最初の文字の位置を示します。
  ↑ ここです。 
   (なお、検索スタート点からのカウントではなく、文字列の最初からの位置であることに注意。)
   これにLen(myStr)を加えると、
  <span class="badge">282 の2の位置を指します。
                      ↑ここです
 ・Val(Mid(html, l2, 4))によって、
   282< を数値化して 282を得ます。

 最初のコードでまずいのは、
 検索文字列が
 <span class = badge>
 とスペースや"の有無が適切ではなかったこと。

 ------
 なお、
 http.Openの第三引数は、非同期設定ですので、これを Falseにすると
 同期処理(つまり、send実行の結果が返って来るまで、処理を待ち、
 次のコード実行には進まない)となり、処理待ちのコードは不要ということになります。
(γ) 2022/02/16(水) 17:15

お疲れ様です。
上記の回答本当に丁寧でわかりやすいく感謝しかありません。
かなり理解が進みました。
VBA初心者ですが、会社の業務に横展開できるようにと思い取り組んでいますが難しすぎて心折れそうでした、、
改善案を提案するまで勉強継続します
(回答頂いたすべての方に感謝です)

(jnk) 2022/02/16(水) 18:40


回答したのは私だけですww。
γと、
 γのフォントが違うだけです。
(γ) 2022/02/16(水) 19:02

フォントの違いだったんですね、、
恥ずかしい、失礼しました、、、
追加で質問なのですが、下記のサイトから上記のように人数を抽出したいです。
URL後のコードだとエラーがでます。
他のサイトで教えて頂いたものを基にコードいじったら数値とれるものもありました。
下記サイトの場合はなぜ値をとれないのでしょうか?
お手すきの際にご確認お願い致します。

https://www.ichishin.co.jp/lp/pass-record/es/sokuhou.html

Sub Get市進()

     Const myStr As String = "<span class= ""red-l3"" >"
     Dim html As String, msg As String
     Dim 中学() As String, l As Long, i As Long, l2 As Long
     Dim http As Object
     中学 = Split("市川中 栄東中 開智中 渋谷幕張中")
     Set http = CreateObject("MSXML2.XMLHTTP")
     http.Open "GET", "https://www.ichishin.co.jp/lp/pass-record/es/sokuhou.html", False 'Falseで同期処理となる
     http.send
     html = http.responseText
     For i = LBound(中学) To UBound(中学)
         l = InStr(html, ">" & 中学(i) & "<")
         l2 = InStr(l, html, myStr) + Len(myStr)
         msg = msg & 中学(i) & ":" & vbTab & Val(Mid(html, l2, 4)) & vbLf
     Next
     Set http = Nothing
     MsgBox msg
 End Sub

(jnk) 2022/02/18(金) 12:18


htmlには何が入っていますか?ローカルウインドウで確認していますか?

(γ) 2022/02/18(金) 13:05


 responseTextには返さず、responseBodyにのみ返す仕組みをとっているようです。
 以下のようにしてください。
 # 昔書いたコードから一部をとってきているので、今どきはもっと気の利いたものがあるのかもしれません。

 Sub Get市進()
      Const myStr As String = "<span class=""red-l3"">"  '■修正しています
      Dim html As String, msg As String
      Dim 中学() As String, l As Long, i As Long, l2 As Long
      Dim http As Object

      中学 = Split("市川中 栄東中 開智中 渋谷幕張中")
      Set http = CreateObject("MSXML2.XMLHTTP")
      http.Open "GET", "https://www.ichishin.co.jp/lp/pass-record/es/sokuhou.html", False 'Falseで同期処理となる
      http.send

      html = getHtml(http)
      For i = LBound(中学) To UBound(中学)
          l = InStr(html, ">" & 中学(i) & "<")
          l2 = InStr(l, html, myStr) + Len(myStr)
          msg = msg & 中学(i) & ":" & vbTab & Val(Mid(html, l2, 4)) & vbLf
      Next
      Set http = Nothing
      Debug.Print msg
 End Sub
 Function getHtml(HttpRequest As Object) As String
     Const adTypeBinary = 1
     Const adTypeText = 2
     Const adSaveCreateOverWrite = 2

     Dim Strm As Object
     Set Strm = CreateObject("ADODB.Stream")
     With Strm
         .Open
         .Type = adTypeBinary
         .Write HttpRequest.responseBody
         .Position = 0
         .Type = adTypeText
         .Charset = "UTF-8"
         getHtml = .ReadText()
         .Close
     End With
 End Function

 ちなみに、
      Const myStr As String = "<span class= ""red-l3"" >"
 としていますが、余計な空白が混じっています。よく確認してください。
 これは、人間がノートに手書きする文字なら、他の人は忖度して理解してくれますが、
 機械はそうした機転は利きません。別の文字列と認識されます。
 前回にも指摘しているはずですが? 適当に聞き流しています?     

 なお、こうしたことを本格的にするのであれば、外注したほうが早いし、
 アフターサービスも期待できるでしょう。コストは少しかかりますが。

 # 外出しますので、しばらくアクセスできません。

(γ) 2022/02/18(金) 14:16


ご返信ありがとうございます。
文字の空白の2度目のご指摘失礼しました。
昔書いたコードから一部とってきているんですね、、(そんなパターンあるんですね、、、)
だから ctrl+u でコードみたときと、F12で該当箇所のコードみたときにぱっと同じ記載がみつけれなかっんですね、、、

頂いたコード勉強します。
今回のはかなり難しそうですが、、

(Y)様のおかげで今回のようなサイト以外に関しては値とれるのでかなり業務効率改善しました
ありがとうございます。
(jnk) 2022/02/18(金) 16:07


コメント返信:

[ 一覧(最新更新順) ]


YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki. Modified by kazu.