#c# #html #linq #html-agility-pack
#c# #HTML #linq #html-agility-pack
Вопрос:
Я хочу получить A href этого элемента в span class=»floatClear», рейтинг которого минимален в
span class=»star-img stars_4″
Как я могу использовать HtmlAgilityPack для достижения такого поведения, я указал html-источник моего файла
<div class="businessresult"> //will repeat
<div class="rightcol">
<div class="rating">
<span class="star-img stars_4">
<img height="325" width="84" src="http://media1.px" alt="4.0 star rating" **title**="4.0 star rating">
</span>
</div>
</div>
<span class="floatClear">
<a class="ybtn btn-y-s" href="/writeareview/biz/KaBw8UEm8u6war_loc%NY">
</span>
</div>
Запрос, который я написал
var lowestreview =
from main in htmlDoc.DocumentNode.SelectNodes("//div[@class='rightcol']")
from rating in htmlDoc.DocumentNode.SelectNodes("//div[@class='rating']")
from ratingspan in htmlDoc.DocumentNode.SelectNodes("//span[@class='star-img stars_4']")
from floatClear in htmlDoc.DocumentNode.SelectNodes("//span[@class='floatClear']")
select new { Rate = ratingspan.InnerText, AHref = floatClear.InnerHtml };
Но я не знаю, как применить условие здесь, в последней строке запроса LINQ!
Комментарии:
1. Вы уверены, что это правильный запрос? Вы выбираете кучу независимых узлов: вы получаете все «рейтинговые» подразделения, независимо от того, находятся они в пределах div «rightcol» или нет (и так далее).
2. Я не уверен в этом, вот почему я спрашиваю!
3. Обязательно ли это должно быть в одном запросе?
4. в этом нет необходимости, мне просто нужно проанализировать html и получить URL-адрес самого низкого просмотренного продукта.
Ответ №1:
Не выбирайте «рейтинг» из всего htmlDoc, выберите его из ранее найденного «main».
Я думаю, вам нужно что-то вроде:
var lowestreview =
from main in htmlDoc.DocumentNode.SelectNodes("//div[@class='rightcol']")
from rating in main.SelectNodes("//div[@class='rating']")
from ratingspan in rating.SelectNodes("//span[@class='star-img stars_4']")
from floatClear in ratingspan.SelectNodes("//span[@class='floatClear']")
select new { Rate = ratingspan.InnerText, AHref = floatClear.InnerHtml };
Я надеюсь, что это не приведет к сбою, если некоторые из этих разделов и диапазонов отсутствуют: предыдущая версия HtmlAgilityPack возвращала null вместо пустого списка, когда SelectNodes
ничего не было найдено.
РЕДАКТИРОВАТЬ
Вероятно, вам также необходимо изменить «запрос xpath» для внутренних выборок: измените «//» на «.//» (дополнительно. в начале), чтобы сигнализировать, что вам действительно нужен подузел. Если AgilityPack работает так же, как обычный XML-XPath (я не уверен на 100%), то «//» в начале будет выполняться поиск из корня документа, даже если вы укажете его из подузла. A «.//» всегда будет выполнять поиск с узла, с которого вы выполняете поиск.
A main.SelectNodes("//div[@class='rating']")
(вероятно) также найдет <div class="rating">
s за пределами <div class="rightcol">
того, что вы нашли в предыдущей строке. main.SelectNodes(".//div[@class='rating']")
Это должно быть исправлено.
Комментарии:
1. Я думаю, что 2-я последняя строка должна быть из floatClear в htmlDoc. DocumentNode. SelectNodes(«//span[@class=’floatClear’]») // поскольку floatclear не является вспомогательным узлом rightcol div. Также в EDIT вы упоминаете о замене // на what is it (.//)