tagCANDY CGI VBレスキュー(花ちゃん) の Visual Basic 2010 用 掲示板(VB.NET 掲示板) [ツリー表示へ]   [Home]
一括表示(VB.NET VB2005)
タイトルjavascriptで生成されるリストをwebbrowserから操作できない
記事No11450
投稿日: 2015/06/30(Tue) 17:42
投稿者まゆぱん
現在Windows7、VB2008で下記のようなサイトを自動で操作するプログラムを作成しております。
WebBrowserのバージョンはIE11を使用しています。

http://nsoyi.pw/test/

自動操作の内容は以下の流れを考えています。

@ 上記テストサイトでラジオボタン2をクリックしてリストボックス3つ(大分類・中分類・小分類)を表示させる。
A 大分類を選択する→javascriptで自動的に中分類が表示される。
B 中分類を選択する→javascriptで自動的に小分類が表示される。
C 小分類を選択する。


@はできたのですが、Aで大分類を選択しても中分類が表示されません。
(ウェブブラウザー上で手動で大分類をクリックすると中分類が表示されるのですが、プログラムで選択すると表示されません・・・)


ちなみに下記ソース内の
 hecTags2(0).SetAttribute("value", "2078297513") '【選択箇所】
  を
 hecTags2(0).Children(1).SetAttribute("selected", "true")
  や
 hecTags2(0).Children(1).InvokeMember("click")
  に変えてもうまくいきませんでした。


説明が下手で申し訳ないのですが、
どなたかお知恵をお貸し頂けると幸いです。
宜しくお願い致します。


============ ソースです ===============

Public Class Form1

    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        Me.WebBrowser1.Navigate("http://nsoyi.pw/test/") '←URLの先頭にhを追加して下さい。
    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim hecTags As HtmlElementCollection
        Dim hecTags2 As HtmlElementCollection
        Dim strData As String

        '「ラジオボタン2」をクリック
        hecTags = Me.WebBrowser1.Document.GetElementsByTagName("div")
        For Each objTag As HtmlElement In hecTags
            strData = objTag.GetAttribute("classname")
            If String.Compare(strData, "main_category") = 0 Then
                hecTags2 = objTag.GetElementsByTagName("input")
                For Each objTag2 As HtmlElement In hecTags2
                    strData = objTag2.GetAttribute("value")
                    If String.IsNullOrEmpty(strData) Then
                        objTag2.InvokeMember("Click")
                        Exit For
                    End If
                Next
                Exit For
            End If

        Next objTag

    End Sub

    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        Dim hecTags As HtmlElementCollection
        Dim hecTags2 As HtmlElementCollection
        Dim strData As String

        '大分類を選択
        hecTags = Me.WebBrowser1.Document.GetElementsByTagName("div")
        For Each objTag As HtmlElement In hecTags
            strData = objTag.GetAttribute("classname")
            If String.Compare(strData, "main_category") = 0 Then
                hecTags2 = objTag.GetElementsByTagName("select")
                For Each objTag2 As HtmlElement In hecTags2
                    If hecTags2.Count >= 3 Then

                        hecTags2(0).SetAttribute("value", "2078297513") '【選択箇所】
                        hecTags2(0).RaiseEvent("onChange")

                    End If
                Next
                Exit For
            End If

        Next objTag

    End Sub

End Class

[ツリー表示へ]
タイトルRe: javascriptで生成されるリストをwebbrowserから操作できない
記事No11451
投稿日: 2015/07/01(Wed) 11:32
投稿者まゆぱん
言葉足らずですみません。

ソースの
「Button1_Click」内の処理が自動操作の@に、
「Button2_Click」内の処理が自動操作のAに
それぞれ対応しています。
(B、Cは未作成です)

ですが現状Button2をクリックして大分類を選択しても中分類が表示されません。
プログラムから大分類を選択して、それに応じた中分類を表示させる事はできるのでしょうか?

[ツリー表示へ]
タイトルRe: javascriptで生成されるリストをwebbrowserから操作できない
記事No11452
投稿日: 2015/07/01(Wed) 19:00
投稿者魔界の仮面弁士
> WebBrowserのバージョンはIE11を使用しています。

既定では IE7 モードのはずですが、意図的に IE11 モードに変更して利用されているのですね。
エミュレーションモードは 11001 でしょうか、11000 でしょうか?
https://msdn.microsoft.com/en-us/library/ee330730%28vs.85%29.aspx#browser_emulation



> 大分類を選択しても中分類が表示されません。
select 要素の onchange は、「利用者が操作して選択肢が変更された時」に発生する
イベントだからです。プログラムから変更した場合には、onchange は発生しません。

https://msdn.microsoft.com/en-us/library/ms536912.aspx
》 To invoke this event, do one of the following:
》 ・Choose a different option in a select object using mouse or keyboard navigation.
》 ・Alter text in the text area and then navigate out of the object.



