Есть ли возможность ускорить снипет + xpath парсинг?

Gunjubasik

Client
Регистрация
30.05.2019
Сообщения
3 521
Благодарностей
1 319
Баллы
113
Доброго времени. Подскажите, пожалуйста, есть ли возможность ускорить парсинг страницы (из переменной - спрашено с помощью GET запроса) или это оптимальный вариант как получать одно конкретное значение, спарсив сначала в список как сделал я?
C#:
string Valuta1 = ZennoPoster.Parser.ParseByXpath(GET, "(//small[1]", "innertext").ToList()[0];
string Valuta2 = ZennoPoster.Parser.ParseByXpath(GET, "(//smalls[2]", "innertext").ToList()[0];
string Valuta3 = ZennoPoster.Parser.ParseByXpath(GET, "(//back[1]", "innertext").ToList()[0];
string Valuta4 = ZennoPoster.Parser.ParseByXpath(GET, "(//slaw[1]", "innertext").ToList()[0];
Потому как метод выше - на парсинг одного значения, уходит примерно 1-3 секунды, а так как мне нужно спарсить допустим 6 элементов с переменной с помощью хпаз, то уходит 5-10+ секунд, что не допустимо, когда нужно обработать 10 000+ таких данных в многопотоке, так как уходи слишком много времени. Даже пытался перед парсингом основных элементов, вырезать основной блок сайта, что бы уменьшить нагрузку парсинга, но ни капельки не помогло.
Есть варианты ускорить парсинг?

P.S. + Так же что-то явно с зеннопостером не то в многопотоке (Версия 7.4.0 \ 7.7.1), есть допустим мини-бот:
1. GET запрос - скачиваем страницу
2. Парсим снипетом выше и заполняем 6 C# переменных данными xpath (на 10 символов каждая)
3. Записываем результат в блокнот одной цельной строкой - соеденив 6 C# переменных.

И в результате такого скрипта - запустить допустим на 10 потоков - скорость будет - 10 результатов предположительно за 40 секунд. По логике вещей - если запустить 100\1000 потоков, как я и сделал - должно быть 100\1000 результатов за 40 секунд, но к сожалению в зенке такая логика не действует и скорость остается примерно та же 10 результатов за 40 секунд... Как это возможно, я вообще не понимаю, даже если:
1. ПК сильный и нагрузка при 1000 потоках - 50-60% максимум что оперативы, что ЦП.
2. Поток интернета 1 ГБ
3. Самые большие зависания - это именно на парсинге данных xpath снипетом выше... Котором может занимать 10-20 секунд, для заполнения 6ти переменных...
4. Сам сайт размером не больше 1080 высоты...
5. Никаких своих Lock-ов в коде нету.
 

radv

Client
Регистрация
11.05.2015
Сообщения
3 788
Благодарностей
1 952
Баллы
113
Попробуйте парсить напрямую из DOM через HTML Agility Pack, а не делать каждый раз гет запрос для получения кода
 
  • Спасибо
Реакции: Gunjubasik

Gunjubasik

Client
Регистрация
30.05.2019
Сообщения
3 521
Благодарностей
1 319
Баллы
113
Попробуйте парсить напрямую из DOM через HTML Agility Pack, а не делать каждый раз гет запрос для получения кода
Get запрос делается всего лишь 1 раз. Как я написал выше - данные берутся из переменной, а не из гет запроса. Есть примеры как htmlnagility pack может помочь?
 

radv

Client
Регистрация
11.05.2015
Сообщения
3 788
Благодарностей
1 952
Баллы
113
  • Спасибо
Реакции: Gunjubasik

amyboose

Client
Регистрация
21.04.2016
Сообщения
2 312
Благодарностей
1 191
Баллы
113
1) берешь outerhtml от body и закидываешь его в HtmlAgility
2) парсишь информацию уже через HtmlAgility в миллион раз быстрее
 
  • Спасибо
Реакции: Gunjubasik

