Парсинг сайтов в .NET

647
24 декабря 2016, 14:46

Пытаюсь распарсить сайт через 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() примененный к вышестоящему элементу извлекает текст и с ниже стоящих=> при рекурсивном обходе у меня дублируется информация.

Answer 1

Для того, чтобы получить у нужного элемента текст с помощью 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"));
READ ALSO
Google Drive REST API Сервисный аккаунт

Google Drive REST API Сервисный аккаунт

Помогите разобраться

457
Как программно выключить компьютер?

Как программно выключить компьютер?

Как программно выключить компьютер?

340
Вывод данных из двух таблиц в один gridview yii2

Вывод данных из двух таблиц в один gridview yii2

Есть две таблицы без ключейДля каждой создал модель(Order и Manager)

1236
htaccess убрать слово из url

htaccess убрать слово из url

Есть сайт на php, проблема в том что он зашифрован, и хотелось бы убрать из ссылок слово - search, можно ли это сделать как то с помощью htaccess, и чтобы...

376