Results 1 to 12 of 12

Thread: C# - WebBrowser manipulation, setting/getting attributes, clicking elements, etc...

Threaded View

  1. #1

    Thread Starter
    Hyperactive Member
    Join Date
    Nov 2008
    Location
    PA
    Posts
    365

    C# - WebBrowser manipulation, setting/getting attributes, clicking elements, etc...

    I've been doing a lot of application development with WebBrowsers lately. I also notice the occasional thread that pops up asking how to do stuff regarding the 'net (login to a site, click something on a site, etc).

    First thing is first, let's create a WebBrowser and navigate it to here:
    Code:
    //new WebBrowser, or add the control to a form instead
    System.Windows.Forms.WebBrowser wb = new System.Windows.Forms.WebBrowser;
    //Hook the document completed event so we know when a page is completely loaded up
    wb.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(wb_DocumentCompleted);
    //Navigate to google
    wb.Navigate("http://www.vbforums.com");
    
    private void wb_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
    {
    
    }
    Now, let's see how to work with the document of the webpage in order to fill in the correct values for logging in.

    There are a couple of ways to do this. First off, if the element has an "id=***", we know that the same id can not exist anywhere else on the same page. So:
    Code:
    //inside of the document completed event
    //here's the html for the username: <input type="text" class="textbox default-value" name="vb_login_username" id="navbar_username" size="10" accesskey="u" tabindex="101" value="User Name" />
    //here's the html for the password: <input type="password" class="textbox" tabindex="102" name="vb_login_password" id="navbar_password" size="10" />
    //here's the html for the button to click: <input type="submit" class="loginbutton" tabindex="104" value="Log in" title="Enter your username and password in the boxes provided to login, or click the 'register' button to create a profile for yourself." accesskey="s" />
    
    //fill in the value for the username element
    ((WebBrowser)sender).Document.GetElementById("navbar_username").SetAttribute("value", "username");
    //fill in the value for the password element
    ((WebBrowser)sender).Document.GetElementById("navbar_password").SetAttribute("value", "password");
    //click the login element
    HtmlElementCollection htmlcol = ((WebBrowser)sender).Document.GetElementsByTagName("input");
    for (int i = 0; i < htmlcol.Count; i++)
                {
                    if (htmlcol[i].GetAttribute("value") == "Log in")
                    {
                        htmlcol[i].InvokeMember("click");
                    }
                }
    Of course, if an element doesn't have an "id=***", we can still get to the element. We just need to figure out what property/attribute we can use to identify them apart.
    Code:
    //inside of the document completed event
    //here's the html for the text to fill in to search for (without id): <input type="text" class="textbox default-value" name="vb_login_username" size="10" accesskey="u" tabindex="101" value="User Name" />
    //here's the html for the password (without id: <input type="password" class="textbox" tabindex="102" name="vb_login_password" size="10" />
    //here's the html for the button to click (without id): <input type="submit" class="loginbutton" tabindex="104" value="Log in" title="Enter your username and password in the boxes provided to login, or click the 'register' button to create a profile for yourself." accesskey="s" />
    
    //get a collection of the input elements on the page
    HtmlElementCollection htmlcol = ((WebBrowser)sender).Document.GetElementsByTagName("input");
    //loop the input elements
    for(int i=0; i<htmlcol.Count; i++)
    {
    	if (htmlcol[i].Name == "vb_login_username") //this is the only element with a name of "vb_login_username"
    	{
    		htmlcol[i].SetAttribute("value", "username");
    	}
            else if (htmlcol[i].Name == "vb_login_;password") //this is the only element with a name of "vb_login_username"
    	{
    		htmlcol[i].SetAttribute("value", "password");
    	}
    }
    
    //click the login element
    
    for (int i = 0; i < htmlcol.Count; i++)
                {
                    if (htmlcol[i].GetAttribute("value") == "Log in")
                    {
                        htmlcol[i].InvokeMember("click");
                    }
                }
    You can use the above and modify it to any ID, or any element you can identify. This is how you can login to websites and the such.

    *Remember, pretty much any element can accept clicks. If the element you need to click is an <img *** *** *** > element, just loop the "img" tag collections instead of "input" or "button" and call the same .InvokeMember("click");

    ------

    There a lot of other elements we can manipulate as well. Radio buttons, checkboxes, and dropdown lists I have manipulated in my applications before. It's the same concept in general.

    Dropdown lists:
    //this is the dropdown list for the "Show threads from the ..." at the bottom of the codebank sub forum I'm currently looking at

    Code:
    //inside a document completed event
    //get a collection of the parent "select" elements first
    HtmlElementCollection htmlcol = ((WebBrowser)sender).Document.GetElementsByTagName("select");
    for(int i=0; i<htmlcol.Count; i++)
    {
    	if(htmlcol[i].Name = "daysprune") //if the select element is the dropdown we need to select something for
    	{
    		//create another element collection for the child elements of the "select" element
    		HtmlElementCollection htmlcolchild = htmlcol[i].Children;
    		for(int j=0; j<htmlcolchild.Count; j++)
    		{
    			//<option value="1" >Last Day</option>
    				//...
    			//<option value="-1" selected="selected">Beginning</option>
    
    			//*** Notice the selected="selected" part
    
    			//if we want to select the "Last Day" instead
    			if(htmlcolchild[j].InnerText == "Last day") //inner text gets the text between the beginning/end of the element without the attributes
    			{
    				htmlcolchild[j].SetAttribute("selected", "selected") //set the selected attribute for the last day, instead of the "beginning"
    				break;
    			}
    		}
    	}
    }
    
    //to make the changes go through, we need to click the "show threads" element
    //<input type="submit" class="button" value="Show Threads" />
    htmlcol = ((WebBrowser)sender).Document.GetElementsByTagName("input");
    for(int i=0; i<htmlcol.Count; i++)
    {
    	if(htmlcol[i].GetAttribute("value") == "Show Threads")
    	{
    		htmlcol[i].InvokeMember("click");
    		break;
    	}
    }

    I hope this helps people out! Some of it caused me great fustration when I learned it.
    Last edited by detlion1643; May 20th, 2013 at 12:54 PM. Reason: changed to vbforums example instead of google, fixed typos

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width