Gunjubasik

Client
Регистрация
30.05.2019
Сообщения
3 521
Благодарностей
1 319
Баллы
113
1) берешь outerhtml от body и закидываешь его в HtmlAgility
2) парсишь информацию уже через HtmlAgility в миллион раз быстрее
Теперь использую такой метод, но быстрее к сожалению парсить не стало:
C#:
HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
var template_html = project.Variables["YY0_GET"].Value;
doc.LoadHtml(template_html);

string Valuta1 = doc.DocumentNode.SelectNodes(@"(//tbody//td[3][@class='bi'])[1]").Single().InnerText;
string Valuta2 = doc.DocumentNode.SelectNodes(@"(//tbody[@class='bi'])[1]").Single().InnerText;
string Valuta3 = doc.DocumentNode.SelectNodes(@"//tbody[@type]").Single().InnerText;
 
Последнее редактирование:
  • Спасибо
Реакции: djaga

amyboose

Client
Регистрация
21.04.2016
Сообщения
2 312
Благодарностей
1 191
Баллы
113
Теперь использую такой метод, но быстрее к сожалению парсить не стало:
C#:
HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
var template_html = project.Variables["YY0_GET"].Value;
doc.LoadHtml(template_html);

string Valuta1 = doc.DocumentNode.SelectNodes(@"(//tbody//td[3][@class='bi'])[1]").Single().InnerText;
string Valuta2 = doc.DocumentNode.SelectNodes(@"(//tbody[@class='bi'])[1]").Single().InnerText;
string Valuta3 = doc.DocumentNode.SelectNodes(@"//tbody[@type]").Single().InnerText;
Так это надо смотреть на все успекты. Если страница грузится 5 сек, то естественно прирост будет пару процентов, которые без запуска бенчмарков никто не заметит. Вот если бы страница грузилась 0.5 сек, то результат бы увидел сразу
 

Astraport

Client
Регистрация
01.05.2015
Сообщения
4 983
Благодарностей
4 433
Баллы
113
Теперь использую такой метод, но быстрее к сожалению парсить не стало:
Да не будет ускорения никакого. Какая разница чем разбирать строку? Все эти инструменты достаточно оптимизированы.
Для тестов попробуй ещё регулярками разобрать, если это возможно. Может они и будут быстрее.
И ещё вариант - классический парсинг по дереву элементов, этот метод тоже принимает HTML на вход.
 

Gunjubasik

Client
Регистрация
30.05.2019
Сообщения
3 521
Благодарностей
1 319
Баллы
113
Так это надо смотреть на все успекты. Если страница грузится 5 сек, то естественно прирост будет пару процентов, которые без запуска бенчмарков никто не заметит. Вот если бы страница грузилась 0.5 сек, то результат бы увидел сразу
А при чем здесь страница не совсем понял, если сама страница берется из переменной, а не с сайта? У меня стоит в логах таймер - который показывает начало парсинга из переменной и конец парсинга, что показывает - большой разницы нету.
 

Dr.Pipetka

Client
Регистрация
12.12.2017
Сообщения
1 307
Благодарностей
865
Баллы
113
Между зенкой и либой, разница как на ракете и на черепахе.

Zenno: 4514ms
HtmlAgilityPack: 378ms

C#:
var tab = instance.ActiveTab;
tab.Navigate("https://www.rambler.ru/");
tab.WaitDownloading();

//Zenno
Stopwatch sw1 = new Stopwatch();
sw1.Start();
var hecol = tab.FindElementsByXPath("//a[@href]");
foreach(var he in hecol)
{
    var tmp = he.GetAttribute("href");
    // тут типа что то делаем со ссылкой
}
sw1.Stop();

