-->

c# webbrowser control does not navigate to another

2020-07-13 12:01发布

问题:

I have a console application and i've defined a webbrowser inside it. Firstly, i navigate to a page and fill a login form and invoke the submit button to login.

After that, i want to go to another page in the same site using the same webbrowser but it does not navigate to that page. instead, it navigates to the page that it's redirected after login.

Here is my code for clarification; this code gives me the source code of www.websiteiwanttogo.com/default.aspx instead of product.aspx what is wrong here?

static WebBrowser wb = new WebBrowser();

    [STAThread]
    static void Main(string[] args)
    {
        wb.AllowNavigation = true;
        wb.Navigate("https://www.thewebsiteiwanttogo.com/login.aspx");
        wb.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(wb_DocumentCompleted);
        Application.Run();


    }

    static void wb_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
    {
        if (wb.Url.ToString().IndexOf("login.aspx") > -1)
        {
            wb.Document.GetElementById("txtnumber").SetAttribute("value", "000001");
            wb.Document.GetElementById("txtUserName").SetAttribute("value", "myusername");
            wb.Document.GetElementById("txtPassword").SetAttribute("value", "mypassword");
            wb.Document.GetElementById("btnLogin").InvokeMember("click");


        }
        else
        {
            //wb.Document.Body  you are logged in do whatever you want here.
            wb.Navigate("https://www.thewebsiteiwanttogo.com/product.aspx");

            Console.WriteLine(wb.DocumentText);
            Console.ReadLine();
            Application.Exit();

        }
    }

回答1:

There are a lot of different ways to accomplish this functionality. However, my guess is that:

  1. Either the call to navigate to the next page is happening too quickly, or
  2. The Document.Completed event is not firing properly after logging in (this is common especially if the destination document contains dynamic scripts)

I've done a lot of web page automating (navigating from link to link, then performing some actions, then navigating to another link, etc.), and you should consider using async processes. In principle, it is probably always best when dealing with the webBrowser object to use async processes, simply because there are many instances where you need one process to run while you perform other functions.

Without going into too much detail, look at the answer to this question and study the code: Flow of WebBrowser Navigate and InvokeScript

Before trying that implementation, however, you could simply try adding an async await before trying to navigate to the page. (async await is similar to a Thread.Sleep(), but doesn't actually stop the loading of the page, i.e. the "thread").

(Never heard of asynchronous processes before? Check out this tutorial on MSDN).

Try this first:

static void wb_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
    if (wb.Url.ToString().IndexOf("login.aspx") > -1)
    {
        wb.Document.GetElementById("txtnumber").SetAttribute("value", "000001");
        wb.Document.GetElementById("txtUserName").SetAttribute("value", "myusername");
        wb.Document.GetElementById("txtPassword").SetAttribute("value", "mypassword");
        wb.Document.GetElementById("btnLogin").InvokeMember("click");


    }
    else
    {
        //wb.Document.Body  you are logged in do whatever you want here.
        await Task.Delay(1000); //wait for 1 second just to let the WB catch up
        wb.Navigate("https://www.thewebsiteiwanttogo.com/product.aspx");

        Console.WriteLine(wb.DocumentText);
        Console.ReadLine();
        Application.Exit();

    }
}

If this doesn't help, consider the link above and try implementing a more robust navigating sequence with async processes.

If that doesn't work, and you'd like some help navigating through or waiting for dynamic pages to load, try this post: how to dynamically generate HTML code using .NET's WebBrowser or mshtml.HTMLDocument? I've used this code theology many times, and it works great.

Hope one of these methods helps! Let me know, and I can help you generate some more specific code snippets.

EDIT:

At second glance, I'm going to guess that the Console.ReadLine() is going to freeze up the navigating of wb.Navigate("https://www.thewebsiteiwanttogo.com/product.aspx");, since it won't happen instantaneously. You'll probably want to add another if statement in the Document.Completed handler to allow wb.Navigate("https://www.thewebsiteiwanttogo.com/product.aspx"); to finish navigating before trying to grab the wb.DocumentText. For example:

static void wb_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
    if (wb.Url.ToString().IndexOf("login.aspx") > -1)
    {
        wb.Document.GetElementById("txtnumber").SetAttribute("value", "000001");
        wb.Document.GetElementById("txtUserName").SetAttribute("value", "myusername");
        wb.Document.GetElementById("txtPassword").SetAttribute("value", "mypassword");
        wb.Document.GetElementById("btnLogin").InvokeMember("click");
    }
    else if(wb.Url.ToString().IndexOf("product.aspx") > -1)
    {
        Console.WriteLine(wb.DocumentText);
        Console.ReadLine();
        Application.Exit();
    }
    else
    {
        //wb.Document.Body  you are logged in do whatever you want here.
        await Task.Delay(1000); //wait for 1 second just to let the WB catch up
        wb.Navigate("https://www.thewebsiteiwanttogo.com/product.aspx");
    }
}