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

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

The_vAe

Client
Регистрация
30.05.2019
Сообщения
3 759
Реакции
1 493
Баллы
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-ов в коде нету.
 
Попробуйте парсить напрямую из DOM через HTML Agility Pack, а не делать каждый раз гет запрос для получения кода
 
  • Оценить
Реакции: The_vAe
Попробуйте парсить напрямую из DOM через HTML Agility Pack, а не делать каждый раз гет запрос для получения кода
Get запрос делается всего лишь 1 раз. Как я написал выше - данные берутся из переменной, а не из гет запроса. Есть примеры как htmlnagility pack может помочь?
 
  • Оценить
Реакции: The_vAe
1) берешь outerhtml от body и закидываешь его в HtmlAgility
2) парсишь информацию уже через HtmlAgility в миллион раз быстрее
 
  • Оценить
Реакции: The_vAe
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
Теперь использую такой метод, но быстрее к сожалению парсить не стало:
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 сек, то результат бы увидел сразу
 
Теперь использую такой метод, но быстрее к сожалению парсить не стало:
Да не будет ускорения никакого. Какая разница чем разбирать строку? Все эти инструменты достаточно оптимизированы.
Для тестов попробуй ещё регулярками разобрать, если это возможно. Может они и будут быстрее.
И ещё вариант - классический парсинг по дереву элементов, этот метод тоже принимает HTML на вход.
 
Так это надо смотреть на все успекты. Если страница грузится 5 сек, то естественно прирост будет пару процентов, которые без запуска бенчмарков никто не заметит. Вот если бы страница грузилась 0.5 сек, то результат бы увидел сразу
А при чем здесь страница не совсем понял, если сама страница берется из переменной, а не с сайта? У меня стоит в логах таймер - который показывает начало парсинга из переменной и конец парсинга, что показывает - большой разницы нету.
 
Между зенкой и либой, разница как на ракете и на черепахе.

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
Между зенкой и либой, разница как на ракете и на черепахе.

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
Между зенкой и либой, разница как на ракете и на черепахе.

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) и поиск конкретного значения. Что в моем снипете должно быть не так, что бы ваш снипет работал быстрее, чем то что я показал? Если не учитывать, что вы методом перебора ищете одно значение.
 
Между зенкой и либой, разница как на ракете и на черепахе.

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
вот такой код , выдал у меня 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" );
 
Между зенкой и либой, разница как на ракете и на черепахе.

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.
 
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

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