Как разобрать текст из анонимного блока в AngleSharp?

Я анализирую содержимое сайта с помощью AngleSharp, и у меня возникла проблема с анонимным блоком.

См. пример кода:

var parser = new HtmlParser();
var document = parser.Parse(@"<body>
<div class='product'>
    <a href='#'><img src='img1.jpg' alt=''></a>
    Hello, world
    <div class='comments-likes'>1</div>
</div>
<div class='product'>
    <a href='#'><img src='img2.jpg' alt=''></a>
    Yet another helloworld
    <div class='comments-likes'>25</div>
</div>
<body>");

var products = document.QuerySelectorAll("div.product");
foreach (var product in products)
{
    var productTitle = product.Text();
    productTitle.Dump();
}

Итак, productTitle содержит числа из div.comments-likes, вывод:

Привет, мир 1

Еще один привет мир 25

Я пробовал что-то вроде product.FirstElementChild.NextElementSibling.Text();, но следующим родственным элементом для элемента ссылки является div.comments-likes, а не анонимный блок. Это показывает:

1

25

Таким образом, анонимные блоки пропускаются. :(

Лучший обходной путь, который я нашел, - это удаление всех блокирующих блоков, например:

product.QuerySelector(".comments-likes").Remove();
var productTitle = product.Text().Trim();

Лучший способ для анализа текста из анонимного блока?


person A K    schedule 11.03.2017    source источник


Ответы (1)


Текст моделируется как TextNode, это тип узла рядом с элементом, узлом комментария, инструкцией по обработке и т. д. Вот почему NextElementSibling, который вы пробовали, не включал текст в результат, поскольку он предназначался для возврата только элементы, как следует из названия.

Вы можете получить текстовые узлы, расположенные непосредственно в продукте div, пройдя через div ChildNodes, а затем отфильтровав NodeType, например:

var products = document.QuerySelectorAll("div.product");
foreach (var product in products)
{
    var productTitle = product.ChildNodes
                              .First(o => o.NodeType == AngleSharp.Dom.NodeType.Text 
                                            && o.TextContent.Trim() != "");
    Console.WriteLine(productTitle.TextContent.Trim());
}

dotnetfiddle demo

Обратите внимание, что новые строки между элементами также являются текстовыми узлами, поэтому нам нужно отфильтровать их в демонстрации выше.

person har07    schedule 12.03.2017
comment
Спасибо за пояснения! - person A K; 12.03.2017
comment
@ har07 har07 Не могли бы вы увидеть этот вопрос, пожалуйста, удалить все строки из таблицы HTML? - person Learner; 17.01.2020
comment
Можете ли вы сделать демонстрацию dotnetfiddle, которая воспроизводит проблему? Мой простой тест работает: dotnetfiddle.net/AAk1W5 - person har07; 17.01.2020