Winform应用程序 - 网页交互

6

Windows窗体应用程序 - 操纵WinForm WebBrowser中的输入元素

虽然我熟悉使用HttpWebResponse/HttpWebRequest登录网站,但现在我正在尝试使用mshtml库,并发现了一些奇怪的行为。我想看看是否有人能够在这里帮助我解决问题。

我有一个带有java后端的HTML登录页面,其中包含一个用户名字段、一个密码字段和一个按钮

逻辑非常基本,我建立了一个带有内置web浏览器的winform应用程序。在Document_Completed事件中,我使用以下代码输入我的设置并单击按钮。

private void webBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
    if (webBrowser.Url.ToString() == @"MyWebPage/signin")            
    {
        HTMLDocument hdc = new HTMLDocumentClass();
        hdc = (HTMLDocument)webBrowser.Document.DomDocument;

        IHTMLElement elb = hdc.getElementById("login_button");
        IHTMLInputElement elu = (IHTMLInputElement)hdc.getElementById("username");
        IHTMLInputElement elp = (IHTMLInputElement)hdc.getElementById("password");

        try
        {
            elu.value = "MyID";
            elp.value = "MyPwd";
            elb.click();
        }
        catch { }
    }
}

除了这段代码非常快且没有错误处理之外,它应该可以解决问题,而且部分地解决了问题。
有两种情况: 1. 我启动工具,它加载网页。 - 工具正确填充了UserID字段和Password字段; - 工具无法点击按钮。 2. 我手动单击按钮,登录后退出,回到登录页面。 - 我立即重新登录,工具输入信息; - 工具立即也单击了按钮。
有人能否向我解释为什么会出现这种情况以及如何在当前设置下解决这个问题(因此不使用HttpWebRequest)。我看不出在启动时加载页面和在注销后重定向之间的区别,但显然存在区别,或者我做错了什么。
非常感谢您对此事的任何反馈。
谢谢, Kevin
编辑: 我在我的Windows表单中添加了一个按钮,该按钮与下面相同的后端代码,以便单击网页上的按钮,这很完美。
我在webBrowser_Completed事件中触发单击此按钮,但它不起作用。由于某种原因,我添加到webBrowser_DocumentCompleted事件的所有内容都不允许我触发WebBrowser控件中按钮的单击事件。一旦整个事件完成,如果我尝试触发它,则会起作用,但我想自动化此过程。有什么建议吗?

似乎你不应该在第一个场景中点击“文档完成”。但是让我问一下,你为什么需要它呢?也许我可以提供替代方法。 - Regfor
Regfor,这是我们在工作中构建的应用程序,逻辑使用了大量的HTML交互,我试图保持相同的线路。但我始终乐于接受建议。谢谢。 - XikiryoX
1
好的,我之前以为这是一种用于Web测试或测试工具。使用WebBrowser与DOM进行交互有很多未记录的陷阱。因此,当我需要像您在Web测试或Web自动化上所做的事情时,我就会使用Watin http://watin.org/。 - Regfor
1
你有没有尝试在文档完成函数中添加延迟?给它一个大约2秒的延迟...然后尝试触发点击事件! - Ovais Khatri
1
@KevinLaerte Watin已经开源,因此您可以查看他们已经解决了哪些相同的问题。http://watin.svn.sourceforge.net/viewvc/watin/ - Regfor
显示剩余4条评论
2个回答

3
这可能是一个冒险且不太优雅的解决方法,但是请考虑在您的DocumentCompleted事件中让一个后台工作线程运行一秒钟,然后触发您从该线程点击的按钮。这可能会使自动化变得更加流畅。
由于这将从不同的线程中运行,请记住您可能需要调用某些控件,因此这可能是此解决方法的另一个缺点。
如果这种方法不起作用,则可以像Regfor之前建议的那样使用Watin.org。

它确实有效,我在一个后台工作器里设置了一个大约一秒钟的休眠,然后触发了我在窗体上的button_onlcick事件,它完美地运行了。这确实是一个变通方法,而且我真的很想弄清楚为什么会发生这种情况,但至少现在我可以先继续开发应用程序的其他部分了。非常感谢。 - XikiryoX

3
这个怎么样:
HtmlElement button = webBrowser.HtmlDocument.GetElementById("login_button");
button.InvokeMember("click");

它在我的程序中工作。


谢谢,我会尝试并保持联络。 - XikiryoX
我尝试了一下,但问题仍然存在。当我打开我的应用程序并且页面加载时,它填写了用户详细信息但无法点击按钮。我手动单击它,我登录了。在我的应用程序中的网站上,我单击注销,页面会将我重定向回登录界面,大约2秒钟后我重新登录,因为它执行了它应该执行的操作。我真的很难弄清楚这两种情况之间的区别。感谢反馈。 - XikiryoX
您可以检查按钮是否真正是“login_button”。 - Yunfei.Xiao
刚刚通过调试器检查了一下,它确实是正确的按钮,因为我可以更改其上的文本,这个功能是正常的,只是onclick事件不起作用。但是当我在工具中被注销时,它确实能够自动连接,所以它确实执行了它,但在主要启动时没有执行。正如Ovais建议的那样,我将尝试添加一个超时。 - XikiryoX
你写下的逻辑应该是有效的,它做了差不多相同的事情,我认为这确实与网页相关。感谢您的反馈。 - XikiryoX

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接