Какой самый быстрый способ парсить?

Mihalich

Пользователь
Регистрация
16.08.2016
Сообщения
39
Благодарностей
3
Баллы
8
Всем доброго дня.
Пришло время оптимизировать шаблон. Судя по трейсу почти все ключевые кубики парсят по 250-300мс.

Часть сделана через кубики "обработка текста" - закидываю {-Page.Dom-} в качестве входной переменной и regex-находит нужный фрагмент.
Часть сделана через конструктор действий - добавить в проект (не знаю как этот кубик называется).

Важный момент - все искомые элементы находятся в коде на одних и тех же местах. Страница не обновляется, никаких переходов, js молча обновляет на ней кучу данных. А мой шаблон фиксирует их появление/исчезновение и парсит из них значения.

1. Какие способы парсить самые быстрые, а каких лучше избегать если нужна скорость?
2. Даже логические кубики if - и те показывают иногда по 500мс. Подскажите как условия делать на порядок быстрее?
 
Последнее редактирование:

Sergodjan

Administrator
Команда форума
Регистрация
05.09.2012
Сообщения
19 446
Благодарностей
8 677
Баллы
113
Всем доброго дня.
Пришло время оптимизировать шаблон. Судя по трейсу почти все ключевые кубики парсят по 250-300мс.

Часть сделана через кубики "обработка текста" - закидываю {-Page.Dom-} в качестве входной переменной и regex-находит нужный фрагмент.
Часть сделана через конструктор действий - добавить в проект (не знаю как этот кубик называется).

Важный момент - все искомые элементы находятся в коде на одних и тех же местах. Страница не обновляется, никаких переходов, js молча обновляет на ней кучу данных. А мой шаблон фиксирует их появление/исчезновение и парсит из них значения.

1. Какие способы парсить самые быстрые, а каких лучше избегать если нужна скорость?
2. Даже логические кубики if - и те показывают иногда по 500мс. Подскажите как условия делать на порядок быстрее?
Время работы кубиков замеряли при включенной отрисовке в ПМ?
 

amyboose

Client
Регистрация
21.04.2016
Сообщения
2 312
Благодарностей
1 191
Баллы
113
Взять весь html и закинуть в htmlagility, затем можно парсить за пару миллисекунд всё от начала до конца.
 
  • Спасибо
Реакции: Mihalich

Lord_Alfred

Client
Регистрация
09.10.2015
Сообщения
3 916
Благодарностей
3 856
Баллы
113
Взять весь html и закинуть в htmlagility, затем можно парсить за пару миллисекунд всё от начала до конца.
А ещё лучше отсниффать запросы, которые тянет js и получать всё в удобоваримом варианте (если там json).
 
  • Спасибо
Реакции: Nike59 и Mihalich

Mihalich

Пользователь
Регистрация
16.08.2016
Сообщения
39
Благодарностей
3
Баллы
8
Время работы кубиков замеряли при включенной отрисовке в ПМ?
Измерял в zennoposter через ПКМ по проекту - Трассировать выполнение - тут c:\Users\Администратор\Documents\ZennoLab\Traces\тест.xmlz\49.txt
 

Mihalich

Пользователь
Регистрация
16.08.2016
Сообщения
39
Благодарностей
3
Баллы
8
Спасибо, пошёл изучать Xpath и htmlagility в этот пост.
 
  • Спасибо
Реакции: orka13

Mihalich

Пользователь
Регистрация
16.08.2016
Сообщения
39
Благодарностей
3
Баллы
8
Подключил htmlagility и сделал C# в котором выдёргиваю один элемент и текст из него.
Но в трейсе ещё хуже стало - 500 мс в среднем.
Что делают не так? Как ускорить на порядок?

Вот код:
Код:
HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument(); // создание объекта
doc.LoadHtml(instance.ActiveTab.DomText); // грузим DOM напрямую сюда
//string temp = "";
string result = "";
//var sourceList = project.Lists["List1_Urls"]; // получаем список, с которым будем работать (в шаблоне должен уже быть пустой список List1_Urls)

