Парсинг innertext

Zoron

Client
Регистрация
24.09.2014
Сообщения
145
Благодарностей
39
Баллы
28
Всех приветствую. Есть задача спарсить все innertext'a в коде сайта, но без повторений. Пытался делать через htmlagilitypack:

C#:
var html =
        @"<h1>Header</h1>
           <div>Text1
                 <p>Text2</p>
           Text3</div>";

        var htmlDoc = new HtmlDocument();
        htmlDoc.LoadHtml(html);

        var htmlNodes = htmlDoc.DocumentNode.SelectNodes("//*");

        foreach (var node in htmlNodes)
        {
           //вывод
        }
Но получаю след. итог:

C#:
Header

Text1

    Text2

Text3

Text2
Т.е первый div содержит в себе тег <p> и соответственно его innertext.
Кто может подскажет как сделать, чтобы брались только вхождения без повторов. Может можно проверять наличие потомка и углубляться ниже или как-то еще? Буду благодарен за любой совет )
 

SergSh

Client
Регистрация
10.05.2017
Сообщения
541
Благодарностей
395
Баллы
63
Попробуй так. Только внимательно присмотрись к синтаксису x.InnerText я не пробовал
C#:
 var htmlNodes = htmlDoc.DocumentNode.SelectNodes("//*");

 foreach (string text in htmlNodes.Select(x => x.InnerText.Trim().ToLower()).Distinct().Where(x => !string.IsNullOrEmpty(x)))
 {
    project.SendInfoToLog(text);
 }
 
  • Спасибо
Реакции: Zoron и Qeludard

Qeludard

Новичок
Регистрация
26.08.2021
Сообщения
6
Благодарностей
0
Баллы
1
Попробуй так. Только внимательно присмотрись к синтаксису x.InnerText я не пробовал
C#:
 var htmlNodes = htmlDoc.DocumentNode.SelectNodes("//*");

foreach (string text in htmlNodes.Select(x => x.InnerText.Trim().ToLower()).Distinct().Where(x => !string.IsNullOrEmpty(x)))
{
    project.SendInfoToLog(text);
}
Думаю теперь точно заработает.
 

Zoron

Client
Регистрация
24.09.2014
Сообщения
145
Благодарностей
39
Баллы
28
Спасибо за ответ, но решение примерно то же вышло.
Попробуй так. Только внимательно присмотрись к синтаксису x.InnerText я не пробовал
C#:
 var htmlNodes = htmlDoc.DocumentNode.SelectNodes("//*");

foreach (string text in htmlNodes.Select(x => x.InnerText.Trim().ToLower()).Distinct().Where(x => !string.IsNullOrEmpty(x)))
{
    project.SendInfoToLog(text);
}
 

Вложения

Регистрация
05.06.2019
Сообщения
570
Благодарностей
454
Баллы
63
C#:
var html =
        @"<h1>Header</h1>
           <div>Text1
                 <p>Text2</p>
           Text3</div>";

var htmlDoc = new HtmlDocument();
htmlDoc.LoadHtml(html);

var htmlNodes = htmlDoc.DocumentNode.SelectNodes("//*");

var temp = new List<string>();

foreach (string text in htmlNodes.Select(x => Regex.Replace(x.InnerText, @"\s{2,}", " ").Trim()).Where(x => !string.IsNullOrEmpty(x)))
{
    project.SendInfoToLog(text);
    temp.Add(text);
}

var temp2 = new List<string>();

foreach (var t in temp)
{
    temp2.AddRange(t.Split(' '));
}

temp.Clear();
return string.Join(";", temp2.Distinct());
Укороченный вариант

C#:
var html =
        @"<h1>Header</h1>
           <div>Text1
                 <p>Text2</p>
           Text3</div>";

var htmlDoc = new HtmlDocument();
htmlDoc.LoadHtml(html);

var temp = htmlDoc.DocumentNode
                .SelectNodes("//*")
                .Select(x => Regex.Replace(x.InnerText, @"\s{2,}", " ").Trim())
                .Where(x => !string.IsNullOrEmpty(x))
                .AsParallel() //удалить, если важен порядок
                .Select(i => i.Split(' '))
                .SelectMany(i => i)
                .Cast<string>()
                .Distinct();

return string.Join(";", temp);
 
Последнее редактирование:
  • Спасибо
Реакции: SHILY, Zoron и Astraport

Zoron

Client
Регистрация
24.09.2014
Сообщения
145
Благодарностей
39
Баллы
28
C#:
var html =
        @"<h1>Header</h1>
           <div>Text1
                 <p>Text2</p>
           Text3</div>";

var htmlDoc = new HtmlDocument();
htmlDoc.LoadHtml(html);

var htmlNodes = htmlDoc.DocumentNode.SelectNodes("//*");

var temp = new List<string>();

foreach (string text in htmlNodes.Select(x => Regex.Replace(x.InnerText, @"\s{2,}", " ").Trim()).Where(x => !string.IsNullOrEmpty(x)))
{
    project.SendInfoToLog(text);
    temp.Add(text);
}

