deanlee17
asked on
wpf htmldocument question
Hi guys,
Im trying to automatically log the user into this website, which I have in a WPF project in a browser window:
http://www.brokerforum.com/
I have the following code so far to populate the username and password
I now need to call the click button to login. The code (I believe) is...
However the click button has no id. So how do I call this?
The html / css behind the button is:
Thanks,
Dean
Im trying to automatically log the user into this website, which I have in a WPF project in a browser window:
http://www.brokerforum.com/
I have the following code so far to populate the username and password
HtmlDocument doc = (HtmlDocument)Enquiry_Sourcing_Netcomponents.Document;
doc.GetElementById("Session_Username").SetAttribute("value", "USERNAME");
doc.GetElementById("Session_Password").SetAttribute("value", "PASSWORD");
I now need to call the click button to login. The code (I believe) is...
doc.GetElementById("").InvokeMember("click");
However the click button has no id. So how do I call this?
The html / css behind the button is:
<div class="formActions">
<input src="/tbf/img/login-button-small-en.png" type="image" />
</div>
Thanks,
Dean
You might be able to get a reference to the <input> element by using the HtmlDocument.GetElementsBy TagName method, and checking the "src" attribute for the desired image name.
That's not a button, though--it's an image. You might need to invoke some Javascript on that one.
ASKER
TheLearnedOne: Any idea how to code this?
ASKER
HtmlDocument doc = (HtmlDocument)Enquiry_Sourcing_Netcomponents.Document;
doc.GetElementById("Session_Username").SetAttribute("value", "XXXXX");
doc.GetElementById("Session_Password").SetAttribute("value", "XXXXX");
doc.GetElementById("").InvokeMember("click");
HtmlElementCollection theElementCollection = doc.GetElementsByTagName("input");
HtmlElementCollection elems = doc.GetElementsByTagName("input");
foreach (HtmlElement elem in theElementCollection)
{
String nameStr = elem.GetAttribute("name");
if (nameStr != null && nameStr.Length != 0)
{
String contentStr = elem.GetAttribute("content");
System.Windows.MessageBox.Show("Document: " + Enquiry_Sourcing_Netcomponents.ToString() + "\nDescription: " + contentStr);
}
}
Throwing error on first line:
System.InvalidCastExceptio
HResult=-2147467262
Message=Unable to cast COM object of type 'mshtml.HTMLDocumentClass'
Aah, yes, the ambiguous nature of HtmlDocument. If that reference is an HTMLDocument, then you need to change some things around, and use different methods, which gets trickier, and a lot heavier.
Word of warning: "If you are going to add a reference to mshtml, don't use a using mshtml; statement at the top of the module, since it will slow Intellisense to a crawl"
Word of warning: "If you are going to add a reference to mshtml, don't use a using mshtml; statement at the top of the module, since it will slow Intellisense to a crawl"
ASKER
Ah ok, all ive added is 'using System.Windows.Forms;'
Now... Im stuck lol
Now... Im stuck lol
Microsoft mshtml is COM library that is part of the .NET framework, but there is a managed wrapper available as a reference.
Example using mshtml:
Example using mshtml:
var htmlDoc = (HTMLDocument)webBrowser1.Document;
//find the search text box..
var searchTextBox = (HTMLInputElement)htmlDoc.all.item("p", 0);
searchTextBox.value = "Search text goes here";
//find the button
var searchButton = (HTMLInputElement)htmlDoc.all.item("searchsubmit", 0);
searchButton.click();
ASKER
Ok that makes sense. So do I add a reference to 'mshtml.HTMLDocumentClass' in the right hand window but then don't include a 'using' statement at the top?
In your example, is 'searchsubmit' the actual id as the button I need to hit doesn't have the id. Im assuming we could do that search on the input source (button image)?
In your example, is 'searchsubmit' the actual id as the button I need to hit doesn't have the id. Im assuming we could do that search on the input source (button image)?
ASKER
Ok cool, and im doing ok with the below code, it populates the input boxes, now I just need to find a way to click a button without an id or class attached...
Thanks,
Dean
var htmlDoc = (HTMLDocument)LoginWebpage.Document;
//find the search text box..
var UsernameTextBox = (mshtml.HTMLInputElement)htmlDoc.all.item("Session_Username", 0);
UsernameTextBox.value = "XXXXX";
var PasswordTextBox = (mshtml.HTMLInputElement)htmlDoc.all.item("Session_Password", 0);
PasswordTextBox.value = "XXXXX";
Thanks,
Dean
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Where did HtmlHelper come from?
I get 'The name 'HtmlHelper' does not exist in the current context'
Does this require another include?
I get 'The name 'HtmlHelper' does not exist in the current context'
Does this require another include?
HtmlHelper is the class that I created and posted, starting with this line:
internal static class HtmlHelper
internal static class HtmlHelper
ASKER
d'oh, I missed that.
Ok so implemented it and its throwing an error on
'var htmlDocument = (mshtml.HTMLDocument)docum ent.DomDoc ument;'
saying....Object reference not set to an instance of an object?
Thanks,
Dean
Ok so implemented it and its throwing an error on
'var htmlDocument = (mshtml.HTMLDocument)docum
saying....Object reference not set to an instance of an object?
Thanks,
Dean
ASKER
Code so far:
internal static class HtmlHelper
{
public static object GetElementByTagNameWithAttribute(
mshtml.HTMLDocument document, string tagName, string attributeName, string attributeValue)
{
var elementList = document.getElementsByTagName(tagName);
foreach (dynamic element in elementList)
{
var attributeList = (mshtml.IHTMLAttributeCollection)element.attributes;
foreach (var attribute in attributeList)
{
var htmlAttribute = (mshtml.IHTMLDOMAttribute)attribute;
if (htmlAttribute.nodeName == attributeName && htmlAttribute.nodeValue == attributeValue)
return element;
}
}
return null;
}
}
private void btnCreateQuote_Click(object sender, RoutedEventArgs e)
{
var htmlDoc = (HTMLDocument)LoginWebpage.Document;
var UsernameTextBox = (mshtml.HTMLInputElement)htmlDoc.all.item("Session_Username", 0);
UsernameTextBox.value = "XXX";
var PasswordTextBox = (mshtml.HTMLInputElement)htmlDoc.all.item("Session_Password", 0);
PasswordTextBox.value = "XXX";
var browser = new System.Windows.Forms.WebBrowser();
var document = browser.Document;
var htmlDocument = (mshtml.HTMLDocument)document.DomDocument;
var buttonElement = (mshtml.HTMLInputElement)HtmlHelper.GetElementByTagNameWithAttribute(htmlDocument,
"input", "src", "/tbf/img/login-button-small-en.png");
buttonElement.click();
}
Is that code working?
ASKER
'var htmlDocument = (mshtml.HTMLDocument)docum ent.DomDoc ument;'
saying....Object reference not set to an instance of an object?
saying....Object reference not set to an instance of an object?
If you got that code from me, that was meant to show you an example, using the WebBrowser control.
I thought this is your HTMLDocument reference:
var htmlDoc = (HTMLDocument)LoginWebpage .Document;
I thought this is your HTMLDocument reference:
var htmlDoc = (HTMLDocument)LoginWebpage
ASKER
Hmmm this is still erroring. Will provide furthur info shortly..
ASKER
Hi The LearnedOne,
Sorry for the delay, I have been away from work for a while.
As per your code and comments above, for the line below:
var htmlDocument = (mshtml.HTMLDocument)WebBr owser_Sour cing_Broke rForum_Enq uiry.DomDo cument;
I get the error:
'System.Windows.Controls.W ebBrowser' does not contain a definition for 'DomDocument' and no extension method 'DomDocument'
Complete code as it stands....
Sorry for the delay, I have been away from work for a while.
As per your code and comments above, for the line below:
var htmlDocument = (mshtml.HTMLDocument)WebBr
I get the error:
'System.Windows.Controls.W
Complete code as it stands....
internal static class HtmlHelper
{
public static object GetElementByTagNameWithAttribute(
mshtml.HTMLDocument document, string tagName, string attributeName, string attributeValue)
{
var elementList = document.getElementsByTagName(tagName);
foreach (dynamic element in elementList)
{
var attributeList = (mshtml.IHTMLAttributeCollection)element.attributes;
foreach (var attribute in attributeList)
{
var htmlAttribute = (mshtml.IHTMLDOMAttribute)attribute;
if (htmlAttribute.nodeName == attributeName && htmlAttribute.nodeValue == attributeValue)
return element;
}
}
return null;
}
}
private void EnquirySave_Click(object sender, RoutedEventArgs e)
{
//ascentEntities.SaveChanges();
var htmlDoc = (HTMLDocument)WebBrowser_Sourcing_BrokerForum_Enquiry.Document;
var UsernameTextBox = (mshtml.HTMLInputElement)htmlDoc.all.item("Session_Username", 0);
UsernameTextBox.value = "XXX";
var PasswordTextBox = (mshtml.HTMLInputElement)htmlDoc.all.item("Session_Password", 0);
PasswordTextBox.value = "XXX";
var browser = new System.Windows.Forms.WebBrowser();
var document = browser.Document;
var htmlDocument = (mshtml.HTMLDocument)WebBrowser_Sourcing_BrokerForum_Enquiry.DomDocument;
var buttonElement = (mshtml.HTMLInputElement)HtmlHelper.GetElementByTagNameWithAttribute(htmlDocument,
"input", "src", "/tbf/img/login-button-small-en.png");
buttonElement.click();
}
Thanks
This line should be changed:
var htmlDocument = (mshtml.HTMLDocument)WebBr owser_Sour cing_Broke rForum_Enq uiry.DomDo cument;
to
var htmlDocument = (mshtml.HTMLDocument)WebBr owser_Sour cing_Broke rForum_Enq uiry.Document.DomDocument;
var htmlDocument = (mshtml.HTMLDocument)WebBr
to
var htmlDocument = (mshtml.HTMLDocument)WebBr
ASKER
Attached
error.png
error.png
What is the type for "WebBrowser_Sourcing_Broke rForum_Enq uiry"?
ASKER
It's WebBrowser
Can you show me the declaration, and tell me what version of the .NET IDE that you are using?
ASKER
.net 4.5
using System;
using System.Collections.Generic ;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imagi ng;
using System.Windows.Shapes;
using DevExpress.Xpf.Core;
using DevExpress.Xpf.Ribbon;
using DevExpress.Xpf.Bars;
using DevExpress.Xpf.Layout.Core ;
using DevExpress.Xpf.Docking;
using System.Data.OleDb;
using System.Data;
using DevExpress.Xpf.Grid;
using System.Data.SqlClient;
using System.IO;
using System.Globalization;
using DevExpress.XtraPrinting;
using DevExpress.XtraGrid.Views. Base;
using DevExpress.Data.Filtering;
using System.Collections;
using DevExpress.XtraGrid.Views. Grid;
using DevExpress.Xpf.Map;
using System.Windows.Forms;
using DevExpress.Xpf.Editors;
using System;
using System.Collections.Generic
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imagi
using System.Windows.Shapes;
using DevExpress.Xpf.Core;
using DevExpress.Xpf.Ribbon;
using DevExpress.Xpf.Bars;
using DevExpress.Xpf.Layout.Core
using DevExpress.Xpf.Docking;
using System.Data.OleDb;
using System.Data;
using DevExpress.Xpf.Grid;
using System.Data.SqlClient;
using System.IO;
using System.Globalization;
using DevExpress.XtraPrinting;
using DevExpress.XtraGrid.Views.
using DevExpress.Data.Filtering;
using System.Collections;
using DevExpress.XtraGrid.Views.
using DevExpress.Xpf.Map;
using System.Windows.Forms;
using DevExpress.Xpf.Editors;
Not the using statements, the declaration in the .Designer.cs file.
ASKER
In model1.designed.cs?
I don't know what you want from in there.
I don't know what you want from in there.
ASKER
It's a WPF application, would that make a difference?
That is what I was trying to get straight. So, you are using the System.Windows.Controls.We bBrowser, and not the System.Windows.Forms.WebBr owser.
Try this instead:
Try this instead:
var htmlDocument = (mshtml.HTMLDocument)WebBrowser_Sourcing_BrokerForum_Enquiry.Document;
ASKER
Got there in the end:
try
{
var htmlDoc1 = (HTMLDocument)WebBrowser_Sourcing_BrokerForum_Enquiry.Document;
var UsernameTextBox = (mshtml.HTMLInputElement)htmlDoc1.all.item("Session_Username", 0);
UsernameTextBox.value = "XXXXX";
var PasswordTextBox = (mshtml.HTMLInputElement)htmlDoc1.all.item("Session_Password", 0);
PasswordTextBox.value = "XXXXX";
foreach (mshtml.HTMLInputElement HTMLI in ((mshtml.HTMLDocument)WebBrowser_Sourcing_BrokerForum_Enquiry.Document).getElementsByTagName("input"))
{
if (HTMLI.getAttribute("type").Equals("image"))
{
if (HTMLI.src == "http://www.brokerforum.com/tbf/img/login-button-en.png")
{
HTMLI.click();
return;
}
}
}
}
catch (Exception) { }