onchange和onclick不能始终如一地工作

时间:2018-11-02 08:17:53

标签: javascript excel vba web scrape

我正在尝试从网页上抓取数据。在此过程中,我需要更改以下一项 该网页的下拉菜单。我能够做到这一点。但是当我手动更改 下拉菜单中,网页会更改其内容,例如图片和其他一些文字。但是当我这样做 使用VBA不会这样做。我测试了我的代码几次。所以如果我运行程序10 它将更改内容1或2次。所以我对发生的事情感到困惑

这是该下拉区域的HTML。

<tbody>
<tr>
<td class="label"><label for="pa_product">Product</label></td>
<td class="value"><select id="pa_product" name="attribute_pa_product" data-attribute_name="attribute_pa_product">
<option value="">Choose an option…</option>
<option value="air-xs-2-octo-16-inch" class="attached enabled">AIR XS 2 Octo 16 Inch</option>
<option value="air-xs-2-octo-18-inch" class="attached enabled">AIR XS 2 Octo 18 Inch</option>
<option value="air-xs-2-octo-20-inch" class="attached enabled">AIR XS 2 Octo 20 Inch</option>
</select> <a class="reset_variations" href="#reset">Clear selection</a></td>
</tr>
</tbody>

这是我开发的代码。我认为onchange和onclick很少起作用。

    Do
    DoEvents
    Loop Until objIE.readystate = 4

    'Body(HTML)
    'MsgBox objIE.document.getElementById("tab-description").outerHTML, , "OHTML"
    'MsgBox objIE.document.getElementById("tab-description").innerHTML, , "IHTML"
    'MsgBox objIE.document.getElementById("tab-description").innerText, , "ITex"
    WS.Range("D" & i).Value = objIE.document.getElementById("tab-description").outerHTML

    'Option 1 value
    'MsgBox objIE.document.getElementById("pa_product").outerHTML
    'MsgBox objIE.document.getElementById("pa_product").innerHTML
    'MsgBox objIE.document.getElementById("pa_product").innerText


    objIE.document.getElementById("pa_product").selectedindex = 1
    Application.Wait (Now + TimeValue("0:00:01"))
    'modify the web page for that selected item
    'For x = 1 To 5
    'objIE.document.getElementById("pa_product").selectedindex = 1
    Application.Wait (Now + TimeValue("0:00:03"))
    objIE.document.getElementById("pa_product").FireEvent ("onchange")
    objIE.document.getElementById("pa_product").FireEvent ("Onclick")
    objIE.document.getElementById("pa_product").FireEvent ("onmousedown")
    'Next x

    Application.Wait (Now + TimeValue("0:00:03"))

    WS.Range("J" & i).Value = objIE.document.getElementById("pa_product").Item(1).innerText

onchange and onclick not work consistantly

首先,我使用了一个事件。但是没有成功。因此,我尝试使用这样发现的所有事件。 FireAllEvents(objIE.document.getElementById(“ pa_product”))函数FireAllEvents(ByRef objHTML)

Function FireAllEvents(ByRef objHTML)
With objHTML
    .FireEvent ("onblur")
    .FireEvent ("onchange")
    .FireEvent ("oncontextmenu")
    .FireEvent ("onfocus")
    .FireEvent ("oninput")
    .FireEvent ("onreset")
    '.FireEvent ("onsearch")
    .FireEvent ("onkeydown")
    .FireEvent ("onkeypress")
    .FireEvent ("onkeyup")
    .FireEvent ("onclick")
End With
End Function

然后我这样调用此函数

    FireAllEvents (objIE.document.getElementById("pa_product"))

    Application.Wait (Now + TimeValue("0:00:03"))

    WS_Oceanic.Range("J" & i).Value = objIE.document.getElementById("pa_product").Item(1).innerText
    objIE.document.getElementById("pa_product").Click   

但是它也不起作用。
非常感谢你。

2 个答案:

答案 0 :(得分:0)

使用VBA的硒基本包装器,这非常容易。安装selenium basic后,您可以通过VBE>工具>引用

添加对Selenium类型库的引用
Option Explicit
Public Sub MakeSelection()
    Dim d As WebDriver
    Set d = New ChromeDriver
    Const URL = "https://oceanicaus.com.au/products/oceanic-airxs-2-octopus/"

    With d
        .Start "Chrome"
        .get URL
        .FindElementById("pa_product").AsSelect.SelectByIndex 1   'You can also use  .SelectByText

        Stop
        .Quit
    End With
End Sub

答案 1 :(得分:0)

有时候,您需要关注和不关注某个元素,以便它能够吸收一些事件,所以我发现了。尽管仅进行了几次测试,但以下代码对我来说一直可靠地工作。

除了使用选定的索引,您还可以使用选项的值来设置选择值,这是我在下面所做的事情。

Public Sub SOTest()
    Dim ie      As Object: Set ie = CreateObject("InternetExplorer.Application")
    Dim ele     As Object
    Const url   As String = "https://oceanicaus.com.au/products/oceanic-airxs-2-octopus"

    With ie
        .Navigate url
        .Visible = True

        Do Until .readystate = 4 And Not .busy
            DoEvents
        Loop

        Set ele = .document.getElementByID("pa_product")

        With ele
            .Focus
            .Value = "air-xs-2-octo-16-inch"
            .fireEvent ("onChange")
            .document.getElementsByTagName("button")(0).Focus
        End With

    End With
End Sub