var temp2 = new List<string>();

foreach (var t in temp)
{
    temp2.AddRange(t.Split(' '));
}

temp.Clear();
return string.Join(";", temp2.Distinct());
Укороченный вариант

C#:
var html =
        @"<h1>Header</h1>
           <div>Text1
                 <p>Text2</p>
           Text3</div>";

var htmlDoc = new HtmlDocument();
htmlDoc.LoadHtml(html);

var temp = htmlDoc.DocumentNode
                .SelectNodes("//*")
                .Select(x => Regex.Replace(x.InnerText, @"\s{2,}", " ").Trim())
                .Where(x => !string.IsNullOrEmpty(x))
                .AsParallel() //удалить, если важен порядок
                .Select(i => i.Split(' '))
                .SelectMany(i => i)
                .Cast<string>()
                .Distinct();

return string.Join(";", temp);
Спасибо за интересное решение, но вот например, этот html текст
C#:
<td align='right' id='webview' style='color: #5e5e5e; font-family: 'Segoe UI', SUWR, Arial, Sans-Serif; font-weight: 400; font-size: 10px; line-height: 12px;'>Having trouble viewing this Text? | <a href='link' target='_blank' style='text-decoration: none; border-bottom: 1px solid #5E5E5E;'><strong style='font-weight: 400; color: #5e5e5e;'>View as web page</strong></a></td>
ваш код видит как:

Having trouble viewing this Text? | View as web page

либо как:

View as web page

Т.е. отдельно кусок текста - Having trouble viewing this Text? |
он не видит, т.к .у него есть дочерние элементы
Мне просто нужно в коде заменить только текста не трогая сам код, а пока не получается..
 
Последнее редактирование:
Регистрация
05.06.2019
Сообщения
570
Благодарностей
454
Баллы
63
1.
Есть задача спарсить все innertext'a в коде сайта, но без повторений.
Т.е первый div содержит в себе тег <p> и соответственно его innertext.
Кто может подскажет как сделать, чтобы брались только вхождения без повторов. Может можно проверять наличие потомка и углубляться ниже или как-то еще?
2.
Мне просто нужно в коде заменить только текста не трогая сам код, а пока не получается..
Совершенно разные задачи, следовательно и решение.
Возможно, если вы более четко сформулируйте задачу и прикрепите живой пример, думаю быстрее получите нужный результат.
 

Zoron

Client
Регистрация
24.09.2014
Сообщения
145
Благодарностей
39
Баллы
28
1.




2.


Совершенно разные задачи, следовательно и решение.
Возможно, если вы более четко сформулируйте задачу и прикрепите живой пример, думаю быстрее получите нужный результат.
Задачи разные, но последовательные, сначала нужно выпарсить все innertext'a, а потом заменить его на мой другой текст, не задев верстку страницы )

Т.е. проще говоря из этого
C#:
var html =
        @"<h1>Header</h1>
           <div>Text1
                 <p>Text2</p>
           Text3</div>";
Получить это:

C#:
var html =
        @"<h1>Mytext1</h1>
           <div>Mytext2
                 <p>Mytext3</p>
           Mytext4</div>";
Естесственно теги. типа br, b, strong, em и т.п. не учитываем, я их предварительно очищаю.
 
Регистрация
05.06.2019
Сообщения
570
Благодарностей
454
Баллы
63
Думаю, что алгоритм следующий:

Разобрать исходный текст страницы в массив, по закрывающим тегам

[0]<h1>Header
[1]<div>text1
[1][0]<p>text2
[1][1][0]text3

Возможно, можно сделать словарь (именованные индексы), чтобы не потерять обозначение маршрута (для конечного сбора структуры), суть, когда полностью разложите таким образом, перебрав его, игнорируя <TAG> (то есть делаете выжимку текста, если надо замену, пожалуйста), далее вам нужно сделать инверсию, собрать его из глубины.
 
  • Спасибо
Реакции: Zoron

Zoron

Client
Регистрация
24.09.2014
Сообщения
145
Благодарностей
39
Баллы
28
Тоже были мысли сделать двойные массивы с обозначение ширины и глубины и разобрать, но реализация конечно будет непростая, думал может попроще решение какое есть )
 

Zoron

Client
Регистрация
24.09.2014
Сообщения
145
Благодарностей
39
Баллы
28
Думаю, что алгоритм следующий:

Разобрать исходный текст страницы в массив, по закрывающим тегам

[0]<h1>Header
[1]<div>text1
[1][0]<p>text2
[1][1][0]text3

Возможно, можно сделать словарь (именованные индексы), чтобы не потерять обозначение маршрута (для конечного сбора структуры), суть, когда полностью разложите таким образом, перебрав его, игнорируя <TAG> (то есть делаете выжимку текста, если надо замену, пожалуйста), далее вам нужно сделать инверсию, собрать его из глубины.
А если не трудно, можешь подсказать как это сделать проще, например, на том же htmlagilitypack?
 

Кто просматривает тему: (Всего: 1, Пользователи: 0, Гости: 1)