没有 ID 或名称的 VBA IE 自动化

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24595288/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-12 03:43:04  来源:igfitidea点击:

VBA IE Automation without ID or Name

htmlvbainternet-explorer

提问by user3809423

I am trying to use VBA to automate input of Username/Password on a form that doesn't have any ID or Name to it. Is this possible?

我正在尝试使用 VBA 在没有任何 ID 或名称的表单上自动输入用户名/密码。这可能吗?

Have a look at the sample webpage. This webpage doesn't work with the names from what I can tell.

查看示例网页。这个网页不能使用我所知道的名字。

VBS code:

VBS 代码:

uname = "myusername"
pword = "mypassword"

Set objIE = CreateObject("InternetExplorer.Application")
WebSite = "https://cis.mesaaz.gov/eservices/p_template"
With objIE
  .Visible = True
  .Navigate WebSite
    Do While .Busy Or .ReadyState <> 4
        DoEvents
    Loop

    Set element = .Document.getElementsByName("userid")
    element.Item(0).Value = uname

    Set element = .Document.getElementsByName("ping")
    element.Item(0).Value = pword

    Set element = .Document.getElementsByName("submit")(0)
    element.Click

    Do While .Busy Or .ReadyState <> 4
        DoEvents
    Loop

End With

Form HTML code:

表单 HTML 代码:

<form action="uwpqutil.p_VALLOGIN" method="POST" target="_top" name="Login">
<center>
<table border="0" cellpadding="3" cellspacing="0">
<tbody><tr>
<td rowspan="1" colspan="3" align="LEFT"><b>Log-In</b></td>
</tr>
<tr>
<td valign="middle"><b>UserName</b></td>
<td valign="middle"><input name="userid" size="30" type="text"></td>
<td>&nbsp;</td>
</tr>
<tr>
<td valign="middle"><b>Password</b></td>
<td valign="middle"><input name="pin" size="30" type="password"></td>
<input name="JavaScript" value="enabled" type="hidden">
<script language="JavaScript"><!--
document.Login.JavaScript.value = 'enabled';
//--></script>
<td>&nbsp;</td>
</tr>
<tr>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td valign="middle" align="right"><input value="Log-In" type="submit"></td>
</tr>
</tbody></table>
</center>
</form>

回答by Palec

Errors seen right away

立即看到的错误

From what I can see immediately, you are getting input named pinginstead of pinand .Document.getElementsByName("submit")returns no elements because there is no element with name submit.

从我立即看到的情况来看,您将输入 namedping而不是pin并且不.Document.getElementsByName("submit")返回任何元素,因为没有带有 name 的元素submit

You could instead use getElementsByTagName("input")and loop through the result to find the correct one, or you can get the form itself via getElementsByName("Login")and use its Submitmethod.

您可以改为使用getElementsByTagName("input")并遍历结果以找到正确的结果,或者您可以通过获取表单本身getElementsByName("Login")并使用其Submit方法。

Also there is no DoEventsfunction in VBS. Instead, you should use WScript.Sleepwith reasonable number of milliseconds as argument (I suggest 100). (Assuming WScriptobject is available. There are circumstances it is not.)

DoEventsVBS中也没有功能。相反,您应该使用WScript.Sleep合理的毫秒数作为参数(我建议使用 100)。(假设WScript对象可用。也有不可用的情况。

Deeper-rooted error

根深蒂固的错误

However, there is also a more fundamental error in your code. The page you request does not contain the form. It contains only frames definition. If you change WebSiteto

但是,您的代码中还有一个更根本的错误。您请求的页面不包含该表单。它只包含框架定义。如果你WebSite改为

WebSite = "https://cis.mesaaz.gov/eservices/p_UWGPDYNA"

it starts working, but does not load other frames.

它开始工作,但不加载其他帧。

uname = "myusername"
pword = "mypassword"

Set objIE = CreateObject("InternetExplorer.Application")
WebSite = "https://cis.mesaaz.gov/eservices/p_UWGPDYNA"
With objIE
    .Visible = True
    .Navigate WebSite
    Do While .Busy Or .ReadyState <> 4
        WScript.Sleep 100
    Loop

    With .Document
        .getElementsByName("userid")(0).Value = uname
        .getElementsByName("pin")(0).Value = pword
        .getElementsByName("Login")(0).Submit
    End With

    Do While .Busy Or .ReadyState <> 4
        WScript.Sleep 100
    Loop
End With

If you want to load them too, you have to keep the original URL, select the correct frame and work on its ContentDocument. The code I finished with:

如果您也想加载它们,则必须保留原始 URL,选择正确的框架并处理其ContentDocument. 我完成的代码:

uname = "myusername"
pword = "mypassword"

Set objIE = CreateObject("InternetExplorer.Application")
WebSite = "https://cis.mesaaz.gov/eservices/p_template"
With objIE
    .Visible = True
    .Navigate WebSite
    Do While .Busy Or .ReadyState <> 4
        WScript.Sleep 100
    Loop

    With .Document.getElementsByName("main")(0).ContentDocument
        .getElementsByName("userid")(0).Value = uname
        .getElementsByName("pin")(0).Value = pword
        .getElementsByName("Login")(0).Submit
    End With

    Do While .Busy Or .ReadyState <> 4
        WScript.Sleep 100
    Loop
End With

Non-related errors

非相关错误

You should improve your HTML markup and fix JavaScript detection.

您应该改进 HTML 标记并修复 JavaScript 检测。

Now the JavaScriptinput always contains enabled. Its default value should be disabledand it should be changed to enabledby JavaScript.

现在JavaScript输入总是包含enabled. 它的默认值应该是disabled并且应该被enabledJavaScript更改为。

The markup itself should be at least stripped from elements and attributes taking care of formatting. This should be done in CSS. The style you are using is from the '90s when CSS has not been around. Also you should validate you markup(it matters). The headis repeated after the body. The frame definition document has scriptbefore htmlelement, it should be in head. Errors like that may make your pages behave strangely.

标记本身至少应该从处理格式的元素和属性中剥离出来。这应该在 CSS 中完成。您使用的样式来自 90 年代,那时 CSS 还没有出现。此外,您应该验证您的标记这很重要)。在head之后重复body。框架定义文件有scriptbeforehtml元素,它应该在head. 类似的错误可能会使您的页面行为异常。