1

Пытаюсь распарсить сайт через AngleSharp.

Для этого написал метод:

void  TravelHtml(IHtmlElement element)
{
    if (element.Children.Length!=0)
    {
        foreach (var child in element.Children)
        {
            TravelHtml((IHtmlElement)child);
            if (child.LocalName == "img")
            {
                richTextBox2.AppendText(child.Attributes["src"].Value + "\n");
                continue;
            }
            richTextBox2.AppendText(child.TextContent + "\n");
        }
    }
}

Которому на вход подаю Body.

Проблема в том, что если один тег внутри другого тега, то получаю задвоенные значения.

Например, внутри <p> тега находится текст в теге <b> .

Сейчас получается, что я получаю текст с тега выше, а потом когда спускаюсь в child, то опять же получаю этот текст. Мне нужно получать текст с самого низкого уровня.

Подскажите, что я делаю не так? Или может быть мне какие-то теги игнорировать в обходе?

Так же можете предложить альтернативную библиотеку.

UPD:

На вход подаю вот это:

Version:0.9
StartHTML:0000000233
EndHTML:0000001392
StartFragment:0000000269
EndFragment:0000001356
SourceURL:http://www.opengost.ru/1016-gost-19325-73-peredachi-zubchatye-konicheskie.-terminy-opredeleniya-i-oboznacheniya.html
<html>
<body>
<!--StartFragment--><p style="color: rgb(14, 14, 14); font-family: Arial, sans-serif; font-size: 14px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(227, 227, 227);">Стандартизованные термины набраны полужирным шрифтом, их краткие формы - светлым, недопустимые термины - курсивом.</p><p align="center" style="color: rgb(14, 14, 14); font-family: Arial, sans-serif; font-size: 14px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(227, 227, 227);"><b>1. ТЕРМИНЫ, ОПРЕДЕЛЕНИЯ И ОБОЗНАЧЕНИЯ</b></p><!--EndFragment-->
</body>

И в итоге получаю вот это:

Version:0.9 StartHTML:0000000233 EndHTML:0000001392 StartFragment:0000000269 EndFragment:0000001356 SourceURL:http://www.opengost.ru/1016-gost-19325-73-peredachi-zubchatye-konicheskie.-terminy-opredeleniya-i-oboznacheniya.html

Стандартизованные термины набраны полужирным шрифтом, их краткие формы - светлым, недопустимые термины - курсивом.1. ТЕРМИНЫ, ОПРЕДЕЛЕНИЯ И ОБОЗНАЧЕНИЯ

Стандартизованные термины набраны полужирным шрифтом, их краткие формы - светлым, недопустимые термины - курсивом. 1. ТЕРМИНЫ, ОПРЕДЕЛЕНИЯ И ОБОЗНАЧЕНИЯ 1. ТЕРМИНЫ, ОПРЕДЕЛЕНИЯ И ОБОЗНАЧЕНИЯ

Т.е дубли из-за того, что один тэг вложен в другой тег, а Text() примененный к вышестоящему элементу извлекает текст и с ниже стоящих=> при рекурсивном обходе у меня дублируется информация.

iluxa1810
  • 24,899
  • 3
  • 1
    а что именно ты разбираешь и что хочешь получить на выходе? – Grundy Dec 23 '16 at 09:32
  • 2
    приведи небольшой пример Html который ты разбираешь, пример результата, который ты получаешь сейчас, и пример результата который ты хотел бы получать, для этого Html – Grundy Dec 23 '16 at 10:09
  • Ну так а какой должен быть результат? что например выводить если кроме одного тега b Будет еще текст? <p>text <b>b text</b> text1</p> – Grundy Dec 23 '16 at 12:44
  • @Grundy,

    text1 text2 text3

    . Вы наверное это имели ввиду? Тогда text1 text2 text3.
    – iluxa1810 Dec 23 '16 at 12:47
  • а почему text1 text2 text3? а не только text2? а если внутри b Будет еще тег span? – Grundy Dec 23 '16 at 12:48
  • в принципе достаточно пройтись по верхнему уровню элементов, например p и брать сразу их text, без захода внутрь. Либо непонятна логика того, какой из текстов должен выбираться – Grundy Dec 23 '16 at 12:50
  • @Grundy, но тогда я могу упустить текст из ссылки, так как Text не возвращает саму ссылку. Вот ради таких случаев я и рекурсивно и обхожу Body, что бы детально проанализировать. – iluxa1810 Dec 23 '16 at 16:48
  • так надо определиться зачем ты обходишь и что хочешь получить. Иначе, проверка всех возможных нюансов будет слишком трудоемка – Grundy Dec 23 '16 at 16:56
  • @iluxa1810 Ваша задача просто получить чистый текст (без тэгов) всего документа? – Vadim Ovchinnikov Jan 27 '17 at 13:55

3 Answers3

0

Для того, чтобы получить у нужного элемента текст с помощью JavaScript есть свойство innerText. То есть средствами JavaScript можно получать, к примеру, весь текст страницы (без разметки). Для этого достаточно document.documentElement.innerText.

Для того, чтобы загрузить саму страницу и исполнить JavaScript используйте библиотеку CefSharp, код-обёртку для которой я подробно описал в ответе. То есть по сути, написав 2-3 класса, вы можете просто исполнить в консоли тот JavaScript, который вам нужен, затем просто перенести код в программу.

Сам код вызова будет выглядеть так (если нужен текст со всего документа):

var url = "http://www.opengost.ru/1016-gost-19325-73-peredachi-zubchatye-konicheskie.-terminy-opredeleniya-i-oboznacheniya.html";

string text = await wrapper.GetResultAfterPageLoad(url,
    async () => await wrapper.EvaluateJavascript<string>(
    "document.documentElement.innerText"));
  • Эм.. Это вообще к вопросу не относится. – Qwertiy Jan 27 '17 at 05:14
  • @Qwertiy Очень даже относится, так как сказано "Также можете предложить альтернативную библиотеку.". И это способ получить текст всего документа или определённого контейнера. А значение url взято из SourceURL вопроса. – Vadim Ovchinnikov Jan 27 '17 at 05:59
  • Ему вроде не надо выполнять скрипты. 2. innerText (который, к тому же, на js должен быть textContent'ом) даст в точности ту же строку, которая приведена в вопросе как нежелательная. Вывод: ответ не решает проблему, описанную в вопросе.
  • – Qwertiy Jan 27 '17 at 13:02
  • @Qwertiy Нет innerText не вернёт дублирования, вернёт чистый текст. Вы похоже мой код не выполняли и не пробовали даже. А выполнение скрипта через CefSharp тоже является решением данной задачи. – Vadim Ovchinnikov Jan 27 '17 at 13:21
  • Если бы он брал текст html, у него бы тоже проблемы не было, а он рекурсивно обходит все элементы. – Qwertiy Jan 27 '17 at 13:50
  • Насколько я понимаю, его задача получить текст и всё. Для этого и нужно получить innerText нужного элемента. – Vadim Ovchinnikov Jan 27 '17 at 13:54