var var_xpath1 = "//div[contains(@class,'buy')]/div[@class='tv-trading-toolbar__value js-value' and 2]"; // условие xpath
var Nodes_list_1 = doc.DocumentNode.SelectNodes(var_xpath1); //  получаем список элементов по условию var_xpath1

//project.SendInfoToLog("нашли столько узлов: " + Nodes_list_1.Count.ToString(), true);

// разбираем что нашли
if (Nodes_list_1 != null)
{
foreach (var res in Nodes_list_1) //  начинаем цикл
    {
           result = res.InnerText; //  получаем текст каждого элемента
        //project.SendWarningToLog("элемент = "+result,true); // в лог пишем
    }      
}
return result;
 

Mihalich

Пользователь
Регистрация
16.08.2016
Сообщения
39
Благодарностей
3
Баллы
8
Нашёл. Вот эта строчка даёт такую задержку: doc.LoadHtml(instance.ActiveTab.DomText);
Кто знает - есть какие-то более шустрые альтернативы?
 

Mihalich

Пользователь
Регистрация
16.08.2016
Сообщения
39
Благодарностей
3
Баллы
8
Вынес её из кода в кубик (Табы - Данные - взять DOM). В половине случаев он выполняется за 60мс. в половине за 600мс. В среднем получается 320мс.
Какие есть способы оптимизировать и ускорить ЗП, чтобы стабильно получать страницу для парсинга за 60-100мс?
 

samsonnn

Client
Регистрация
02.06.2015
Сообщения
1 649
Благодарностей
1 317
Баллы
113
Вынес её из кода в кубик (Табы - Данные - взять DOM). В половине случаев он выполняется за 60мс. в половине за 600мс. В среднем получается 320мс.
Какие есть способы оптимизировать и ускорить ЗП, чтобы стабильно получать страницу для парсинга за 60-100мс?
Как вариант оставить браузер в покое, и перейти на Post/Get запросы
 

Mihalich

Пользователь
Регистрация
16.08.2016
Сообщения
39
Благодарностей
3
Баллы
8
Там одна страничка загружается и дальше похоже только js-ы обновляют данные вот по такой ссылке: wss://site.com/socket.io/websocket?from=chart%2FGfc340Hb%2F&date=2018_11_16-15_48
Выглядит это нескончаемым потоком http://joxi.ru/p277BBSobdxp27?d=1
Как её слушать и вылавливать данные?
 

Hartwell

Client
Регистрация
25.09.2014
Сообщения
194
Благодарностей
117
Баллы
43
Там одна страничка загружается и дальше похоже только js-ы обновляют данные вот по такой ссылке: wss://site.com/socket.io/websocket?from=chart%2FGfc340Hb%2F&date=2018_11_16-15_48
Выглядит это нескончаемым потоком http://joxi.ru/p277BBSobdxp27?d=1
Как её слушать и вылавливать данные?
wss:// - web socket

https://kaazing.com/inspecting-websocket-traffic-with-chrome-developer-tools/


https://docs.microsoft.com/ru-ru/dotnet/api/system.net.sockets.socket?redirectedfrom=MSDN&view=netframework-4.7.2
 
  • Спасибо
Реакции: Mihalich

Mihalich

Пользователь
Регистрация
16.08.2016
Сообщения
39
Благодарностей
3
Баллы
8
Глянул, но там идут сплошные Binary Frame (Opcode 2). В хроме их контент не видно. Да и как "присосаться" к этому потоку в ЗП не знаю.
Может кто поможет? Там две цифры обновляющиеся нужно постоянно мониторить в цикле.
 

Hartwell

