There is a Page, I want to get it's body for reading input areas, and changing their values by GetAttribute and SetAttribute in C#. This is no problem to do it but,
There is nothing returns (I mean empty string), when I call the body via:
webBrowser1.Document.Body.InnerText
or,
webBrowser1.Document.Body.InnerHtml
That's why I can't acces any input field.
I see The Web Page in webbrowser component, But Neither InnerText nor InnerHtml return. It's a saved Bank weppage running on local.
So How can I read body, for running SetAttribute or GetAttribute or InvokeMember something else?
You need to get the input element then to get or set the text :
HtmlElementCollection elements = currentBrowser.Document.GetElementsByTagName("INPUT");
foreach (HtmlElement element in elements)
{
//to get the text use : string value = element.GetAttribute("value");
//to set the text use : elemet.InnerText = "something";
}
but don't forget that by the code above you get all the input elements , to search for a specific element you can check its id or name as in the webpage : for example :
if (element.Name.ToLower().Contains("email"))
//do work
Related
I have piece of code as below
<div class="span6" style="text-align:right;">
<span class="muted" style="padding-left:20px;">Member ID: </span>MKL123451KKM
<span class="muted" style="padding-left:20px;">Service Date: </span>05/08/2018
</div>
in above code i want to get the value "MKL123451KKM", this value is going to change often.
i have tried with below xpaths which was giving error.
XPATH :
/html/body/div/span[1][contains(text(),'Member ID:')]/../text()
/html/body/div/span[1][contains(.,'Member ID:')]/../text()
ERROR :
The result of the xpath expression :
/html/body/div/span[1][contains(text(),'Member ID:')]/../text() is: [object Text]. It should be an element.
NOTE:
i am using selenium driver for IE and c# with VS 2015 IDE
Can anybody throw light on this?
You were fairly close. It's generally not a good practice to create a locator that starts at the HTML tag or has too many levels because it's more brittle (more likely to break when the page changes). Ideally you would find the label element by text label, e.g. "Member ID", and then locate the following text node. The big benefit of this method is that it's tied to the "Member ID" label. Some of the other answers are hard-coded to a specific text node which may be good now but if the data changes, it may return the wrong value.
You can wrap this all in a function where you pass in the label and it returns the value.
public string GetValue(string labelName)
{
IWebElement e = Driver.FindElement(By.XPath($"//span[contains(.,'{labelName}')]"));
string s = (string)((IJavaScriptExecutor)Driver).ExecuteScript("return arguments[0].nextSibling.textContent;", e);
return s.Trim();
}
and you would call it like
GetValue("Member ID")
As per the HTML you have shared the text MKL123451KKM is not within any child <span> node but within the parent <div> node. To extract the text e.g. MKL123451KKM you can use the following code block :
IWebElement elem = driver.FindElement(By.XPath("//div[#class='span6']"));
string text = (string)((IJavaScriptExecutor)driver).ExecuteScript("return arguments[0].childNodes[2].textContent;", elem);
That's because the text is within the div. You will need to get text from xpath:
//div[#class='span6']
Even though this xpath isn't very change-proof, it should work if you get text from it. The text though will be MKL123451KKM and 05/08/2018
Try this XPath
//div[#class='span6']/span/following-sibling::text()[1]
I'm using the Html Agility Pack for this task, basically I've got a URL, and my program should read through the content of the html page on it, and if it finds a line of text (ie: "John had three apples"), it should change a label's text to "Found it".
I tried to do it with contains, but I guess it only checks for one word.
var nodeBFT = doc.DocumentNode.SelectNodes("//*[contains(text(), 'John had three apples')]");
if (nodeBFT != null && nodeBFT.Count != 0)
myLabel.Text = "Found it";
EDIT: Rest of my code, now with ako's attempt:
if (CheckIfValidUrl(v)) // foreach var v in a list..., checks if the URL works
{
HtmlWeb hw = new HtmlWeb();
HtmlDocument doc = hw.Load(v);
try
{
if (doc.DocumentNode.InnerHtml.ToString().Contains("string of words"))
{
mylabel.Text = v;
}
...
One possible option is using . instead of text(). Passing text() to contains() function the way you did will, as you suspected, effective only when the searched text is the first direct child of the current element :
doc.DocumentNode.SelectNodes("//*[contains(., 'John had three apples')]");
In the other side, contains(., '...') evaluates the entire text content of current element, concatenated. So, just a heads up, the above XPath will also consider the following element for example, as a match :
<span>John had <br/>three <strong>apples</strong></span>
If you need the XPath to only consider cases when the entire keyword contained in a single text node, and therefore considers the above case as a no-match, you can try this way :
doc.DocumentNode.SelectNodes("//*[text()[contains(., 'John had three apples')]]");
If none of the above works for you, please post minimal HTML snippet that contains the keyword but returned no match, so we can examine further what possibly causes that behavior and how to fix it.
use this:
if (doc.DocumentNode.InnerHtml.ToString().Contains("John had three apples"))
myLabel.Text="Found it";
C# Selenium Webdriver
So i need to ensure that none of my pages (around 200 pages) contain a particular known string. Is there any way that i can scan a page for the existence of this string and if it does then return both the ElementID of that element and the entire string?
For example my source is like:
<a id="cancel_order_lnkCancel">Cancel Order</a>
I want to search for the word 'Cancel' on the whole page (<div id="sitewrapper">) and return both
cancel_order_lnkCancel;Cancel Order
Thanks
You can use XPath to find by text. e.g.:
var element = driver.FindElement(By.XPath(string.Format("//*[contains(text(), '{0}')]", value)));
value being the string you are searching for.
Then to get the element's markup and content:
var html = element.GetAttribute("outerHTML");
var text = element.Text;
or
var text = element.GetAttribute("innerHTML");
I haven't worked in C# binding but you can use FindElements to get a list of all elements containing the text. You can by no doubt use #Jarga's xpath. The good thing with FIndElements will be that it won't throw you an exception (atleast this is what happens in java) though you have to use try catch to handle getAttribute if you get null for value of id. And if you iterate over the list you can fetch all texts using getText method.
I would like a to find a way to store the text from within a read only element.
IWebElement LName = Driver.Instance.FindElement(By.XPath(".//*[#id='inputGrid']/div[1]/div[1]/div/div[1]/table/tbody/tr[1]/td[4]"));
string LNValue = LName.GetAttribute("value");
The result of this code is that LNValue is empty.
However, LName is a cell that contains this text: "********"
If I inspect the element, I can see this:
<td class="htDimmed fill">********</td>
<td class="htDimmed">*********</td>
Since code is being written in C#, you can use built in "Text" property to fetch the innerHTML of that element and it should work in all browsers.
String LNValue= LName.Text;
Moreover make sure that XPath is correctly reaching the element as well..I hope this helps
You can use the textContent attribute to get the text. AFAIK, the td element doesnot have a value attribute.
string LNValue = LName.GetAttribute("textContent");
You could also use the innerText attribute, but that is not supported across all browsers.
I have a source code on a webpage that I wish to extract (I've narrowed it down to exactly what is relevant here:
<div class="sideInfoPlayer">
<a class="signLink" href="spieler.php?uid=12345" title="Profile">
<span class="wrap">Wagamama</span>
</a>
Now the trick here is that I want to get the word Wagamama into a message box but that word changes on every page of that site so I need to get that element but there is no ID on this page. Therefore I was thinking of doing a search for the class named "sideInfoPlayer" first and then find the "wrap" class within the previous class block.
I have written the below to get the first one but do not know how to tackle the second one and then get the desired value.
HtmlElementCollection col = webBrowser1.Document.GetElementsByTagName("div");
foreach (HtmlElement element in col)
{
string cls = element.GetAttribute("className");
if (String.IsNullOrEmpty(cls) || !cls.Equals("sideInfoPlayer"))
continue;
}
I hope you can help unstuck me on this one.
You have better options. Look at http://htmlagilitypack.codeplex.com/
And here: How can i parse html string
First you'll need to add reference to HtmlAgilityPack library by downloading it manually or with NuGet package manager.
// loading html into HtmlDocument
var doc = new HtmlWeb().Load("http://website.com/mypage");
// walking through all nodes of interest
foreach (var node in doc.DocumentNode.SelectNodes("//div[#class='sideInfoPlayer']/span[#class='wrap']"))
{
// here is your text: node.InnerText
}
//div[#class='sideInfoPlayer']/span[#class='wrap'] is called Xpath Expression and this one literally means "get me all span elements with class=wrap that are children of div element with class=sideInfoPlayer.
I didn't test it, but it should work.