ZennoPoster.Parser.ParseByXpath не всегда работает

ial1408

Client
Регистрация
26.07.2016
Сообщения
194
Благодарностей
18
Баллы
18
Доброго дня. Перевожу один проект с Web на запросы. Заметил такую особенность (баг). Есть код:
Код:
string strUrl = "https://site.ru";
string strDom = ZennoPoster.HttpGet(strUrl, "", "UTF-8", ZennoLab.InterfacesLibrary.Enums.Http.ResponceType.BodyOnly, 30000);
List<string> lstAnswers = new List<string>();
lstAnswers = ZennoPoster.Parser.ParseByXpath(strDom, @"//путь xpath", "innertext").ToList();
int intAnswers = lstAnswers.Count;
project.SendInfoToLog(intAnswers.ToString());
Некоторые сайты он выполняет, а некоторые выводит "Ошибка получения данных из html документа"
Если делать при отладке то будет ошибка на ZennoPoster.Parser.ParseByXpath: "Ошибка завершения действия отладчика Ссылка на объект не указывает на экземпляр объекта."
Все пути xpath и url верные так как перехожу с Web на запросы и заодно перепроверяю это все.
 

ibred

Client
Регистрация
04.04.2015
Сообщения
3 835
Благодарностей
3 552
Баллы
113
Можете привести конкретный пример с HTML страницей и xPath выражением?
Необходимо сохранить исходный код в текстовый файл, после возникновения ошибки.

Некоторые сайты он выполняет, а некоторые выводит "Ошибка получения данных из html документа"
Эта ошибка значит, что HTML элемент по данному xPath выражению не найден.
 

ial1408

Client
Регистрация
26.07.2016
Сообщения
194
Благодарностей
18
Баллы
18
Код:
string strUrl = "https://torens-auto.com/catalog/engine/?set_filter=y&arrFilter_31_1695837498=Y&arrFilter_13_1906346974=Y&arrFilter_12_3396376858=Y";

string strDom = ZennoPoster.HttpGet(strUrl, "", "UTF-8", ZennoLab.InterfacesLibrary.Enums.Http.ResponceType.BodyOnly, 30000);
List<string> lstAnswers = new List<string>();
lstAnswers = ZennoPoster.Parser.ParseByXpath(strDom, @"//table[@id='item_list']/tbody/tr", "id").ToList();
int intAnswers = lstAnswers.Count;
project.SendInfoToLog(intAnswers.ToString());
 

ibred

Client
Регистрация
04.04.2015
Сообщения
3 835
Благодарностей
3 552
Баллы
113
Как я и говорил, ошибка в xPath выражении:

Уберите tbody:
//table[@id='item_list']//tr

 
Последнее редактирование:
  • Спасибо
Реакции: Metrix и ial1408

ial1408

Client
Регистрация
26.07.2016
Сообщения
194
Благодарностей
18
Баллы
18
Как я и говорил, ошибка в xPath выражении:

Уберите tbody:
//table[@id='item_list']//tr
Странно, у меня мой xpath отрабатывает в вебе и chrome как надо


UPD. Мне не надо получать заголовки таблицы, надо получить данные (строки) этой таблицы
 
Последнее редактирование модератором:

ibred

Client
Регистрация
04.04.2015
Сообщения
3 835
Благодарностей
3 552
Баллы
113
Странно, у меня xpath отрабатывает в вебе и chrome как надо
Если Вы сейчас откроете исходный код этой страницы в Chrome, увидите, что там нет тега tbody. Его доставляет сам Chrome, поэтому в безбраузерной версии он отсутствует.

P.S. Подредактировал xPath выражение в посте выше т.к. первое было неправильным.
 

ial1408

Client
Регистрация
26.07.2016
Сообщения
194
Благодарностей
18
Баллы
18
Если Вы сейчас откроете исходный код этой страницы в Chrome, увидите, что там нет тега tbody. Его доставляет сам Chrome, поэтому в безбраузерной версии он отсутствует.
Примерно понял. Т.е. подгружает в процессе загрузки страницы? Об этом я не подумал. Спасибо. Есть ли способ забрать эти данные без браузера? Хотя бы скажите в какую сторону смотреть.
P.s. Хотя я вроде проверял этот вариант, давайте перепроверю чуть позже и отпишусь.
 

ibred

Client
Регистрация
04.04.2015
Сообщения
3 835
Благодарностей
3 552
Баллы
113
Есть ли способ забрать эти данные без браузера? Хотя бы скажите в какую сторону смотреть.
Я же выше скинул выражение, оно универсальное - работает в браузере и без браузера:
//table[@id='item_list']//tr
 
  • Спасибо
Реакции: Yuriy Zymlex и ial1408

ial1408

Client
Регистрация
26.07.2016
Сообщения
194
Благодарностей
18
Баллы
18
Я же выше скинул выражение, оно универсальное - работает в браузере и без браузера:
//table[@id='item_list']//tr
Посмотрю, спасибо, тогда надо придумать как избавится от первого элемента(заголовка). В любом случае спасибо.
 

ibred

Client
Регистрация
04.04.2015
Сообщения
3 835
Благодарностей
3 552
Баллы
113
  • Спасибо
Реакции: Yuriy Zymlex и ial1408

ial1408

Client
Регистрация
26.07.2016
Сообщения
194
Благодарностей
18
Баллы
18

ial1408

Client
Регистрация
26.07.2016
Сообщения
194
Благодарностей
18
Баллы
18
//table[@id='item_list']//tr[@id]
Спрошу здесь сразу. Мне удобнее смотреть путь в дереве html. Можно ли как то посмотреть дерево до полной загрузки страницы. Как в моем примере. Просто в голом html не очень удобно искать.
 
