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

  • Автор темы Автор темы ial1408
  • Дата начала Дата начала

ial1408

Client
Регистрация
26.07.2016
Сообщения
219
Реакции
24
Баллы
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 на запросы и заодно перепроверяю это все.
 
Можете привести конкретный пример с HTML страницей и xPath выражением?
Необходимо сохранить исходный код в текстовый файл, после возникновения ошибки.

Некоторые сайты он выполняет, а некоторые выводит "Ошибка получения данных из html документа"
Эта ошибка значит, что HTML элемент по данному xPath выражению не найден.
 
Код:
Развернуть Свернуть Копировать
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());
 
Как я и говорил, ошибка в xPath выражении:

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

uXMLBpz.png
 
Последнее редактирование:
  • Спасибо
Реакции: Metrix и ial1408
Как я и говорил, ошибка в xPath выражении:

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


UPD. Мне не надо получать заголовки таблицы, надо получить данные (строки) этой таблицы
 
Последнее редактирование модератором:
Странно, у меня xpath отрабатывает в вебе и chrome как надо
Если Вы сейчас откроете исходный код этой страницы в Chrome, увидите, что там нет тега tbody. Его доставляет сам Chrome, поэтому в безбраузерной версии он отсутствует.

P.S. Подредактировал xPath выражение в посте выше т.к. первое было неправильным.
 
Если Вы сейчас откроете исходный код этой страницы в Chrome, увидите, что там нет тега tbody. Его доставляет сам Chrome, поэтому в безбраузерной версии он отсутствует.
Примерно понял. Т.е. подгружает в процессе загрузки страницы? Об этом я не подумал. Спасибо. Есть ли способ забрать эти данные без браузера? Хотя бы скажите в какую сторону смотреть.
P.s. Хотя я вроде проверял этот вариант, давайте перепроверю чуть позже и отпишусь.
 
Есть ли способ забрать эти данные без браузера? Хотя бы скажите в какую сторону смотреть.
Я же выше скинул выражение, оно универсальное - работает в браузере и без браузера:
//table[@id='item_list']//tr
 
  • Спасибо
Реакции: ZX и ial1408
Я же выше скинул выражение, оно универсальное - работает в браузере и без браузера:
//table[@id='item_list']//tr
Посмотрю, спасибо, тогда надо придумать как избавится от первого элемента(заголовка). В любом случае спасибо.
 
//table[@id='item_list']//tr[@id]
Спрошу здесь сразу. Мне удобнее смотреть путь в дереве html. Можно ли как то посмотреть дерево до полной загрузки страницы. Как в моем примере. Просто в голом html не очень удобно искать.
 
Подскажите пожалуйста, из экшана "Парсить данные" все получается, а вот с конвертацией в 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");
}

П.С. надеюсь на вашу помощь...
 
Последнее редактирование:
Вопрос: Как полученную коллекцию, перенести в список проекта?
C#:
Развернуть Свернуть Копировать
Tab tab = instance.ActiveTab;
var attributes = ZennoPoster.Parser.ParseByXpath(tab, ZennoLab.InterfacesLibrary.Enums.Parser.SourceType.Html, "//a", "href").ToList();
project.Lists["Список 1"].AddRange(attributes);
 
  • Спасибо
Реакции: Маломальский

Вложения

Не очень понятно, откуда там взялась эта ошибка. Держите пример.
Все получилось, потому что, чек-бокс не стоял на "искать во всех фреймах", соответственно: 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);
}
 
Последнее редактирование:
Тоже самое решение, только через цикл 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[], не написано в документации.
 
Последнее редактирование:
Не очень понятно
Приветствую, можешь объяснить что из себя представляет эта штука, а то в справке нет объяснения.
ZennoLab.InterfacesLibrary.Enums.Parser.SourceType.Html
и чем отличается от ... .DOM?
 
Подскажите,
Эта ошибка значит, что HTML элемент по данному xPath выражению не найден.

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

Этот код выдает ошибку и останавливается, а мне нужно, чтобы продолжил выполнять код
 

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