Client
Регистрация
25.09.2014
Сообщения
194
Благодарностей
117
Баллы
43
Глянул, но там идут сплошные Binary Frame (Opcode 2). В хроме их контент не видно. Да и как "присосаться" к этому потоку в ЗП не знаю.
Может кто поможет? Там две цифры обновляющиеся нужно постоянно мониторить в цикле.
линк бы раз такая специфика на словах

ну а в c# выглядит это как то так (с чтением данных из сокета)
на примере wss.idex.market

Код:
using System;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.IO;
using System.IO.Compression;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using System.Windows.Forms;
using System.Xml;

namespace CodeEvaler {
    public static class Program {
        public static void Main() {
            (new CodeEvaler()).Eval();
        }
    }

    public class CodeEvaler {
        public void Eval() {
            MakeRequests();
        }
//Calls request functions sequentially.
private void MakeRequests()
{
    HttpWebResponse response;
    string responseText;

    if (Request_wss_idex_market(out response))
    {
        //Success, possibly use response.
        responseText = ReadResponse(response);

        response.Close();
    }
    else
    {
        //Failure, cannot use response.
    }
}

//Returns the text contained in the response.  For example, the page HTML.  Only handles the most common HTTP encodings.
private static string ReadResponse(HttpWebResponse response)
{
    using (Stream responseStream = response.GetResponseStream())
    {
        Stream streamToRead = responseStream;
        if (response.ContentEncoding.ToLower().Contains("gzip"))
        {
            streamToRead = new GZipStream(streamToRead, CompressionMode.Decompress);
        }
        else if (response.ContentEncoding.ToLower().Contains("deflate"))
        {
            streamToRead = new DeflateStream(streamToRead, CompressionMode.Decompress);
        }

        using (StreamReader streamReader = new StreamReader(streamToRead, Encoding.UTF8))
        {
            return streamReader.ReadToEnd();
        }
    }
}

/// <summary>
/// Tries to request the URL: https://wss.idex.market/
/// </summary>
/// <param name="response">After the function has finished, will possibly contain the response to the request.</param>
/// <returns>True if the request was successful; false otherwise.</returns>
private bool Request_wss_idex_market(out HttpWebResponse response)
{
    response = null;

    try
    {
        //Create request to URL.
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://wss.idex.market/");

        //Set request headers.
        request.Headers.Set(HttpRequestHeader.Pragma, "no-cache");
        request.Headers.Set(HttpRequestHeader.CacheControl, "no-cache");
        request.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36";
        request.Headers.Set(HttpRequestHeader.Upgrade, "websocket");
        request.Headers.Add("Origin", @"https://idex.market");
        request.Headers.Add("Sec-WebSocket-Version", @"13");
        request.Headers.Set(HttpRequestHeader.AcceptEncoding, "gzip, deflate, br");
        request.Headers.Set(HttpRequestHeader.AcceptLanguage, "en,ru;q=0.9");
        request.Headers.Set(HttpRequestHeader.Cookie, @"__cfduid=d88e16e134560b5565e4770398f9333521532634285");
        request.Headers.Add("Sec-WebSocket-Key", @"cj20R8IQfpldg9qv5JxoHw==");
        request.Headers.Add("Sec-WebSocket-Extensions", @"permessage-deflate; client_max_window_bits");

        //Get response to request.
        response = (HttpWebResponse)request.GetResponse();
    }
    catch (WebException e)
    {
        //ProtocolError indicates a valid HTTP response, but with a non-200 status code (e.g. 304 Not Modified, 404 Not Found)
        if (e.Status == WebExceptionStatus.ProtocolError) response = (HttpWebResponse)e.Response;
        else return false;
    }
    catch (Exception)
    {
        if(response != null) response.Close();
        return false;
    }

    return true;
}

    }
}

альтернативный вариант заюзать js или html5, тупо локально клиент подрубать и по файлу грзить страничку с js кодом аля file:///c:/mysocket.html (но правд нахрена... если можно все через консоль туже)
 
  • Спасибо
Реакции: pym933 и Mihalich

Zy6ek