Регистрация
05.06.2019
Сообщения
570
Благодарностей
454
Баллы
63
Подскажите пожалуйста, из экшана "Парсить данные" все получается, а вот с конвертацией в C# нет, нету в коде, как перенести данные в список проекта.

Пример:
C#:
Tab tab = instance.ActiveTab;
// Получаем атрибут "href" всех элементов, соответствующих пути "//a"
var attributes = ZennoPoster.Parser.ParseByXpath(tab, ZennoLab.InterfacesLibrary.Enums.Parser.SourceType.Html, "//a", "href").ToList();

// Фильтруем элементы
attributes.Filter(ZennoLab.InterfacesLibrary.Enums.Parser.FilterType.None, "");

// Выбираем элементы из диапазона "all"
attributes.Range("all");
Вопрос: Как полученную коллекцию, перенести в список проекта?

Это наверное не самый лучший вариант парсинга коллекции методом xPath, раз такой случай, подскажите, как заставить работать:
C#:
HtmlElementCollection url = tab.FindElementsByXPath(@"//a/@href");
1. Нужно собрать коллекцию ссылок из тега "href", которые нужно упаковать.
2. Сохранить в список проекта.

Если я правильно понимаю, то для этого нужно:
C#:
1) string ListPath = project.Directory+ "/папка/файл.txt"; //путь к файлу-списку, куда будем сохранять.

2) List<string> ListTest = new List<string>(); // Создать объект для коллекции, куда будем складывать ссылки.
3) ListTest = ........... // Преобразовать полученные данные в коллекцию.
4) ........... //Сохранить данные в список
Места обозначенные ........... , означает, что я не знаю, решения задачи.

Вопрос: Возможно и вовсе не нужна эта коллекция, а через foreach, сразу поместить, увы с этим у меня пока трудности :(

C#:
foreach(var a in url)
{
   a.GetAttribute("href");
}
П.С. надеюсь на вашу помощь...
 
Последнее редактирование:

ibred

Client
Регистрация
04.04.2015
Сообщения
3 835
Благодарностей
3 552
Баллы
113
  • Спасибо
Реакции: Маломальский

ibred

Client
Регистрация
04.04.2015
Сообщения
3 835
Благодарностей
3 552
Баллы
113

Вложения

Регистрация
05.06.2019
Сообщения
570
Благодарностей
454
Баллы
63
Не очень понятно, откуда там взялась эта ошибка. Держите пример.
Все получилось, потому что, чек-бокс не стоял на "искать во всех фреймах", соответственно: FilterType., был без значения.

П.С. Я просто использовал весь предлагаемый код, думая, что это обязательное условие для выполнения.
C#:
// Фильтруем элементы
attributes.Filter(ZennoLab.InterfacesLibrary.Enums.Parser.FilterType.None, "");
// Выбираем элементы из диапазона "all"
attributes.Range("all");
На мой взгляд, данное решение в 3 строчки, для парсинга коллекции методом xPath, вполне прекрасное решение! Правда всех тонкостей пока не вижу, возможно что-то там с производительностью, что-то мб быстрее работает и проще, но мне нравится, возьму на заметку!

Решение через HtmlElementCollection, создавая внутренний список программы, перебирая множество собранной коллекции через foreach, делаем выжимку из атрибута и помещаем результат уже в список проекта.

C#:
IZennoList ItemList = project.Lists["Список 1"];
Tab tab = instance.ActiveTab;

HtmlElementCollection urlCollection = tab.FindElementsByXPath(@"//a");

foreach (HtmlElement a in url)
{
    string link = a.GetAttribute("href");
    ItemList.Add(link);
}
 
Последнее редактирование:
Регистрация
05.06.2019
Сообщения
570
Благодарностей
454
Баллы
63
Тоже самое решение, только через цикл for (п.с. данный метод медленнее, чем foreach, так как парсит границу списка):

C#:
IZennoList ItemList = project.Lists["Список 1"];
Tab tab = instance.ActiveTab;

HtmlElement[] urlCollection = tab.FindElementsByXPath(@"//a").Elements;


for (int i =0; i < urlCollection.Count(); i++) {

    string link = urlCollection[i].GetAttribute("href");
    ItemList.Add(link);
}
Вопрос:
1) IZennoList, это такой же объект списка, как и в программе C# List<string> ListTest = new List<string>(); ?
В чем его преимущества и отличия?

2) Не понял метод HtmlElement[], в отличие от HtmlElementCollection. Создает объект массива элементов? Просто про HtmlElement[], не написано в документации.
 
Последнее редактирование:

Advert31337

Client
Регистрация
18.12.2016
Сообщения
53
Благодарностей
38
Баллы
18
Не очень понятно
Приветствую, можешь объяснить что из себя представляет эта штука, а то в справке нет объяснения.
ZennoLab.InterfacesLibrary.Enums.Parser.SourceType.Html
и чем отличается от ... .DOM?
 

vesb

Client
Регистрация
13.03.2010
Сообщения
139
Благодарностей
18
Баллы
18
Подскажите,
Эта ошибка значит, что HTML элемент по данному xPath выражению не найден.
Подскажите а как можно тогда поправить код, чтобы если не "найден", то просто игнорировался блок
C#:
doc.LoadHtml(text);
HtmlNode elPage = doc.DocumentNode.SelectSingleNode("//div[contains(@id, 'breadcrumbs')]");
if (elPage.OuterHtml != "") {
text = text.Replace(elPage.OuterHtml, "");
}
Этот код выдает ошибку и останавливается, а мне нужно, чтобы продолжил выполнять код
 

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