Использование xpath на чистом html

z@jivalo

Client
Регистрация
27.12.2016
Сообщения
800
Благодарностей
179
Баллы
43
Облазил довольно много форумов но вот что-то не нашел, как мне использовать
прекраснейший xpath без загрузки страницы или DOM, а из чистого html который находится в переменной.

Ну вот пример: сделал я GET запрос на http://lessons.zennolab.com/captchas/
результат попал в переменную и вот как теперь обратиться к этой переменной через xpath и что-то от туда вытащить.

Во всех примерах только требуется instance.ActiveTab.FindElementByXPath но это не то.
 

z@jivalo

Client
Регистрация
27.12.2016
Сообщения
800
Благодарностей
179
Баллы
43
Можно и регулярками но я думаю что регулярка может ошибиться и взять не нужное.
вот пример кода.

Тут привязаться сложно так как id и name не уникальный они могут так же меняться

Код:
<div class="code_sum">
<table width="100%" id="codes_table0" border="0" cellpadding="2" cellspacing="2" class="new_table2">
    <tr>
    <td colspan="2" class="big_text">Скопируйте код </td>
    </tr>
<tr>
<td width="50%"><b>BBCODE для форумов</b>, превью </td>
<td width="53%"><input name="c12" type="text" class="code_inputs" id="c12" onClick="this.select();" value="[URL=http://fotosite.ru/12840076/658972/][IMG]http://fotosite.ru/allimage/2017/8-10/img_thumb/658972-thumb.jpeg[/IMG][/URL]"></td>
</tr>
<tr>
<td><b>BBCODE для форумов</b>, полная картинка </td> </td>
<td><input name="c13" type="text" class="code_inputs" id="c13" onClick="this.select();" value="[URL=http://fotosite.ru/12840076/658972/][IMG]http://fotosite.ru/allimage/2017/8-10/img_full/658972.jpeg[/IMG][/URL]"></td>
</tr>
<tr>
<td><b>HTML превью</b></td>
<td><input name="c14" type="text" class="code_inputs" id="c14" onClick="this.select();" value="&lt;a href=&quot;http://fotosite.ru/12840076/658972/&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;http://fotosite.ru/allimage/2017/8-10/img_thumb/658972-thumb.jpeg&quot;&gt;&lt;/a&gt;"></td>
</tr>
<tr>
<td><b>HTML полная картинка</b></td>
<td><input name="c15" type="text" class="code_inputs" id="c15" onClick="this.select();" value="&lt;a href=&quot;http://fotosite.ru/12840076/658972/&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;http://fotosite.ru/allimage/2017/8-10/img_full/658972.jpeg&quot;&gt;&lt;/a&gt;"></td>
</tr>
<tr>
<td><b>Прямая ссылка</b></td>
<td><input name="c1" type="text" class="code_inputs" id="c1" onClick="this.select();" value="http://fotosite.ru/12840076/658972/"></td>
Надо вытащить значения атрибутов value
 

Aleksk

Client
Регистрация
19.06.2013
Сообщения
31
Благодарностей
23
Баллы
8
Код:
// переменная x с html кодом после гет запроса
var x = project.Variables["dom"].Value;

instance.ActiveTab.MainDocument.Body.SetAttribute("innerHtml", x);
 

Troll_UA

Client
Регистрация
11.04.2016
Сообщения
121
Благодарностей
38
Баллы
28
Облазил довольно много форумов но вот что-то не нашел, как мне использовать
прекраснейший xpath без загрузки страницы или DOM, а из чистого html который находится в переменной.

Ну вот пример: сделал я GET запрос на http://lessons.zennolab.com/captchas/
результат попал в переменную и вот как теперь обратиться к этой переменной через xpath и что-то от туда вытащить.

Во всех примерах только требуется instance.ActiveTab.FindElementByXPath но это не то.
Можно использовать библиотеку Html Agility Pack. А вот пример реализации сниппета.
 
  • Спасибо
Реакции: z@jivalo

z@jivalo

Client
Регистрация
27.12.2016
Сообщения
800
Благодарностей
179
Баллы
43

z@jivalo

Client
Регистрация
27.12.2016
Сообщения
800
Благодарностей
179
Баллы
43

Aleksk