Client
Регистрация
15.09.2018
Сообщения
18
Благодарностей
6
Баллы
3
В хроме их контент не видно.
В хроме клацни вкладку WS в Network, появится соединение, жмешь на него и справа будет Headers , Frames, cookies. Жмеш на Frames и пойдут данные. Или я юзаю в ФФ дополнение WebSocket Monitor, он появится там же где и все остальное добро.
scroff6539fabbff8e.jpg
Так же рекомендую сайт https://www.websocket.org/echo.html У них есть тестовый wss к которому можно пробовать прицепится зенкой. У меня получилось на C# в Visual Studio прицепится и получать данные в wss потоке в консоли, но перенести в зенку так и не смог. Я юзал вот эту библиотеку https://github.com/sta/websocket-sharp
 
Последнее редактирование:
  • Спасибо
Реакции: Mihalich

Zy6ek

Client
Регистрация
15.09.2018
Сообщения
18
Благодарностей
6
Баллы
3
Итак получилось у меня подружить таки зенку и вебсокет. Вот рабочее решение:
В Общий код добавляем
Код:
using WebSocketSharp;
В кубик пишем:
Код:
using (var ws = new WebSocket("wss://ТВОЙПОТОК"))
{
ws.OnMessage += (sender, e) =>
project.SendInfoToLog(e.Data, true);
System.Threading.Thread.Sleep(2000);
ws.Connect();
System.Threading.Thread.Sleep(1000);
//у меня чтобы wss сервер начал отправлять данные, нужно было отправить ключевую фразу
ws.Send("сообщение которое нужно отправить");
//паузу и выход по действию прикрутиш уже сам,
System.Threading.Thread.Sleep(5000);
}
Данный код выводит в лог зенки принимаемые данные. Дальше уже сам решай куда тебе их, в список или в переменную.
Библиотека использовалась https://github.com/sta/websocket-sharp
 
Последнее редактирование:
  • Спасибо
Реакции: pym933 и Jfgertz

Jfgertz

Новичок
Регистрация
05.09.2017
Сообщения
6
Благодарностей
0
Баллы
1
Zy6ek , не могли бы вы объяснить как добавить эту библиотеку в проект?
я добавил using WebSocketSharp; в общий код, но при выполнении C# ошибка:


 

Meteorburn

Client
Регистрация
23.05.2016
Сообщения
1 446
Благодарностей
564
Баллы
113
Zy6ek , не могли бы вы объяснить как добавить эту библиотеку в проект?
я добавил using WebSocketSharp; в общий код, но при выполнении C# ошибка:


А сам dll куда нужно перенесли, а в проект добавили?

Если апи библиотеки используется в самом проекте, то using надо вписывать на вкладку директивы using
 

Jfgertz

Новичок
Регистрация
05.09.2017
Сообщения
6
Благодарностей
0
Баллы
1

Meteorburn

Client
Регистрация
23.05.2016
Сообщения
1 446
Благодарностей
564
Баллы
113

Jfgertz

Новичок
Регистрация
05.09.2017
Сообщения
6
Благодарностей
0
Баллы
1
Данный код выводит в лог зенки принимаемые данные. Дальше уже сам решай куда тебе их, в список или в переменную.
Объясните пожалуйста, как из лога перенести данные в переменную либо список?
Или же если возможно писать поток не в лог, а сразу в переменную или список.

Код:
using (var ws = new WebSocket("wss://ТВОЙПОТОК"))
{
ws.OnMessage += (sender, e) =>
project.SendInfoToLog(e.Data, true);
ws.Connect();
//паузу и выход по действию прикрутиш уже сам,
System.Threading.Thread.Sleep(5000);
}
 

Hartwell

Client
Регистрация
25.09.2014
Сообщения
194
Благодарностей
117
Баллы
43
Тип того вроде
readsocket:
ws.Connect();

if (e.IsText) {
// делаешь что то с e.Data
string project.varible = e.Data;
  return;
}}
 

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