I am kinda new to c# (spent my time in delphi before) and I am having trouble finding this out:
the Html code of the website is this:
<div class="progress-bar progress-bar-danger" id="counter" style="width: 10.%; overflow: hidden;"></div>
I am trying to figure out sth like this:
var CheckValue = webBrowser1.Document.GetElementById("counter"); if (counter.style.width > 70%) { //code }
So basically what im trying to do is:
I want to check if the width of the progressbar on the website ist filled by more than 70% and if it is it shall execute a code but if it isnt it shall try again after a few seconds.
If you need any more information just tell me!
Thanks
You can use CheckValue.Style, which will return a string containing the style. Then you can use Regex to find what you are looking for.
You want your regex to match the digits between the width: and the .%. You can use this for that:
width: ([0-9]+(\.[0-9]+)?)\.?%
This will match every string starting with width: and ending with % with the possibility of a . before the %, with at least 1 character between 0 and 9.
You can use this code to get this value:
var checkValue = webBrowser1.Document.GetElementById("counter");
Regex regex = new Regex("width: ([0-9]+(\\.[0-9]+)?)\\.?%");
Match match = regex.Match(checkValue.Style);
// Check if match found
if (match.Groups.Count > 1)
{
String s = match.Groups[1].ToString();
int width = (int)Convert.ToDouble(s);
}
Related
<td class="lineitem">964.00 oz</td>
<td class="lineitem" align="right" bgcolor="#141414"><font color="#33ff66">230.00</td>
<td class="lineitem" align="right">$460</td>
<td class="lineitem" align="right">1.00</td>
<td class="lineitem" align="right">$2.00</td>
From this I am trying to get: 964.00 , 230.00 , 460 , 1.00 , 2.00
and save them to string to use later on
Thanks in advance
I have tried :
string bleh = ("http://www.drugrunners.net/quickBuySummary.cfm?");
string[] qual = Regex.Split(bleh, "<td class=");
for (int i = 1; i < qual.Length; i++)
{
switch (i)
{
case 1:
Details[0] = Regex.Split(qual[i], "\">")[0];
button3.Text = Regex.Split(qual[i], "\">")[1]
break;
what you need is a web scraping tool like HtmlAgilityPack
here an example
HtmlDocument doc = new HtmlDocument();
doc.Load("http://yourUrl")
var findclasses = doc.DocumentNode.Descendants("td").Where(d =>
d.Attributes.Contains("class") && d.Attributes["class"].Contains("lineitem")
);
new System.Text.RegularExpressions.Regex("^<td class=\"lineitem\".*>(?<number>.*)</td>$")
Will capture 964.00 oz, 230.00, $460, 1.00 and $2.00 respectively, from the lines you posted.
It does require you to run one row at a time, and you will have to figure out what to do with your units as well.
You need to retrieve the remote webpage and 'scrape' it using a library like html agility pack:
About retrieving it, this SO link is useful:
protected void getHtml(string url){
WebClient client = new WebClient();
string downloadString = client.DownloadString(url);
return downloadString;
}
Then once you create a html document out of the string (not sure about how to do it, but should be a no brainer), you can parse it using html agility pack and XPATH;
Ultimately, I think you can get what you want by following this CodeProject tutorial, and you'd get something like this:
protected void ClickMeButton_Click(object sender, EventArgs e){
var document = getHtml("http://url.to.your/page");
var tdTags = document.DocumentNode.SelectNodes("//td"); //use a xpath expression to select contents
int counter = 1;
if (aTags != null)
{
foreach (var aTag in aTags){
myVarToSave = tdTag.InnerHtml ;
}
}
My question is, does what you're doing (in your example) work? Your string bleh line tells me otherwise. You're obviously working with a page that needs authentication, so you can't simply access the document on HtmlDocument.Load. It will be a little harder than doing any of these answers before you can scrape the page. You will need to figure out:
How to do a proper HttpRequest
How to request with authentication (cookies/postdata, whatever it involves).
How to get the response of the page you want and parse it with HtmlAgilityPack
You can look for each of these points separately on S.O. or elsewhere.
You can also take the other path and download the page manually if it works for you, and then you can do a IO.File method to open the document, which you can feed to HtmlDocument.LoadHtml(), meaning you can skip to number 3.
The regex pattern can be >\$?([\d\.]+).*<
Meaning:
searching something between > and <
\$? is the optional $
() indicate a subpattern to match, returned as $matches[1]
[] indicate the characters to match, the + incidates one or more
\d is a digit
\. is a dot
.* is anything following
In php,
preg_match_all(
'#>\\$*([\\d\\.]+)<#',
'<td class="lineitem">964.00 oz</td>
<td class="lineitem" align="right" bgcolor="#141414"><font color="#33ff66">230.00</td>
<td class="lineitem" align="right">$460</td>
<td class="lineitem" align="right">1.00</td>
<td class="lineitem" align="right">$2.00</td>',
$matches
);
returns
$matches => array (
0 => array (
0 => '>964.00 oz<',
1 => '>230.00<',
2 => '>$460<',
3 => '>1.00<',
4 => '>$2.00<',
),
1 => array (
0 => '964.00',
1 => '230.00',
2 => '460',
3 => '1.00',
4 => '2.00',
),
)
for (int iCount = 0; iCount < oForm.LineItems.Count; iCount++)
{
// cartDetails is a stringbuilder here.
cartDetails.Append(String.Format("{0:0}", oForm.LineItems[iCount].Quantity));
cartDetails.Append(String.Format("{0:0.00}", oForm.LineItems[iCount].Price));
cartDetails.Append(String.Format("{0:0.00}", oForm.LineItems[iCount].ExtendedPrice));
//cartDetails.Append(string.Format("{0,10:#,##0.00}", oForm.LineItems[iCount].Price) + "</TD><TD>");
//cartDetails.Append(string.Format("{0,10:#,##0.00}", oForm.LineItems[iCount].ExtendedPrice) + "</TD><TD>");
//cartDetails.Append(String.Format("{0}", oForm.LineItems[iCount].Quantity).PadLeft(4)+ "</TD><TD>");
//cartDetails.Append(String.Format("{0:0.00}", oForm.LineItems[iCount].Price).PadLeft(8) + "</TD><TD>");
I have pastd the source code I am using. I add qty, price, extendedprice and all are decimal columns. All I am looking to do is to pad left with leading spaces. Decimal rounding to 2 digits seems to be happening.
Those commented lines above are some of the other options I have tried.
Currently if qty has values such as 4 and 40, they don't get aligned when I print them in a table. Same with price.
CAn someone please suggest what am I doing here?
Update1: Tried Lucas suggestion, but it is not working. Here is what I am geting.
cartDetails.Append(String.Format("{0:0,10}", oForm.LineItems[iCount].Quantity));
When I try the above, it shows 10 for every line irrespective of the value in oForm.LineItems[iCount].Quantity.
And if I change
String.Format("{0:0,4}", it shows 04 for all the records
You can use AppendFormat method instead of appending formatted string.
Also correct format will be {index,padding:format}. And consider to use foreach instead of for:
foreach (var lineItem in oForm.LineItems)
{
cartDetails.AppendFormat("{0,4:0}", lineItem.Quantity);
cartDetails.AppendFormat("{0,10:0.00}", lineItem.Price);
// etc
}
Remark: This is for alignemend in caracter based representation such as text files
Have a look at the last section in composite formatting (MSDN).
First format the number as desired and the pad the result
cartDetails.AppendFormat("{0,4}", // padding with spaces
String.Format("{0:0}", oForm.LineItems[iCount].Quantity)); // format number
Addtition: If you want to position your data in a html table you should use css (or inline styles)
<td class="right">This is right aligned</td>
with css
.right { text-align: right; }
or inlined:
<td style="text-align: right">This is right aligned</td>
I am currently trying to extract the ID of a YouTube video from the embed url YouTube supplies.
I am currently using this as an example:
<iframe width="560" height="315" src="http://www.youtube.com/embed/aSVpBqOsC7o" frameborder="0" allowfullscreen></iframe>
So far my code currently looks like this,
else if (TB_VideoLink.Text.Trim().Contains("http://www.youtube.com/embed/"))
{
youtube_url = TB_VideoLink.Text.Trim();
int Count = youtube_url.IndexOf("/embed/", 7);
string cutid = youtube_url.Substring(Count,youtube_url.IndexOf("\" frameborder"));
LB_VideoCodeLink.Text = cutid;
}
I Seem to be getting there, however the code falls over on CutID and I am not sure why???
Cheers
I always find it much easier to use regular expressions for this sort of thing, Substringand IndexOf always seem dated to me, but that's just my personal opinion.
Here is how I would solve this problem.
Regex regexPattern = new Regex(#"src=\""\S+/embed/(?<videoId>\w+)");
Match videoIdMatch = regexPattern.Match(TB_VideoLink.Text);
if (videoIdMatch.Success)
{
LB_VideoCodeLink.Text = videoIdMatch.Groups["videoId"].Value;
}
This will perform a regular expression match, locating src=", ignoring all characters up until /embed/ then extracting all the word characters after it as a named group.
You can then get the value of this named group. The advantage is, this will work even if frameborder does not occur directly after the src.
Hope this is useful,
Luke
The second parameter of the Substring method is length, not second index. Subtract the index of the second test from the first to get the required length.
else if (TB_VideoLink.Text.Trim().Contains("http://www.youtube.com/embed/"))
{
youtube_url = TB_VideoLink.Text.Trim();
// Find the start of the embed code
int Count = youtube_url.IndexOf("/embed/", 7);
// From the start of the embed bit, search for the next "
int endIndex = youtube_url.IndexOf("\"", Count);
// The ID is from the 'Count' variable, for the next (endIndex-Count) characters
string cutid = youtube_url.Substring(Count, endIndex - Count);
LB_VideoCodeLink.Text = cutid;
}
You probably should have some more exception handling for when either of the two test strings do not exist.
Similar to answer above, but was beaten to it.. doh
//Regex with YouTube Url and Group () any Word character a-z0-9 and expect 1 or more characters +
var youTubeIdRegex = new Regex(#"http://www.youtube.com/embed/(?<videoId>\w+)",RegexOptions.IgnoreCase|RegexOptions.Compiled);
var youTubeUrl = TB_VideoLink.Text.Trim();
var match = youTubeIdRegex.Match(youTubeUrl);
var youTubeId = match.Groups["videoId"].Value; //Group[1] is (\w+) -- first group ()
LB_VideoCodeLink.Text = youTubeId;
I'm having a bit of trouble with regex's (C#, ASP.NET), and I'm pretty sure I'm doing something fundamentally wrong. My task is to bind a dynamically created gridview to a datasource, and then iterate through a column in the grid, looking for the string "A&I". An example of what the data in the cell (in template column) looks like is:
Name: John Doe
Phone: 555-123-1234
Email: john.doe#url.com
Dept: DHS-A&I-MRB
Here's the code I'm using to find the string value:
foreach(GridViewRow gvrow in gv.Rows)
{
Match m = Regex.Match(gvrow.Cells[6].Text,"A&I");
if(m.Success)
{
gvrow.ForeColor = System.Drawing.Color.Red;
}
}
I'm not having any luck with any of these variations:
"A&I"
"[A][&][I]"
But when I strictly user "&", the row does turn red. Any suggestions?
Thanks, Dan
The Regex looks fine to me. I suspect the text to perhaps be encoded like:
A&I
on the input.
You could also do gvrow.Cells[6].Text.Contains("A&I") instead of regex. Or gvrow.Cells[6].Text.Contains("A&I") if I'm right with the encoding issue.
string.Contains is also faster than Regex.
You could also HttpUtility.HtmlDecode on the text before checking for the occurance of A&I.
Both of these match successfully:
Match m = Regex.Match("DHS-A&I-MRB", "A&I");
Match m0 = Regex.Match("DHS-A&I-MRB", #"A\&I");
Debug.WriteLine("m.Success = " + m.Success.ToString());
Debug.WriteLine("m0.Success = " + m0.Success.ToString());
Output:
m.Success = True
m0.Success = True
Perhaps the problem is elsewhere (possibly the wrong Cells index)?
I don't know if this is even possible, I have the following regular expression (?<=[\?|\&])(?[^\?=\&#]+)=?(?[^\?=\&#]*)& which splits a URL into key/value pairs. I would like to use this in a replace function to build some markup:
string sTest = "test.aspx?width=100&height=200&";
ltTest.Text = Regex.Replace(sTest, #"(?<=[\?|\&])(?<key>[^\?=\&\#]+)=?(?<value>[^\?=\&\#]*)&",
"< div style='width:$2px; height:$2px; border:solid 1px red;'>asdf</div>");
this is generating:
test.aspx?<div style='width:100px; height:100px; border:solid 1px red;'>asdf</div><div style='width:200px; height:200px; border:solid 1px red;'>asdf</div>
Any ideas?
Thanks in advance!
First, .net has better ways of dealing with your peoblem. Consider HttpUtility.ParseQueryString:
string urlParameters = "width=100&height=200";
NameValueCollection parameters = HttpUtility.ParseQueryString(urlParameters);
s = String.Format("<div style='width:{0}px; height:{1}px;'>asdf</div>",
parameters["width"], parameters["height"]);
That takes care of escaping for you, so it is a better option.
Next, to the question, your code fails because you're using it wrong. you're looking for pairs of key=value, and replacing every pair with <div width={value} height={value}>. So you end up with ad many DIVs as values.
You should make a more surgical match, for example (with some added checks):
string width = Regex.Match(s, #"width=(\d+)").Groups[1].Value;
string height = Regex.Match(s, #"height=(\d+)").Groups[1].Value;
s = String.Format("<div style='width:{0}px; height:{1}px;'>asdf</div>",
width, height);
Is there a reason why you would want to use a regular expression to handle this instead of a Request.QueryString function to grab the data and put this into the string instead?
Right now you would have to make a much more specific Regular Expression to get the value of each key/value pairs and put them into the replace.