Два вопроса по xPath+HtmlAgilityPack

spmwork1

Новичок
Регистрация
09.09.2018
Сообщения
16
Благодарностей
0
Баллы
1
Два вопроса по xPath

В продолжение темы https://zennolab.com/discussion/threads/parsing-soobschenij-s-foruma.52035/#post-388935

Пытаюсь спарсить данные отсюда http://www.stavochka.com/forum/viewtopic.php?f=1&t=1129 в таком формате

имя пользователя;дата сообщения;текст сообщения
Искал информацию по форуме, понял что для парсинга мне нужно использовать xPath+HtmlAgilityPack

Нашел пример на форуме:

https://zennolab.com/discussion/threads/vopros-po-xpath.43645/#post-323326

Подставил свои значения xPath

Код:
//table[@cellspacing='1'] - основной узел

.//b[@class='postauthor'] - автор поста

.//div[@class='postbody'] - сам пост

Общий код выглядит так


Код:
var html = project.Variables["HTML"].Value; // html страница
var doc = new HtmlDocument();
doc.LoadHtml(html); // создали объект HtmlDocument и загрузили в него html страницу
var nodes = doc.DocumentNode.SelectNodes("//table[@cellspacing='1']"); // взяли нужные узлы сразу без рекламы (как писал @Moadip: "Для маньяков xpath")
project.SendInfoToLog("нашли столько узлов:" + nodes.Count.ToString(), true);
var list = new List<string>();
foreach (var node in nodes) // в цикле добавляем в список элемент состоящий из двух строчек
{
    var author = node.SelectSingleNode(".//b[@class='postauthor']").InnerText; // текст заголовка
    var post = node.SelectSingleNode(".//div[@class='postbody']']").InnerText; // текст описания

    list.Add(author + "\r\n" + post); // добавил в список "двойную строчку"

}
var res = string.Join("\r\n", list); // объединил двойный строчки
return res;

Суть проблемы. Я делаю get запрос к сайту, он проходит успешно, а вот с C# кодом возникла проблема.


2.PNG

1.PNG


Выбивает ошибку Выполнение действия CSharp OwnCode Ссылка на объект не указывает на экземпляр объекта.


И второй вопрос, как составить xPath чтобы еще дату сообщения парсило? Проект прикрепил к посту. Спасибо за помощь!
 

Вложения

orka13

Client
Регистрация
07.05.2015
Сообщения
2 167
Благодарностей
2 168
Баллы
113
Было:
C#:
var html = project.Variables["HTML"].Value; // html страница
var doc = new HtmlDocument();
doc.LoadHtml(html); // создали объект HtmlDocument и загрузили в него html страницу
var nodes = doc.DocumentNode.SelectNodes("//table[@cellspacing='1']"); // взяли нужные узлы сразу без рекламы (как писал @Moadip: "Для маньяков xpath")
project.SendInfoToLog("нашли столько узлов:" + nodes.Count.ToString(), true);
var list = new List<string>();
foreach (var node in nodes) // в цикле добавляем в список элемент состоящий из двух строчек
{
    var author = node.SelectSingleNode(".//b[@class='postauthor']").InnerText; // текст заголовка
    var post = node.SelectSingleNode(".//div[@class='postbody']']").InnerText; // текст описания
    list.Add(author + "\r\n" + post); // добавил в список "двойную строчку"
}
var res = string.Join("\r\n", list); // объединил двойный строчки
return res;
Надо:
C#:
var html = project.Variables["HTML"].Value; // html страница
var doc = new HtmlDocument();
doc.LoadHtml(html); // создали объект HtmlDocument и загрузили в него html страницу
var nodes = doc.DocumentNode.SelectNodes(@"//table[@cellspacing='1' and .//b[@class='postauthor'] and .//div[@class='postbody']]"); // взяли нужные узлы сразу без рекламы (как писал @Moadip: "Для маньяков xpath")
project.SendInfoToLog("нашли столько узлов:" + nodes.Count.ToString(), true);
var list = new List<string>();
foreach (var node in nodes) // в цикле добавляем в список элемент состоящий из двух строчек
{
    var author = node.SelectSingleNode(".//b[@class='postauthor']").InnerText; // текст заголовка
    var post = node.SelectSingleNode(".//div[@class='postbody']").InnerText; // текст описания
    list.Add(author + "\r\n" + post); // добавил в список "двойную строчку"
}
var res = string.Join("\r\n", list); // объединил двойный строчки
return res;
Почему не работало:
В "var nodes" код ищет лишние элементы, там захватило блоки без постов. А потом в коде далее вы пытаетесь из этих блоков без проверки есть ли там заголовки постов получить эти заголовки, вот оно и ругается что не с чего брать.
И опечатка в последнем Xpath:
Код:
']']"
 