//HtmlAgilityPack
Stopwatch sw2 = new Stopwatch();
sw2.Start();
var dom = instance.ActiveTab.DomText;
var htmlDoc = new HtmlDocument();
htmlDoc.LoadHtml(dom);
var hhecol = htmlDoc.DocumentNode.SelectNodes("//a[@href]");
foreach(var he in hhecol)
{
    var tmp = he.Attributes["href"].Value;
    // тут типа что то делаем со ссылкой
}
sw2.Stop();
project.SendInfoToLog($"Zenno: {sw1.ElapsedMilliseconds}ms\n HtmlAgilityPack: {sw2.ElapsedMilliseconds}ms" );
 
  • Спасибо
Реакции: Roman48 и Astraport

Phoenix78

Client
Read only
Регистрация
06.11.2018
Сообщения
11 790
Благодарностей
5 720
Баллы
113
Между зенкой и либой, разница как на ракете и на черепахе.

Zenno: 4514ms
HtmlAgilityPack: 378ms

C#:
var tab = instance.ActiveTab;
tab.Navigate("https://www.rambler.ru/");
tab.WaitDownloading();

//Zenno
Stopwatch sw1 = new Stopwatch();
sw1.Start();
var hecol = tab.FindElementsByXPath("//a[@href]");
foreach(var he in hecol)
{
    var tmp = he.GetAttribute("href");
    // тут типа что то делаем со ссылкой
}
sw1.Stop();

//HtmlAgilityPack
Stopwatch sw2 = new Stopwatch();
sw2.Start();
var dom = instance.ActiveTab.DomText;
var htmlDoc = new HtmlDocument();
htmlDoc.LoadHtml(dom);
var hhecol = htmlDoc.DocumentNode.SelectNodes("//a[@href]");
foreach(var he in hhecol)
{
    var tmp = he.Attributes["href"].Value;
    // тут типа что то делаем со ссылкой
}
sw2.Stop();
project.SendInfoToLog($"Zenno: {sw1.ElapsedMilliseconds}ms\n HtmlAgilityPack: {sw2.ElapsedMilliseconds}ms" );
нечестное сравнение. :D
для зенно прописал получение атрибута из элемента, а это обращение к браузеру. там только одна эта команда 120-200 миллисекунд занимает.
а для HtmlAgilityPack прописал работу с переменной.
 
  • Спасибо
Реакции: djaga

Gunjubasik

Client
Регистрация
30.05.2019
Сообщения
3 521
Благодарностей
1 319
Баллы
113
Между зенкой и либой, разница как на ракете и на черепахе.

Zenno: 4514ms
HtmlAgilityPack: 378ms

C#:
var tab = instance.ActiveTab;
tab.Navigate("https://www.rambler.ru/");
tab.WaitDownloading();

//Zenno
Stopwatch sw1 = new Stopwatch();
sw1.Start();
var hecol = tab.FindElementsByXPath("//a[@href]");
foreach(var he in hecol)
{
    var tmp = he.GetAttribute("href");
    // тут типа что то делаем со ссылкой
}
sw1.Stop();

//HtmlAgilityPack
Stopwatch sw2 = new Stopwatch();
sw2.Start();
var dom = instance.ActiveTab.DomText;
var htmlDoc = new HtmlDocument();
htmlDoc.LoadHtml(dom);
var hhecol = htmlDoc.DocumentNode.SelectNodes("//a[@href]");
foreach(var he in hhecol)
{
    var tmp = he.Attributes["href"].Value;
    // тут типа что то делаем со ссылкой
}
sw2.Stop();
project.SendInfoToLog($"Zenno: {sw1.ElapsedMilliseconds}ms\n HtmlAgilityPack: {sw2.ElapsedMilliseconds}ms" );
Не совсем понял в чем разниза между моим снипетом и вашим?
C#:
HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
var template_html = project.Variables["YY0_GET"].Value;
doc.LoadHtml(template_html);

