Extracting the nth list item using HtmlAgilityPack - c#

I am working on a web scraper project using HmlAgilityPack and C#. Please have look at the HTML code section which I am having trouble with. Since all the <li> items in the <ul> have the same class names for <div> and , how can I extract the full location (Town, City) i.e value of second <span> in the second <li> item?
<ul class="Menu">
<li>
<div class="item">
<span class="name">Name:</span>
<span class="value">....</span>
</div>
</li>
<li>
<div class="item">
<span class="name">Location:</span>
<span class="value">
<div class="location">
Town
","
City
</div>
</span>
</div>
</li>
<li>
<div class="item">
<span class="name">Phone:</span>
<span class="value">....</span>
</div>
</li>
</ul>
This is what I have tried and failed:
var location = adHtml.DocumentNode.SelectNodes(
#"//ul[#class='Menu']
/div[#class='location']
/a").Select(a => a.InnerText);
Writing location to the console gives me a Null Exception.

Related

HtmlNode Get inner text from nested span

I am trying to get information from a html segment, it is all going well however I am struggling to return the value of the Trade in value. Below is a copy of the code I have tried so far.
htmlNode.Descendants("li").Where(x => x.HasClass("trade-in-price")).Select(x => x.Descendants("span").Where(z => z.HasClass("value")).Last().InnerText);
which returns the following:
"£36.00"
Now, I don't really want to substring this value to get the cost as I don't think it is the best way to do this however I have tried every other way and i can't seem to return 'just the cost' value.
Here is a copy of the html I am trying to navigate to get the desired value
<section
class="product-item"
itemscope="itemscope">
<div>
<div class="group">
<div>
<div class="product-image"><a
href="/trade-in-sell/call-of-duty-modern-warfare-ps4"
itemprop="url"
><span><img
width="160"
height="200"
alt="Call Of Duty: Modern Warfare"
title="Show more information on Call Of Duty: Modern Warfare"
itemprop="image"
/></span></a></div>
<div class="product-categories gray">
<ul>
<li>PlayStation</li>
</ul>
</div>
<div class="product-label top-seller"><strong>modernwarfare</strong></div>
<h2 class="product-title" itemprop="name">Call Of Duty: Modern Warfare</h2>
</div>
</div>
<div class="group">
<div>
<div class="product-price">
<ul>
<li class="buy-new-price">
<Buy new</span> <span class="value"><span class="symbol l">£</span>49.99</span>
</li>
<li class="trade-in-price">
<a href="/trade-in-sell/call-of-duty-modern-warfare-ps4">
<span class="label">Trade in</span>
<span class="value">
<span class="symbol l">
£
</span>
36.00 // I want this value here
</span>
</a>
</li>
<li class="sell-price">
<a href="/trade-in-sell/call-of-duty-modern-warfare-ps4">
<span class="label">Get cash</span>
<span class="value">
<span class="symbol l">
£
</span>
32.00
</span>
</a>
</li>
</ul>
</div>
</div>
</div>
</div>
</section>
Does anyone know where abouts I am going wrong in my LINQ query?
I think you can use the method GetDirectInnerText() instead of property InnerText. For me it returns only text of node itself without childs.
htmlNode.Descendants("li").Where(x => x.HasClass("trade-in-price")).Select(x => x.Descendants("span").Where(z => z.HasClass("value")).Last().GetDirectInnerText());

Count some nodes by Selenium, using xpath. C#

class Program
{
static void Main(string[] args)
{
var driver = new ChromeDriver();
driver.Navigate().GoToUrl("https://www.favorit.com.ua/uk/live/");
string numberOfGame = driver.FindElement(By.XPath("//*[#id='livediv']/div/div[2]/ul/li[1]/ul/li[1]/ul/li/div/div/div[1]/div[2]/div[1]/span")).Text;
string Command1_Goals = driver.FindElement(By.XPath("//*[#id='livediv']/div/div[2]/ul/li[1]/ul/li[1]/ul/li/div/div/div[2]/div/div/div/div[1]/div[1]")).GetAttribute("innerHTML");
string Command2_Goals = driver.FindElement(By.XPath("//*[#id='livediv']/div/div[2]/ul/li[1]/ul/li[1]/ul/li/div/div/div[2]/div/div/div/div[1]/div[2]")).GetAttribute("innerHTML");
string Command1 = driver.FindElement(By.XPath("//*[#id='livediv']/div/div[2]/ul/li[1]/ul/li[1]/ul/li/div/div/div[1]/div[1]/span[1]")).GetAttribute("innerHTML");
string Command2 = driver.FindElement(By.XPath("//*[#id='livediv']/div/div[2]/ul/li[1]/ul/li[1]/ul/li/div/div/div[1]/div[1]/span[2]")).GetAttribute("innerHTML");
string TimeOfGame = driver.FindElement(By.XPath("//*[#id='livediv']/div/div[2]/ul/li[1]/ul/li[1]/ul/li/div/div/div[1]/div[2]/div[2]/div")).GetAttribute("innerHTML");
Console.OutputEncoding = Encoding.UTF8;
Console.WriteLine("Game: " + numberOfGame + " Team 1: " + Command1 + " Goals: " + Command1_Goals + " | Team 2: " + Command2 + " Goals: " + Command2_Goals);
Console.ReadLine();
}
}
Hey, guys! I am now creating the online statistic of games. I know that there is a statistic at website, but I want to get my personal one.
How can I count 'li' blocks which are here: //*[#id='livediv']/div/div[2]/ul/li[1]/ul/li[1]
I am going to count them and then use each number as ID to get numbers of games. Is it right way? Because there are many 'li' blocks and I want to get values in each of them. Check screenshot:
Each category--block sp_1 contains few 'li'. And I want to get game's values for each 'li';
Look at this
I have to get access into each category--block sp_1 and into each 'li' there.
<ul class="events--list">
<li>
<div class="event--head-block">
<u></u>
<div class="event--head">
<div class="event--name--info">
<div class="event--name two--name">
<span>Славен Белупо</span>
<span>Істра 1961</span>
</div>
<div class="event--short--info">
<div class="event--line--position">
<span>9953</span>
<b>1491</b>
</div>
<div class="time--block">
<div class="event--timer">9:31</div>
</div>
<div class="event--result--type--name">П1</div>
</div>
<div class="stat--button">
<a href="https://stats.betradar.com/s4/?clientid=65&language=ru&matchid=11953108" title="Перегляд статистики"
target="_blank">
<i class="fav-icon"></i>
</a>
</div>
<div class="video--button">
<span class="video-block" title="Для перегляду відео трансляції необхідний баланс на обраному гаманці в еквіваленті понад 400 грн., або зробіть ставку в еквіваленті мінімум 40 грн.">
<i class="fav-icon"></i>
</span>
</div>
<!-- react-empty: 1620 -->
</div>
<div class="result--block result-count-1 sp_1">
<div class="result--content">
<div class="result--absolute">
<div class="result--block--entire">
<!-- react-empty: 1625 -->
<div class="result--item result--item--ft">
<div class="result--score">0</div>
<div class="result--score">0</div>
</div>
<div class="result--item result--item--cur">
<div class="result--score">0</div>
<div class="result--score">0</div>
</div>
</div>
</div>
</div>
</div>
<div class="fav--button">
<button class="" title="Додати до обраних/Прибрати з обраних">
<i class="fav-icon"></i>
</button>
</div>
<ul class="outcome_list outcome-count-3 count-0">
<li>
<label class="outcome--empty">
<button></button>
</label>
</li>
<li>
<label class="outcome--empty">
<button></button>
</label>
</li>
<li>
<label class="outcome--empty">
<button></button>
</label>
</li>
</ul>
<ul class="outcome_list outcome-count-3 count-1">
<li class="outcome">
<label class="">
<u title="Славен Белупо (+0.5)">1 (+0.5)</u>
<span title="Славен Белупо (+0.5)">Славен Белупо (+0.5)</span>
<button>1.10</button>
</label>
</li>
<li class="param">
<span>+0.5</span>
</li>
<li class="outcome">
<label class="">
<u title="Істра 1961 (-0.5)">2 (-0.5)</u>
<span title="Істра 1961 (-0.5)">Істра 1961 (-0.5)</span>
<button>5.75</button>
</label>
</li>
</ul>
<ul class="outcome_list outcome-count-3 count-2 has-param">
<li>
<label class="outcome--empty">
<button></button>
</label>
</li>
<li>
<label class="outcome--empty">
<button></button>
</label>
</li>
<li>
<label class="outcome--empty">
<button></button>
</label>
</li>
</ul>
<div class="event--more">
<button>+0</button>
</div>
</div>
</div>
</li>
</ul>
</li>
<li class="category--block sp_1">
<div class="caterory--head">
<div class="outcomes--name">
<div class="category--name">
<span>Йорданія | Дивізіон 1</span>
</div>
<ul class="count--label count-0 outcome-count-3">
<li title="1">1</li>
<li title="X">X</li>
<li title="2">2</li>
</ul>
<ul class="count--label count-1 outcome-count-3 has-param">
<li title="1">1</li>
<li>Фора</li>
<li title="2">2</li>
</ul>
<ul class="count--label count-2 outcome-count-3 has-param">
<li title="Б">Б</li>
<li>Тотал</li>
<li title="М">М</li>
</ul>
<div class="close--category"></div>
</div>
</div>
<ul class="events--list">
<li>
<div class="event--head-block">
<u></u>
<div class="event--head">
<div class="event--name--info">
<div class="event--name two--name">
<span>Етхад Аль-Рамта</span>
<span>Шабаб Аль Хусейн</span>
</div>
<div class="event--short--info">
<div class="event--line--position">
<span>4672</span>
<b>1491</b>
</div>
<div class="time--block">
<div class="event--timer">41:14</div>
</div>
<div class="event--result--type--name">П1</div>
</div>
<div class="stat--button">
<i class="fav-icon"></i>
</div>
<div class="video--button">
<span class="video-block" title="Для перегляду відео трансляції необхідний баланс на обраному гаманці в еквіваленті понад 400 грн., або зробіть ставку в еквіваленті мінімум 40 грн.">
<i class="fav-icon"></i>
</span>
</div>
<!-- react-empty: 720 -->
</div>
<div class="result--block result-count-1 sp_1">
<div class="result--content">
<div class="result--absolute">
<div class="result--block--entire">
<!-- react-empty: 725 -->
<div class="result--item result--item--ft">
<div class="result--score">0</div>
<div class="result--score">0</div>
</div>
<div class="result--item result--item--cur">
<div class="result--score">0</div>
<div class="result--score">0</div>
</div>
</div>
</div>
</div>
</div>
<div class="fav--button">
<button class="" title="Додати до обраних/Прибрати з обраних">
<i class="fav-icon"></i>
</button>
</div>
<ul class="outcome_list outcome-count-3 count-0">
<li class="outcome">
<label class="">
<u title="Етхад Аль-Рамта">1</u>
<span title="Етхад Аль-Рамта">Етхад Аль-Рамта</span>
<button>2.55</button>
</label>
</li>
<li class="outcome">
<label class="">
<u title="Нічия">X</u>
<span title="Нічия">Нічия</span>
<button>2.30</button>
</label>
</li>
<li class="outcome">
<label class="">
<u title="Шабаб Аль Хусейн">2</u>
<span title="Шабаб Аль Хусейн">Шабаб Аль Хусейн</span>
<button>3.70</button>
</label>
</li>
</ul>
<ul class="outcome_list outcome-count-3 count-1">
<li class="outcome">
<label class="">
<u title="Етхад Аль-Рамта (0.0)">1 (0.0)</u>
<span title="Етхад Аль-Рамта (0.0)">Етхад Аль-Рамта (0.0)</span>
<button>1.55</button>
</label>
</li>
<li class="param">
<span>0.0</span>
</li>
<li class="outcome">
<label class="">
<u title="Шабаб Аль Хусейн (0.0)">2 (0.0)</u>
<span title="Шабаб Аль Хусейн (0.0)">Шабаб Аль Хусейн (0.0)</span>
<button>2.20</button>
</label>
</li>
</ul>
<ul class="outcome_list outcome-count-3 count-2">
<li class="outcome">
<label class="">
<u title="Більше (1.5)">Б (1.5)</u>
<span title="Більше (1.5)">Більше (1.5)</span>
<button>2.40</button>
</label>
</li>
<li class="param">
<span>1.5</span>
</li>
<li class="outcome">
<label class="">
<u title="Менше (1.5)">М (1.5)</u>
<span title="Менше (1.5)">Менше (1.5)</span>
<button>1.47</button>
</label>
</li>
</ul>
<div class="event--more">
<button>+20</button>
</div>
</div>
</div>
</li>
<li>
<div class="event--head-block">
<u></u>
<div class="event--head">
<div class="event--name--info">
<div class="event--name two--name">
<span>Аль Джаліл</span>
<span>Аль-Тора</span>
</div>
<div class="event--short--info">
<div class="event--line--position">
<span>4521</span>
<b>1491</b>
</div>
<div class="time--block">
<div class="event--timer">37:43</div>
</div>
<div class="event--result--type--name">П1</div>
</div>
First : how can I count 'li' blocks ?
Answer : use driver.FindElements(By.XPath("//*[#id='livediv']/div/div[2]/ul/li[1]/ul/li"))
This will return a list of WebElement (In your case all will be li elements)
then you can use something like list.size(); to count number of li blocks.
last one: What is the best way to keep turning on ?
You should initialize your browser instance only once. and rotate the reference of driver object anywhere you want, may be you would like to use constructor in few cases.

ASP.NET MVC / Bootstrap - Display Selected Item from List w/ navigation controls

I have a partial view that I am returning to my home view. I want to be able to pass in a string array of values and then pass back the view. The view will allow for the list to be navigated through and control various things on the page. I need both previous and next buttons to traverse through the list.
Before I post my attempts, here is a picture of what I want. I am showing this first because I am all but certain my attempts is not the way to go and am 100% open to any solution that gets this done.
I've attempted to do this by with a carousel with little luck. One, i cant even get it to work correctly. Two, I cant get the appearance I want (see image above)
#model List<string>
<div class="well">
<div class="carousel slide" id="av-agmt-car" data-interval="false">
<div class="carousel-inner">
#foreach (var item in Model)
{
string c = "";
var i = 0;
if (i == 0)
{
c = "item active";
}
else
{
c = "item";
}
<div class=#c>#item</div>
i++;
}
</div>
<a class="left carousel-control" href="#av-agmt-car" data-slide="prev">
<span class="glyphicon glyphicon-chevron-left"></span>
<span class="sr-only">Previous</span>
</a>
<a class="right carousel-control" href="#av-agmt-car" data-slide="next">
<span class="glyphicon glyphicon-chevron-right"></span>
<span class="sr-only">Next</span>
</a>
</div>
</div>
Another thought would be to use pagination and some fancy javascript. I havent put the JS together but think i could manage it. I struggle with the css of this one to look appropriate.
#model List
<nav class="av-no-marg">
<ul class="pagination">
<li class="col-md-4">
<div>
<a class="left carousel-control" href="#" data-slide="prev">
<span class="glyphicon glyphicon-chevron-left"></span>
</a>
</div>
</li>
<li class="col-md-4">
<div>
TEST
</div>
</li>
<li class="col-md-4">
<div>
<a class="right carousel-control" href="#" data-slide="next">
<span class="glyphicon glyphicon-chevron-right"></span>
</a>
</div>
</li>
</ul>
</nav>
I would change your #foreach loop to a for loop. If you declaring i inside a foreach loop, it'll stay at 0, unless you declare outside of the foreach loop. The below is untested code.
#for (var i = 0; i < Model.length; i++)
{
string c = "item";
string item = Model.AtElement(i);
if(i == 0)
{
c = "item active";
}
<text><div class=#c>#item</text>
}

How to get the 3rd div value with the same class name in C#?

How to get 3rd div in this code snippet using C#?
For example I'd like to get the text in the 3rd div with a class name of gwt-Label WBCI. I'm having issues on getting the right values and at the same time figuring out on what codes do i need to get it
What my code now is something like this but I'm getting the wrong value
browser.Div(Find.ByClass("gwt-Label WBCI")).OuterText.ToString();
<ul class="WCVH WKVH" role="list">
<li class="WIUH" role="listitem">
<div class="WKUH">
<label id="labeledImage.POSTED_DATE--uid6-formLabel" data-automation-id="formLabel"></label>
</div>
<div class="WMUH">
<div class="WDBN WMP WDCN" data-automation-id="responsiveMonikerInput" id="labeledImage.POSTED_DATE--uid6">
<div class="WIBN">
<ul tabindex="-2" class="WCHJ WHBN" role="list" data-automation-id="selectedItemList">
<li class="WGHJ" role="presentation">
<div class="WOGJ WFHJ" tabindex="-2" id="b7e15031a749444a855366b1f1a87a46" data-automation-id="menuItem" aria-label="Posted Today, press delete to clear value." role="listitem" aria-posinset="1" aria-setsize="1">
<div class="WPGJ">
<div class="WACI">
<ul class="WCBI WIBI" role="presentation">
<li class="WPBI"><img class="gwt-Image WHWI WFPJ WKQJ" src="https://vps-wd5.myworkdaycdn.com/assets/ui-html/update/WorkdayApp/8CB9E57BEDDE62E4F67DEB6E19F5308C.cache.png" draggable="false" data-automation-id="POSTED_DATE_charm" alt="" aria-label=""
aria-labelledby="promptOption"></li>
</ul>
<div class="gwt-Label WBCI" data-automation-id="promptOption" id="promptOption" title="Posted Today" aria-label="Posted Today" data-automation-label="Posted Today" aria-labelledby="labeledImage.POSTED_DATE--uid6-formLabel">Posted Today</div>
<ul class="WCBI"></ul>
</div>
</div>
</div>
</li>
</ul>
</div>
</div>
</div>
</li>
<li class="WIUH" role="listitem">
<div class="WKUH">
<label id="labeledImage.JOB_TYPE--uid7-formLabel" data-automation-id="formLabel"></label>
</div>
<div class="WMUH">
<div class="WDBN WMP WDCN" data-automation-id="responsiveMonikerInput" id="labeledImage.JOB_TYPE--uid7">
<div class="WIBN">
<ul tabindex="-2" class="WCHJ WHBN" role="list" data-automation-id="selectedItemList">
<li class="WGHJ" role="presentation">
<div class="WOGJ WFHJ" tabindex="-2" id="5c6eda594d0d46609fa4c8e2ff13e731" data-automation-id="menuItem" aria-label="Full time, press delete to clear value." role="listitem" aria-posinset="1" aria-setsize="1">
<div class="WPGJ">
<div class="WACI">
<ul class="WCBI WIBI" role="presentation">
<li class="WPBI"><img class="gwt-Image WHWI WFPJ WCQJ" src="https://vps-wd5.myworkdaycdn.com/assets/ui-html/update/WorkdayApp/8CB9E57BEDDE62E4F67DEB6E19F5308C.cache.png" draggable="false" data-automation-id="JOB_TYPE_charm" alt="" aria-label="" aria-labelledby="promptOption"></li>
</ul>
<div class="gwt-Label WBCI" data-automation-id="promptOption" id="promptOption" title="Full time" aria-label="Full time" data-automation-label="Full time" aria-labelledby="labeledImage.JOB_TYPE--uid7-formLabel">Full time</div>
<ul class="WCBI"></ul>
</div>
</div>
</div>
</li>
</ul>
</div>
</div>
</div>
</li>
<li class="WIUH" role="listitem">
<div class="WKUH">
<label id="labeledImage.JOB_REQ--uid8-formLabel" data-automation-id="formLabel"></label>
</div>
<div class="WMUH">
<div class="WDBN WMP WDCN" data-automation-id="responsiveMonikerInput" id="labeledImage.JOB_REQ--uid8">
<div class="WIBN">
<ul tabindex="-2" class="WCHJ WHBN" role="list" data-automation-id="selectedItemList">
<li class="WGHJ" role="presentation">
<div class="WOGJ WFHJ" tabindex="-2" id="cc054d6cca664a3282855669711520d5" data-automation-id="menuItem" aria-label="T_R_1616417, press delete to clear value." role="listitem" aria-posinset="1" aria-setsize="1">
<div class="WPGJ">
<div class="WACI">
<ul class="WCBI WIBI" role="presentation">
<li class="WPBI"><img class="gwt-Image WHWI WFPJ WBQJ" src="https://vps-wd5.myworkdaycdn.com/assets/ui-html/update/WorkdayApp/8CB9E57BEDDE62E4F67DEB6E19F5308C.cache.png" draggable="false" data-automation-id="JOB_REQ_charm" alt="" aria-label="" aria-labelledby="promptOption"></li>
</ul>
<div class="gwt-Label WBCI" data-automation-id="promptOption" id="promptOption" title="T_R_1616417" aria-label="T_R_1616417" data-automation-label="T_R_1616417" aria-labelledby="labeledImage.JOB_REQ--uid8-formLabel">T_R_1616417</div>
<ul class="WCBI"></ul>
</div>
</div>
</div>
</li>
</ul>
</div>
</div>
</div>
</li>
</ul>

Show bootstrap panel in a row inside foreach loop

Here is my code, what should I do to show 3 panels in a row. Is there any way to do this?
Its showing in the same row but the next panel starts slightly below the previous one I'll be really thankful to you for your help
#foreach (DEProperty.Web.Models.PlotsViewModelSearchResult c in Model)
{
<div class="col-md-4">
<div class="panel panel-info">
<div class="panel-heading text-center">
<h4>#c.PhaseText, #c.SectorText-#c.PlotAddress</h4>
</div>
<div class="panel-body text-center">
<p class="lead">
<img src="~/images/plot...image.jpg" />
</p>
</div>
<ul class="list-group list-group-flush text-center">
<li class="list-group-item" style="border:none">
#c.AreaText
</li>
<li class="list-group-item" style="border:none">
Facing Park
</li>
<li class="list-group-item text-center" style="border:none">
Near Mosque
</li>
<li class="list-group-item" style="border:none">
Near Commercial
</li>
<li class="list-group-item" style="border:none">
Corner
</li>
</ul>
<div class="panel-footer">
<a class="btn btn-lg btn-block btn-info">Detail View</a>
</div>
</div>
</div>
Just Add <div class="row"> like this:
<div class="row">
#foreach (DEProperty.Web.Models.PlotsViewModelSearchResult c in Model)
{
....
}
</div>

Categories

Resources