Последнее редактирование:
  • Спасибо
Реакции: grin-du и spmwork1

grin-du

Client
Регистрация
09.10.2017
Сообщения
96
Благодарностей
46
Баллы
18
Было:
C#:
var html = project.Variables["HTML"].Value; // html страница
var doc = new HtmlDocument();
doc.LoadHtml(html); // создали объект HtmlDocument и загрузили в него html страницу
var nodes = doc.DocumentNode.SelectNodes("//table[@cellspacing='1']"); // взяли нужные узлы сразу без рекламы (как писал @Moadip: "Для маньяков xpath")
project.SendInfoToLog("нашли столько узлов:" + nodes.Count.ToString(), true);
var list = new List<string>();
foreach (var node in nodes) // в цикле добавляем в список элемент состоящий из двух строчек
{
    var author = node.SelectSingleNode(".//b[@class='postauthor']").InnerText; // текст заголовка
    var post = node.SelectSingleNode(".//div[@class='postbody']']").InnerText; // текст описания
    list.Add(author + "\r\n" + post); // добавил в список "двойную строчку"
}
var res = string.Join("\r\n", list); // объединил двойный строчки
return res;
Надо:
C#:
var html = project.Variables["HTML"].Value; // html страница
var doc = new HtmlDocument();
doc.LoadHtml(html); // создали объект HtmlDocument и загрузили в него html страницу
var nodes = doc.DocumentNode.SelectNodes(@"//table[@cellspacing='1' and .//b[@class='postauthor'] and .//div[@class='postbody']]"); // взяли нужные узлы сразу без рекламы (как писал @Moadip: "Для маньяков xpath")
project.SendInfoToLog("нашли столько узлов:" + nodes.Count.ToString(), true);
var list = new List<string>();
foreach (var node in nodes) // в цикле добавляем в список элемент состоящий из двух строчек
{
    var author = node.SelectSingleNode(".//b[@class='postauthor']").InnerText; // текст заголовка
    var post = node.SelectSingleNode(".//div[@class='postbody']").InnerText; // текст описания
    list.Add(author + "\r\n" + post); // добавил в список "двойную строчку"
}
var res = string.Join("\r\n", list); // объединил двойный строчки
return res;
Почему не работало:
В "var nodes" код ищет лишние элементы, там захватило блоки без постов. А потом в коде далее вы пытаетесь из этих блоков без проверки есть ли там заголовки постов получить эти заголовки, вот оно и ругается что не с чего брать.
И опечатка в последнем Xpath:
Код:
']']"
Взял этот код. Но к сожалению не работает идеально. Перебирает посты, грубо говоря и если нет в посте нужного мне, то прерывает исполнение. Выше написано о проверках, которые нужны, то есть чтобы проверял на пустоту ли в принципе на наличие этого элемента верно? Можете пример написать на основе выше исправленного вами кода. Заранее благодарю!
 

grin-du