string Valuta1 = doc.DocumentNode.SelectNodes(@"(//tbody//td[3][@class='bi'])[1]").Single().InnerText;
string Valuta2 = doc.DocumentNode.SelectNodes(@"(//tbody[@class='bi'])[1]").Single().InnerText;
string Valuta3 = doc.DocumentNode.SelectNodes(@"//tbody[@type]").Single().InnerText;
И не совсем понятен метод перебора foreach, когда у меня конкретно используется метод получения разных значений из переменной после GET запроса, а не WEB открытия страницы (которая по идее еще дольше грузится будет чем get) и поиск конкретного значения. Что в моем снипете должно быть не так, что бы ваш снипет работал быстрее, чем то что я показал? Если не учитывать, что вы методом перебора ищете одно значение.
 

Phoenix78

Client
Read only
Регистрация
06.11.2018
Сообщения
11 790
Благодарностей
5 720
Баллы
113
Между зенкой и либой, разница как на ракете и на черепахе.

Zenno: 4514ms
HtmlAgilityPack: 378ms

C#:
var tab = instance.ActiveTab;
tab.Navigate("https://www.rambler.ru/");
tab.WaitDownloading();

//Zenno
Stopwatch sw1 = new Stopwatch();
sw1.Start();
var hecol = tab.FindElementsByXPath("//a[@href]");
foreach(var he in hecol)
{
    var tmp = he.GetAttribute("href");
    // тут типа что то делаем со ссылкой
}
sw1.Stop();

//HtmlAgilityPack
Stopwatch sw2 = new Stopwatch();
sw2.Start();
var dom = instance.ActiveTab.DomText;
var htmlDoc = new HtmlDocument();
htmlDoc.LoadHtml(dom);
var hhecol = htmlDoc.DocumentNode.SelectNodes("//a[@href]");
foreach(var he in hhecol)
{
    var tmp = he.Attributes["href"].Value;
    // тут типа что то делаем со ссылкой
}
sw2.Stop();
project.SendInfoToLog($"Zenno: {sw1.ElapsedMilliseconds}ms\n HtmlAgilityPack: {sw2.ElapsedMilliseconds}ms" );
вот такой код , выдал у меня 277 мс. что даже быстрей чем у тебя HtmlAgilityPack выдал :bk:
C#:
var tab = instance.ActiveTab;
tab.Navigate("https://www.rambler.ru/");
tab.WaitDownloading();

//Zenno
Stopwatch sw1 = new Stopwatch();
sw1.Start();
var dom = instance.ActiveTab.DomText;
var Valus = ZennoPoster.Parser.ParseByXpath(dom, "//a[@href]", "href").ToList();
foreach(var he in Valus)
{
    var tmp = he;
    // тут типа что то делаем со ссылкой
}
sw1.Stop();

return sw1.ElapsedMilliseconds;

HtmlAgilityPack я не стал подключать.
так что вопрос про что быстрей остается открытым ;-)
 
  • Спасибо
Реакции: djaga

Dr.Pipetka

Client
Регистрация
12.12.2017
Сообщения
1 307
Благодарностей
865
Баллы
113
вот такой код , выдал у меня 277 мс. что даже быстрей чем у тебя HtmlAgilityPack выдал :bk:
C#:
var tab = instance.ActiveTab;
tab.Navigate("https://www.rambler.ru/");
tab.WaitDownloading();

//Zenno
Stopwatch sw1 = new Stopwatch();
sw1.Start();
var dom = instance.ActiveTab.DomText;
var Valus = ZennoPoster.Parser.ParseByXpath(dom, "//a[@href]", "href").ToList();
foreach(var he in Valus)
{
    var tmp = he;
    // тут типа что то делаем со ссылкой
}
sw1.Stop();

return sw1.ElapsedMilliseconds;

HtmlAgilityPack я не стал подключать.
так что вопрос про что быстрей остается открытым ;-)
Все же библиотека и в этом случае быстрее:-)
Zenno: 4470ms
HtmlAgilityPack: 344ms
ZennoParse: 387ms

C#:
var tab = instance.ActiveTab;