Client
Регистрация
19.06.2013
Сообщения
31
Благодарностей
23
Баллы
8
Берем код html который находится в переменной допустим х,
устанавливаем его в активную вкладку - instance.ActiveTab.MainDocument.Body.SetAttribute("innerHtml", x);
Дальше работаем как с обычной страницей через методы instance.ActiveTab.FindElementByXPath
 
  • Спасибо
Реакции: z@jivalo

z@jivalo

Client
Регистрация
27.12.2016
Сообщения
800
Благодарностей
179
Баллы
43
альше работаем как с обычной страницей
этот вариант думаю и буду использовать, просто хотелось не запускать браузер с экономить важные секунды во время выполнения шаблона

так понимаю, данный способ не делает обращения к сайту?
он просто запускает исходный html код ?
 

Aleksk

Client
Регистрация
19.06.2013
Сообщения
31
Благодарностей
23
Баллы
8
этот вариант думаю и буду использовать, просто хотелось не запускать браузер с экономить важные секунды во время выполнения шаблона

так понимаю, данный способ не делает обращения к сайту?
он просто запускает исходный html код ?
Вы работаете с html кодом с гет запроса, никаких запросов к сайту нет и секундных задержек также нет
 

z@jivalo

Client
Регистрация
27.12.2016
Сообщения
800
Благодарностей
179
Баллы
43
Чуть чуть поторопился со второй img
Код:
(?<=value="\[URL=).*?(?=])
получить значение из атрибута value это значить получить все что находится внутри
Вот что надо получить, что находиться в кавычках, при условии что тег input имеет name="c1" который меняется

Код:
value="[URL=http://fotosite.ru/12840076/658972/][IMG]http://fotosite.ru/allimage/2017/8-10/img_thumb/658972-thumb.jpeg[/IMG][/URL]"
 

z@jivalo

Client
Регистрация
27.12.2016
Сообщения
800
Благодарностей
179
Баллы
43

doc

Client
Регистрация
30.03.2012
Сообщения
8 684
Благодарностей
4 641
Баллы
113
Вы работаете с html кодом с гет запроса, никаких запросов к сайту нет и секундных задержек также нет
запросов к сайту нет, вот только для работы с инстансом, если я не ошибаюсь, должен быть включён браузер. А скорость работы и ресурсозатраты браузерного и безбраузерного проекта очень сильно отличаются

Вообще, Я немного отстал от обнов, но кажется в какой-то из версий вшивали библиотеку хтмл агилити пак
 
  • Спасибо
Реакции: orka13

z@jivalo

Client
Регистрация
27.12.2016
Сообщения
800
Благодарностей
179
Баллы
43
запросов к сайту нет, вот только для работы с инстансом, если я не ошибаюсь, должен быть включён браузер. А скорость работы и ресурсозатраты браузерного и безбраузерного проекта очень сильно отличаются
вот именно что ресурсы поджирать будет, я и хотел в будущем использовать чистый html +xpath может не много regex
по поводу либы пацаны пишут что она уже давно в off ушла в плане разработки баги многолетней давности не фиксять и бывает так что сыплется
 

orka13

Client
Регистрация
07.05.2015
Сообщения
2 177
Благодарностей
2 184
Баллы
113
Изучал чистый xpath (HtmlAgilityPack, без использования браузера для POST\GET запросов) последний месяц под свои нужды. Очень часто в новичков на форуме проблемы с его подключением. Так что вот пример шаблона с подключенными библиотеками, СКАЧАТЬ ПРИМЕР.
Основной код из шаблона:
C#:
HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument(); // создание объекта
var template_html = project.Variables["Htnl_Code"].Value; // грузим наш код
// условие xpath, если надо найти все элементы с value, где тег input имеет name='c1':
var var_xpath1 = @"//*[@value and @name='c1']";
// или условие xpath, если надо найти просто все элементы с value:
// var var_xpath1 = @"//*[@value]";
string temp = "";
string result = "";

doc.LoadHtml(template_html); // грузим DOM текст (из переменной template_html) в объект doc

// получаем список, с которым будем работать (в шаблоне должен уже быть пустой список List1_Urls)
var sourceList = project.Lists["List1_Urls"];

var Nodes_list_1 = doc.DocumentNode.SelectNodes(var_xpath1); //  получаем список элементов по условию var_xpath1
if (Nodes_list_1 != null) //  обязательно надо делать проверку "не пустой ли результат"
{
foreach (var res in Nodes_list_1) //  начинаем цикл
    {
          temp = res.GetAttributeValue("value", ""); //  получаем значение value каждого элемента
        result += temp + "\r\n"; //  добавляем его в переменную, каждое значение с новой строки
        sourceList.Add(temp); //  и добавляем его в список (кому как удобнее)
  
    }  
}
return result;
Шаблон работает с использованием Html Agility Pack (.NET парсер HTML).
Поэтому для его работы надо закинуть содержимое папки "ExternalAssemblies" в аналогическую папку ZennoPoster, пример у меня:
c:\Program Files (x86)\ZennoLab\RU\ZennoPoster Pro\5.11.5.0\Progs\ExternalAssemblies\
Ети файлы я тестировал на своем «Windows 10». Они взяты из файла «HtmlAgilityPack.1.5.1\lib\Net45\» (под .NET Framework 4.5). Все актуальные версии файлов можно посмотреть на сайте разработчиков: https://www.nuget.org/packages/HtmlAgilityPack/1.5.1 . Они там правда распаковываются через их консольную утилиту.
Если с этими файлами шаблон не запускается без ошибок, значит чего-то не хватает, и надо разбираться.

Почти все нюансы работы с HtmlAgilityPack разбирались на форуме. Я вот себе в закладки добавил самые важные ссылки из сети:
http://zennolab.com/discussion/threads/problema-s-parsingom-v-amazon.32660/
http://citforum.ru/internet/xpath/xpath.shtml
http://kronus.me/2011/04/введение-в-xpath-на-примере-простого-парсе/
https://docs.google.com/document/d/1PdfKMDfoqFIlF4tN1jKrOf1iZ1rqESy2xVMIj3uuV3g/pub#h.pazner1ml919
http://onedev.net/post/458
http://html-agility-pack.net/api
https://stackoverflow.com/questions/5801828/html-agility-pack-null-reference
 
Последнее редактирование:

z@jivalo

Client
Регистрация
27.12.2016
Сообщения
800
Благодарностей
179
Баллы
43

iBotovod

Client
Регистрация
01.07.2017
Сообщения
56
Благодарностей
19
Баллы
8

up_lvl

Client
Регистрация
02.09.2014
Сообщения
131
Благодарностей
53
Баллы
28
Помогите плз с htmlagility, сейчас голова взорвётся

Есть тело поста с вложенным в него репостом, но оба имеют одинаковый div с class="story_body"

Необходимо выбрать узел минуя вложенный div[@class=\"story_body\"], то есть выбрать сам головной пост без вложенного репоста чтоб в результате в переменной было то что зеленым выделено на скрине (см. внутри архива).
 

Вложения

Moadip

Client
Регистрация
26.09.2015
Сообщения
509
Благодарностей
824
Баллы
93
upload_2018-4-10_18-9-8.png
Можно сделать вот так. Т.е. будет браться только верхний узел post_body.
Но выбрать только верхний узел post_body, чтобы не брался внутренний, так не получится. Т.к. при выборе узла, берется все что внутри него.

Если нужен именно верхний узел, и надо чтобы внутреннего не было, то тут тогда только один вариант, берется весь узел, а потом внутри него удаляется post_body.
 
  • Спасибо
Реакции: up_lvl

up_lvl

Client
Регистрация
02.09.2014
Сообщения
131
Благодарностей
53
Баллы
28
Понял, спасибо. Ещё я поковырялся и думаю пилить логику от присутствия/отсутствия репоста
"//div[@class=\"story_body\"]/descendant::div[@class=\"story_body\"]"

А вообще у меня в похожем кейсе помогло это решение:
https://www.experts-exchange.com/questions/28936346/Select-top-level-tables-using-HtmlAgilityPack.html
Там ответ с //table[not(ancestor::table)]

Но в этом случае с репостом наверно всё же вёрстка и вложенность отличается, ибо не работает, хотя я так и не понял в чём разница.
 

nik-n

Client
Регистрация
05.11.2016
Сообщения
242
Благодарностей
20
Баллы
18
Изучал чистый xpath (HtmlAgilityPack, без использования браузера для POST\GET запросов) последний месяц под свои нужды. Очень часто в новичков на форуме проблемы с его подключением. Так что вот пример шаблона с подключенными библиотеками, СКАЧАТЬ ПРИМЕР.
Основной код из шаблона:
C#:
HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument(); // создание объекта
var template_html = project.Variables["Htnl_Code"].Value; // грузим наш код
// условие xpath, если надо найти все элементы с value, где тег input имеет name='c1':
var var_xpath1 = @"//*[@value and @name='c1']";
// или условие xpath, если надо найти просто все элементы с value:
// var var_xpath1 = @"//*[@value]";
string temp = "";
string result = "";

doc.LoadHtml(template_html); // грузим DOM текст (из переменной template_html) в объект doc

// получаем список, с которым будем работать (в шаблоне должен уже быть пустой список List1_Urls)
var sourceList = project.Lists["List1_Urls"];

var Nodes_list_1 = doc.DocumentNode.SelectNodes(var_xpath1); //  получаем список элементов по условию var_xpath1
if (Nodes_list_1 != null) //  обязательно надо делать проверку "не пустой ли результат"
{
foreach (var res in Nodes_list_1) //  начинаем цикл
    {
          temp = res.GetAttributeValue("value", ""); //  получаем значение value каждого элемента
        result += temp + "\r\n"; //  добавляем его в переменную, каждое значение с новой строки
        sourceList.Add(temp); //  и добавляем его в список (кому как удобнее)
 
    } 
}
return result;
Шаблон работает с использованием Html Agility Pack (.NET парсер HTML).
Поэтому для его работы надо закинуть содержимое папки "ExternalAssemblies" в аналогическую папку ZennoPoster, пример у меня:
c:\Program Files (x86)\ZennoLab\RU\ZennoPoster Pro\5.11.5.0\Progs\ExternalAssemblies\
Ети файлы я тестировал на своем «Windows 10». Они взяты из файла «HtmlAgilityPack.1.5.1\lib\Net45\» (под .NET Framework 4.5). Все актуальные версии файлов можно посмотреть на сайте разработчиков: https://www.nuget.org/packages/HtmlAgilityPack/1.5.1 . Они там правда распаковываются через их консольную утилиту.
Если с этими файлами шаблон не запускается без ошибок, значит чего-то не хватает, и надо разбираться.

Почти все нюансы работы с HtmlAgilityPack разбирались на форуме. Я вот себе в закладки добавил самые важные ссылки из сети:
http://zennolab.com/discussion/threads/problema-s-parsingom-v-amazon.32660/
http://citforum.ru/internet/xpath/xpath.shtml
http://kronus.me/2011/04/введение-в-xpath-на-примере-простого-парсе/
https://docs.google.com/document/d/1PdfKMDfoqFIlF4tN1jKrOf1iZ1rqESy2xVMIj3uuV3g/pub#h.pazner1ml919
http://onedev.net/post/458
http://html-agility-pack.net/api
https://stackoverflow.com/questions/5801828/html-agility-pack-null-reference
сделал по примеру, затрахался уже голову ломать что не так.
достает одну пустую строку и все.
 

Вложения

orka13

Client
Регистрация
07.05.2015
Сообщения
2 177
Благодарностей
2 184
Баллы
113
сделал по примеру, затрахался уже голову ломать что не так.
достает одну пустую строку и все.
1. гуглим HtmlAgilityPack innerhtml
2. видим что там вовсе не так InnerHtml парсится как у вас, а так:
3, Меняем у себя строку:
C#:
temp = res.GetAttributeValue("innerhtml", "");
на:
C#:
temp = res.InnerHtml;
 
  • Спасибо
Реакции: nik-n

nik-n

Client
Регистрация
05.11.2016
Сообщения
242
Благодарностей
20
Баллы
18
лишний пост.... удалить )
 

nik-n

Client
Регистрация
05.11.2016
Сообщения
242
Благодарностей
20
Баллы
18
1. гуглим HtmlAgilityPack innerhtml
2. видим что там вовсе не так InnerHtml парсится как у вас, а так:
3, Меняем у себя строку:
C#:
temp = res.GetAttributeValue("innerhtml", "");
на:
C#:
temp = res.InnerHtml;
низкий поклон!
 
  • Спасибо
Реакции: z@jivalo

ial1408

Client
Регистрация
26.07.2016
Сообщения
194
Благодарностей
18
Баллы
18
C#:
string strTest = ZennoPoster.Parser.ParseByXpath(strDom, "//a", "innertext").ToList()[0].Trim();
 
  • Спасибо
Реакции: doc

nik-n

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

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