4

我正在做一个项目,我必须制作一个可以从用户那里获取文本框中的 URL 的 Windows 应用程序。现在,当用户按下“继续”按钮时,应用程序应在 Web 浏览器控件中打开该 URl,并在该页面上填写包含用户 ID 和密码文本框的表单,并通过该网页上的登录按钮提交。现在我的应用程序应该向用户显示该 webbrowser 控件中的下一页。

我可以通过我的 C# 代码在应用程序的 webbrowser 控件中打开 url,但我不知道如何在我的应用程序的 webbrowser 控件中当前打开的那个网页上找到用户 ID 和密码文本框,如何填写它们,如何找到登录按钮以及如何通过我的 C# 代码单击它。

4

4 回答 4

6

为此,您必须查看第 3 方站点的页面源并找到用户名、密码文本框和提交按钮的 ID。(如果您提供链接,我会为您检查)。然后使用此代码:

//add a reference to Microsoft.mshtml in solution explorer
using mshtml;

private SHDocVw.WebBrowser_V1 Web_V1;

Form1_Load()
{
    Web_V1 = (SHDocVw.WebBrowser_V1)webBrowser1.ActiveXInstance;
}

webBrowser1_Document_Complete()
{
if (webBrowser1.ReadyState == WebBrowserReadyState.Complete)
    {
        if (webBrowser1.Url.ToString() == "YourLoginSite.Com")
        {
            try
            {
                HTMLDocument pass = new HTMLDocument();
                pass = (HTMLDocument)Web_V1.Document;
                HTMLInputElement passBox = (HTMLInputElement)pass.all.item("PassIDThatyoufoundinsource", 0);
                passBox.value = "YourPassword";
                HTMLDocument log = new HTMLDocument();
                log = (HTMLDocument)Web_V1.Document;
                HTMLInputElement logBox = (HTMLInputElement)log.all.item("loginidfrompagesource", 0);
                logBox.value = "yourlogin";
                HTMLInputElement submit = (HTMLInputElement)pass.all.item("SubmitButtonIDFromPageSource", 0);
                submit.click();
            }
            catch { }
        }
    }
}
于 2013-07-09T02:06:10.563 回答
5

我会使用Selenium而不是 WebBrowser 控件。

它有一个优秀的 C# 库,而这种东西是它被开发的主要原因。

于 2013-07-08T14:54:13.623 回答
1

您不必模拟填写用户名/密码字段,也不必单击登录按钮。您需要模拟浏览器而不是用户。

读取登录页面 html 并解析它以找到用户名和密码字段的 id。用户名可以通过查找名称设置为“username”、“user”、“login”等的标签来获取。密码通常是 type="password" 的标签。用于登录的基于 Javascript 的弹出面板将涉及解析 js。

然后按照此处显示的示例代码,如何以编程方式填写表单并“发布”网页?

于 2013-07-08T21:14:03.850 回答
1

这里重要的是您正在模拟浏览器 POST 事件。不用担心文本框和其他可视表单元素,您的目标是使用适当的键值对生成 HTTP POST 请求。

您的第一步是查看您所伪装的页面的 HTML,并找出用户 ID 和密码表单元素的名称。因此,假设它们分别被称为“txtUsername”和“txtPassword”,那么浏览器(或用户代理)将在其 POST 请求中发送的 post 参数将类似于:

txtUsername=fflintstone&txtPassword=ilikerocks

作为这方面的背景,您可能想对 HTTP 的工作原理进行一些研究。但我会把它留给你。

另一件重要的事情是弄清楚它将这个登录请求发布到哪个 URL。通常,这是您登录时浏览器地址栏中显示的内容,但也可能是其他内容。您需要检查表单元素的 action 属性,以便查看它的去向。

下载 Fiddler2 的副本可能很有用。是的,奇怪的名字,但它是一个很棒的 Web 调试工具,它基本上充当代理并捕获浏览器和远程主机之间的所有内容。一旦你弄清楚如何使用它,你就可以将每个请求-响应分开,看看发生了什么。它会为您提供被调用的 URL、请求的类型(通常是 GET 或 POST)、请求参数以及响应的全文。

现在,您想要构建您的应用程序。您需要构建发出正确 HTTP 请求的逻辑,传入表单参数并取回结果。幸运的是,System.Net.HttpWebRequest 类将帮助您做到这一点。

假设登录页面位于 www.hello.org/login.aspx,它希望您发布登录参数。所以你的代码可能看起来像这样(显然,这是非常简化的):

Imports System.IO
Imports System.Net
Imports System.Web
Dim uri As String = "http://www.hello.org/login.aspx"
Dim request As HttpWebRequest = DirectCast(WebRequest.Create(uri), HttpWebRequest)
request.Timeout = 10000 ' 10 seconds
request.UserAgent = "FlintstoneFetcher/1.0" ' or whatever
request.Accept = "text/*"
request.Headers.Add("Accept-Language", "en")
request.Method = "POST"
Dim data As Byte() = New ASCIIEncoding().GetBytes("txtUsername=fflintstone&txtPassword=ilikerocks")
request.ContentType = "application/x-www-form-urlencoded"
request.ContentLength = data.Length
Dim postStream As Stream = request.GetRequestStream()
postStream.Write(data, 0, data.Length)
postStream.Close()
Dim webResponse As HttpWebResponse
webResponse = DirectCast(request.GetResponse(), HttpWebResponse)
Dim streamReader As StreamReader = New StreamReader(webResponse.GetResponseStream(), Encoding.GetEncoding(1252))
Dim response As String = streamReader.ReadToEnd()
streamReader.Close()
webResponse.Close()

响应字符串现在包含来自远程主机的完整响应文本,并且该主机应该认为您已登录。如果远程主机尝试设置 cookie,您可能需要做一些额外的工作(您需要返回这些 cookie )。或者,如果它希望您在连续页面上通过集成身份验证,则需要将凭据添加到连续请求中,例如:

request.Credentials = New NetworkCredential(theUsername, thePassword)

这应该是足够的信息来破解。我建议您将使用 HTTP 的逻辑模块化为自己的类。我已经实现了一个复杂的解决方案,它登录到某个网站,导航到一个预先确定的页面,解析 html 并在“invox”中查找要下载的每日文件,如果存在则下载它。我将其设置为每天早上运行的批处理过程,从而节省了必须手动执行此操作的人。希望我的经验能给你带来帮助!

于 2013-07-10T02:59:22.817 回答