tab.Navigate("https://www.rambler.ru/");
tab.WaitDownloading();
//Zenno
Stopwatch sw1 = new Stopwatch();
sw1.Start();
var hecol = tab.FindElementsByXPath("//a[@href]");
foreach(var he in hecol)
{
    var tmp = he.GetAttribute("href");
    // тут типа что то делаем со ссылкой
}
sw1.Stop();
//HtmlAgilityPack
Stopwatch sw2 = new Stopwatch();
sw2.Start();
var dom = instance.ActiveTab.DomText;
var htmlDoc = new HtmlDocument();
htmlDoc.LoadHtml(dom);
var hhecol = htmlDoc.DocumentNode.SelectNodes("//a[@href]");
foreach(var he in hhecol)
{
    var tmp = he.Attributes["href"].Value;
    // тут типа что то делаем со ссылкой
}
sw2.Stop();
// zenno parse
Stopwatch sw3 = new Stopwatch();
sw3.Start();
dom = instance.ActiveTab.DomText;
var Valus = ZennoPoster.Parser.ParseByXpath(dom, "//a[@href]", "href").ToList();
foreach(var he in Valus)
{
    var tmp = he;
    // тут типа что то делаем со ссылкой
}
sw3.Stop();

project.SendInfoToLog($"Zenno: {sw1.ElapsedMilliseconds}ms\n HtmlAgilityPack: {sw2.ElapsedMilliseconds}ms\n ZennoParse: {sw3.ElapsedMilliseconds}ms" );
 

amyboose

Client
Регистрация
21.04.2016
Сообщения
2 312
Благодарностей
1 191
Баллы
113
Между зенкой и либой, разница как на ракете и на черепахе.

Zenno: 4514ms
HtmlAgilityPack: 378ms

C#:
var tab = instance.ActiveTab;
tab.Navigate("https://www.rambler.ru/");
tab.WaitDownloading();

//Zenno
Stopwatch sw1 = new Stopwatch();
sw1.Start();
var hecol = tab.FindElementsByXPath("//a[@href]");
foreach(var he in hecol)
{
    var tmp = he.GetAttribute("href");
    // тут типа что то делаем со ссылкой
}
sw1.Stop();

//HtmlAgilityPack
Stopwatch sw2 = new Stopwatch();
sw2.Start();
var dom = instance.ActiveTab.DomText;
var htmlDoc = new HtmlDocument();
htmlDoc.LoadHtml(dom);
var hhecol = htmlDoc.DocumentNode.SelectNodes("//a[@href]");
foreach(var he in hhecol)
{
    var tmp = he.Attributes["href"].Value;
    // тут типа что то делаем со ссылкой
}
sw2.Stop();
project.SendInfoToLog($"Zenno: {sw1.ElapsedMilliseconds}ms\n HtmlAgilityPack: {sw2.ElapsedMilliseconds}ms" );
Stopwatch надо запускать после этой части кода
C#:
var dom = instance.ActiveTab.DomText;
И использовать Body.OuterHtml вместо DomText с текстом внутри конкретного фрейма, так как парсер HtmlAgility тоже мучается, когда видит кривой Dom. Зато движок браузера уже за нас сделал всю работу по исправлению всех ошибок структуры Html.
 

amyboose

Client
Регистрация
21.04.2016
Сообщения
2 312
Благодарностей
1 191
Баллы
113
Zenno: 5527ms
HtmlAgilityPack: 230ms

Часть кода:
C#:
Stopwatch sw2 = new Stopwatch();
            sw2.Start();
            var dom = instance.ActiveTab.MainDocument.Body.OuterHtml;
            var htmlDoc = new HtmlDocument();
            htmlDoc.LoadHtml(dom);
            var hhecol = htmlDoc.DocumentNode.SelectNodes("//a[@href]");
            foreach (var he in hhecol)
            {
                var tmp = he.Attributes["href"].Value;
                // тут типа что то делаем со ссылкой
            }
            sw2.Stop();
 
Последнее редактирование:
  • Спасибо
Реакции: AtlanticsSurfer

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