> どなたかお知恵をお貸し頂けると幸いです。
たとえばこんな感じでしょうか。タグの選択方法はかなり端折っているので、適宜修正してください。


''' <summary>
''' ラジオボタン2を選択
''' </summary>
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As EventArgs) Handles Button1.Click
 Dim doc = Me.WebBrowser1.Document

 Dim radio2 = doc.GetElementsByTagName("INPUT")(1)
 radio2.SetAttribute("checked", "checked")
 radio2.InvokeMember("click")    'クリックイベントを誘発
End Sub

''' <summary>
''' 大分類を選択
''' </summary>
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As EventArgs) Handles Button2.Click
 Dim doc = Me.WebBrowser1.Document

 Dim select1 = doc.GetElementsByTagName("SELECT")(0)

 'デフォルトの動作モードであれば、この方法で動作しますが、
 '今回は IE11 モードとのことなので、この方法では動作しません
 'Dim listItem = select1.Children.OfType(Of HtmlElement).FirstOrDefault(
 '   Function(opt) opt.GetAttribute("value") = "2078297513")
 'select1.SetAttribute("selectedIndex", listItem.GetAttribute("index"))
 ''listItem.SetAttribute("selected", "selected")
 'select1.RaiseEvent("onchange")
 
 'IE11 モードの場合は、ユーザー操作をエミュレートすることで代用して下さい
 select1.Focus()
 SendKeys.Send(Space(1))
End Sub

-----

IE7 モードであれば、<OPTION> の selected で選択しても、<SELECT> の selectedIndex で選択しても
.RaiseEvent("onchange") が使えるのですが、IE8 モードで .RaiseEvent("onchange") する場合は
<SELECT> の selectedIndex を使って選択する必要があります。

IE9〜IE11 モードの場合は、そもそも .RaiseEvent("onchange") すら使えないため、
キーボード操作もしくはマウス操作をエミュレートする必要があります。


なお、現在のブラウザバージョンを確認する場合は
http://www.useragentstring.com/
を表示させてみると良いでしょう。

[ツリー表示へ]
タイトルRe^2: javascriptで生成されるリストをwebbrowserから操作できない
記事No11453
投稿日: 2015/07/01(Wed) 22:30
投稿者まゆぱん
>魔界の仮面弁士さん

ご回答ありがとうございます!
いつも色んなQAの回答を参考にさせて頂いています。


> 既定では IE7 モードのはずですが、意図的に IE11 モードに変更して利用されているのですね。
> エミュレーションモードは 11001 でしょうか、11000 でしょうか?

仰るとおりです。 IE11 でないと正常に表示されないサイトを扱うため IE11 モードに変更しています。
エミュレーションモードは 11001 を使用しています。


> select 要素の onchange は、「利用者が操作して選択肢が変更された時」に発生する
> イベントだからです。プログラムから変更した場合には、onchange は発生しません。
>
> https://msdn.microsoft.com/en-us/library/ms536912.aspx
> 》 To invoke this event, do one of the following:
> 》 ・Choose a different option in a select object using mouse or keyboard navigation.
> 》 ・Alter text in the text area and then navigate out of the object.
>
>  'デフォルトの動作モードであれば、この方法で動作しますが、
>  '今回は IE11 モードとのことなので、この方法では動作しません
>  'Dim listItem = select1.Children.OfType(Of HtmlElement).FirstOrDefault(
>  '   Function(opt) opt.GetAttribute("value") = "2078297513")
>  'select1.SetAttribute("selectedIndex", listItem.GetAttribute("index"))
>  ''listItem.SetAttribute("selected", "selected")
>  'select1.RaiseEvent("onchange")
>  
>  'IE11 モードの場合は、ユーザー操作をエミュレートすることで代用して下さい
>  select1.Focus()
>  SendKeys.Send(Space(1))
> -----
>
> IE7 モードであれば、<OPTION> の selected で選択しても、<SELECT> の selectedIndex で選択しても
> .RaiseEvent("onchange") が使えるのですが、IE8 モードで .RaiseEvent("onchange") する場合は
> <SELECT> の selectedIndex を使って選択する必要があります。
>
> IE9〜IE11 モードの場合は、そもそも .RaiseEvent("onchange") すら使えないため、
> キーボード操作もしくはマウス操作をエミュレートする必要があります。
>
> なお、現在のブラウザバージョンを確認する場合は
>  http://www.useragentstring.com/
> を表示させてみると良いでしょう。

非常にわかりやすく丁寧に教えて頂きありがとうございました。
IE のモードによってこんなにも挙動が違うんですね。とても勉強になりました。
(Linqで記述すると1行でまとめられてスッキリしますね、これも使えるように勉強したいと思います!)

IE8 モードにしたところ意図した動作をしてくれたのですが、やはりサイトが正しく表示されないので、
IE11 モードでキーボード操作をエミュレートする方法で作っていこうと思います。

[ツリー表示へ]