Как получить текст с атрибута "a" , сравнивая тем что находится внутри "strong" при парсинге c помощью htmlagilitypack

Прошу прощения за заголовок, не знал как написать. Есть div блок который содержит в себе несколько li. В каждом li написан год книги, автор, правообладатель и т.д.. Я хотел получить только правообладателя. Я думал чтобы это сделать мне нужно найти где написано <strong> Правообладатель:</strong> который находится в li и достать текст с a (Азбука-Аттикус). Я перепробовал много разных способов и ни один не сработал.

<div class="blocks">
<li>...</li>
<li>...</li>
<li>
<strong>Правообладатель:</strong>
<a href="/azbuka-attikus/">Азбука-Аттикус</a>
</li>
<li>...</li>
</div>

Пытался я вот так:

HtmlNode pravo = document.DocumentNode.SelectSingleNode("//li/strong[@text='Правообладатель:']/a");

Я знаю что таким образом я ни как не смогу достать текст из a, но у меня уже не осталось ни каких идей, как можно это сделать.


Ответы (1 шт):

Автор решения: aepot

Хорошая шпаргалка - Xpath cheatsheet

Ошибка пропала, но он берет не с того места и пишет "Икабог Дж. К. Роулинг Оглавление", а должно быть "Икабог Дж. К. Роулинг Азбука-Аттикус". Он берет данные вот оттсюда https://litres.ru/dzhoan-ketlin-rouling/ikabog

Ваша проблема в том, что вы взяли код из инспектора, то есть уже обработанный яваскриптом, встроенным в страницу, а надо брать именно исходный код страницы (правый клик по странице - Исходный код), нужная часть которого выглядит вот так:

<li><strong>Правообладатель:</strong> <span data-link="/azbuka-attikus/" class="biblio_info_detailed__link biblio_book_link_js">Азбука-Аттикус</span></li>

Следовательно полный код получения нужной ссылки будет выглядеть вот так.

private static readonly HttpClient client = new HttpClient();

static async Task Main(string[] args)
{
    string html = await client.GetStringAsync("https://www.litres.ru/dzhoan-ketlin-rouling/ikabog/");
    HtmlDocument doc = new HtmlDocument();
    doc.LoadHtml(html);
    HtmlNode pravo = doc.DocumentNode.SelectSingleNode("//strong[contains(text(),'Правообладатель')]/following::span");
    Console.WriteLine(pravo.InnerText);
    Console.WriteLine(pravo.Attributes["data-link"].Value);
}

Вывод в консоль

Азбука-Аттикус
/azbuka-attikus/

Или даже можно проще запрос сделать

HtmlNode pravo = doc.DocumentNode.SelectSingleNode("//span[contains(@class,'biblio_book_link_js')]");

А еще можно использовать не XPath, а CSS селектор, для этого нужно дополнительно установить NuGet пакет Fizzler.Systems.HtmlAgilityPack, и можно будет сделать то же самое вот так:

HtmlNode pravo = doc.DocumentNode.QuerySelector(".biblio_book_link_js");
→ Ссылка