Client
Регистрация
09.10.2017
Сообщения
96
Благодарностей
46
Баллы
18
Было:
C#:
var html = project.Variables["HTML"].Value; // html страница
var doc = new HtmlDocument();
doc.LoadHtml(html); // создали объект HtmlDocument и загрузили в него html страницу
var nodes = doc.DocumentNode.SelectNodes("//table[@cellspacing='1']"); // взяли нужные узлы сразу без рекламы (как писал @Moadip: "Для маньяков xpath")
project.SendInfoToLog("нашли столько узлов:" + nodes.Count.ToString(), true);
var list = new List<string>();
foreach (var node in nodes) // в цикле добавляем в список элемент состоящий из двух строчек
{
    var author = node.SelectSingleNode(".//b[@class='postauthor']").InnerText; // текст заголовка
    var post = node.SelectSingleNode(".//div[@class='postbody']']").InnerText; // текст описания
    list.Add(author + "\r\n" + post); // добавил в список "двойную строчку"
}
var res = string.Join("\r\n", list); // объединил двойный строчки
return res;
Надо:
C#:
var html = project.Variables["HTML"].Value; // html страница
var doc = new HtmlDocument();
doc.LoadHtml(html); // создали объект HtmlDocument и загрузили в него html страницу
var nodes = doc.DocumentNode.SelectNodes(@"//table[@cellspacing='1' and .//b[@class='postauthor'] and .//div[@class='postbody']]"); // взяли нужные узлы сразу без рекламы (как писал @Moadip: "Для маньяков xpath")
project.SendInfoToLog("нашли столько узлов:" + nodes.Count.ToString(), true);
var list = new List<string>();
foreach (var node in nodes) // в цикле добавляем в список элемент состоящий из двух строчек
{
    var author = node.SelectSingleNode(".//b[@class='postauthor']").InnerText; // текст заголовка
    var post = node.SelectSingleNode(".//div[@class='postbody']").InnerText; // текст описания
    list.Add(author + "\r\n" + post); // добавил в список "двойную строчку"
}
var res = string.Join("\r\n", list); // объединил двойный строчки
return res;
Почему не работало:
В "var nodes" код ищет лишние элементы, там захватило блоки без постов. А потом в коде далее вы пытаетесь из этих блоков без проверки есть ли там заголовки постов получить эти заголовки, вот оно и ругается что не с чего брать.
И опечатка в последнем Xpath:
Код:
']']"
Вот тут получилось изолировать ошибку но слишком уж чопорно. Поправьте, как настоящий джентльмен, пожалуйста.
C#:
var html = project.Variables["html"].Value; // html страница
var doc = new HtmlDocument();
doc.LoadHtml(html); // создали объект HtmlDocument и загрузили в него html страницу
var nodes = doc.DocumentNode.SelectNodes(@"//div[contains(@class, 'brow-data')]"); // взяли нужные узлы сразу без рекламы (как писал @Moadip: "Для маньяков xpath")
project.SendInfoToLog("нашли столько узлов:" + nodes.Count.ToString(), true);
var list = project.Lists["Тотал"];
list.Clear();
var desc = "";
//var title = "";

foreach (var node in nodes) // в цикле добавляем в список элемент состоящий из двух строчек
{
    var title = node.SelectSingleNode(".//a[contains(@class, 'brow-book-name with-cycle')]").InnerText; // текст заголовка
  
    //var desc = node.SelectSingleNode(".//a[contains(@class, 'brow-book-author')]");
    if (node.SelectSingleNode(".//a[contains(@class, 'brow-book-author')]") != null)
    {
        var desc1 = node.SelectSingleNode(".//a[contains(@class, 'brow-book-author')]").InnerText;
        list.Add(desc1 + "\r\n" + title);
      
    }
    else
    {
        project.SendInfoToLog("Нет данного поля");

        desc = "";
        list.Add(desc + "\r\n" + title);
    }
    //list.Add(desc1 + "\r\n" + title); // добавил в список "двойную строчку"

}
var res = string.Join("\r\n", list); // объединил двойный строчки
return res;
 

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