Leaf.xNet - Библиотека для работы с запросами: Get, Post, Put, Path, Delete, Option.

RoyalBank

Client
Регистрация
07.09.2015
Сообщения
557
Благодарностей
550
Баллы
93
intro.jpg


Приветствую всех!

В статье рассмотрим примеры работы с библиотекой Leaf.xNet, являющейся форком xNet.

Из коробки доступны следующие методы:
  • GET
  • POST
  • PATCH
  • DELETE
  • PUT
  • OPTIONS

Подключаем библиотеку:
  1. Leaf.xNet.dll копируем в папку ExternalAssemblies
  2. Добавляем в GAC
  3. Прописываем в Директивы using и общий код:
C#:
using Leaf.xNet; // dll
using HttpStatusCode = Leaf.xNet.HttpStatusCode; // debug request
using System.Net; // cookie

Для работы с запросами можно использовать две конструкции.

///++++++++++++++++++++++++++++++++++++++++++
/// Конструкция работы с запросом #1: using
///++++++++++++++++++++++++++++++++++++++++++


C#:
using (var request = new HttpRequest())
{
    request.Get("https://zennolab.com");
}
Преимущества:
  • Короткая запись если необходимо сделать простой запрос;
  • Используя using, нам не нужно закрывать (dispose) запрос;
Также мы можем объявить запрос предварительно и затем передать его в using. В случае, если необходимо скачать файл используя cookie.

C#:
HttpRequest request = null;

using (request)
{
    var resp = request.Get("http://google.com/file.zip");
    resp.ToFile("C:\\myDownloadedFile.zip");
}

///++++++++++++++++++++++++++++++++++++++++++
/// Конструкция работы с запросом #2: try, catch, finally
///++++++++++++++++++++++++++++++++++++++++++


Эта конструкция позволяет использовать более детальный формат сообщений об ошибках, таким образом, можно продумать разные сценарии на каждый тип ошибки.

C#:
HttpRequest request = null;

try
{

}
catch (HttpException ex)
{
    project.SendErrorToLog(String.Format("HttpException: {0}", ex.Message)), true);

    switch (ex.Status)
    {
        case HttpExceptionStatus.Other:
            project.SendErrorToLog("Unknown error", true);
        break;

        case HttpExceptionStatus.ProtocolError:
            project.SendErrorToLog(String.Format("Status code: {0}", (int)ex.HttpStatusCode)), true);
        break;

        case HttpExceptionStatus.ConnectFailure:
            project.SendErrorToLog("Failed to connect to the HTTP-server.", true);
        break;

        case HttpExceptionStatus.SendFailure:
            project.SendErrorToLog("Failed to send request to HTTP-server.", true);
        break;

        case HttpExceptionStatus.ReceiveFailure:
            project.SendErrorToLog("Failed to load response from HTTP-server.", true);
        break;
    }
}
finally
{
    request.Dispose();
}
В подобной конструкции необходимо всегда закрывать запрос, это делается через finally.


///++++++++++++++++++++++++++++++++++++++++++
/// Отладка запроса
///++++++++++++++++++++++++++++++++++++++++++


Помимо отладки ошибок запроса через конструкцию catch, мы можем также отладить ответ в конструкции try.

К примеру, по какой-то причине могут тупить прокси или сервер, к которому идет обращение. В этом случае можно воспользоваться следующей конструкцией внутри try.

C#:
HttpRequest request = null;

request.IgnoreProtocolErrors = true; // В этом случае блок catch не будет выходить по ошибке.

string _request = null;

try
{
    // Создадим цикл из пяти запросов.
    for (int i = 1; i <= 5; i++)
    {
        var responce = request.Get("https://zennolab.com");

        if (responce.StatusCode == HttpStatusCode.OK)
        {
            // HTTP status 200 - выходим из цикла, запрос вернул ответ
            _request = responce.ToString();
            break;
        }
        else if (responce.StatusCode == HttpStatusCode.NotFound)
        {
            // HTTP status 404
            throw new Exception("Сервер вернул 404 - Страница не найдена");
        }
        if (responce.StatusCode == HttpStatusCode.InternalServerError)
        {
            // HTTP status 500
            project.SendErrorToLog("Сервер вернул 500 - Сервер приболел, сделаем паузу", true);
            Thread.Sleep(2000);
        }
        else if (Responce.Address.AbsolutePath.Contains("/errors/500.html"))
        {
            // Можем проверять абсолютный путь конечной ссылки
            project.SendErrorToLog("Сервер вернул 500 - Сервер приболел, сделаем паузу", true);
            Thread.Sleep(2000);
        }
        else if (Responce.Address.Host.Contains("zennostore"))
        {
            // Можем проверять адрес хоста на случай переадресации.
            throw new Exception("Сервер перекинул на хост zennostore");
        }
    }
}
// С Подробной информацией по статус кодам можно ознакомитсья по ссылке:
// https://docs.microsoft.com/en-us/dotnet/api/system.net.httpstatuscode?redirectedfrom=MSDN&view=net-5.0

///++++++++++++++++++++++++++++++++++++++++++
/// Настройки для запроса
///++++++++++++++++++++++++++++++++++++++++++


C#:
HttpRequest request = null;

request.Cookies = new CookieStorage();

request.UserAgent = Http.ChromeUserAgent(); // Создает UserAgent

/// UserAgents were updated in January 2019.
// ChromeUserAgent()
// FirefoxUserAgent()
// IEUserAgent()
// OperaUserAgent()
// OperaMiniUserAgent()

request.IgnoreProtocolErrors = true; // Блок catch не будет выходить по ошибке если 4xx или 5xx.
request.EnableEncodingContent = true;

request.KeepAlive = true;

request.AllowAutoRedirect = true;
request.MaximumAutomaticRedirections = 5;
request.ReconnectLimit = 3;
request.ReconnectDelay = 50;

request[HttpHeader.DNT] = "1";
request[HttpHeader.UpgradeInsecureRequests] = "1";

request["Host"] = String.Format("www.{0}", "zennolab.com");
request[HttpHeader.Accept] = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8";
request[HttpHeader.AcceptLanguage] = "en-US,en;q=0.5";
request.AcceptEncoding = "gzip, deflate, br";

///++++++++++++++++++++++++++++++++++++++++++
/// Работа с GET запросами:
///++++++++++++++++++++++++++++++++++++++++++


C#:
// Если не нужен ответ
request.Get("https://zennolab.com").None();


// Можем сделать запрос без возврата значения
request.Get("https://zennolab.com");


// Либо объявить var и работать с ним.
var httpResponse = request.Get("https://zennolab.com").ToString();

string html = httpResponse.ToString();
string headerToken = httpResponse["cf-request-id"];


// Скачиваем файл.
var resp = request.Get("http://google.com/file.zip");
resp.ToFile("C:\\myDownloadedFile.zip");

///++++++++++++++++++++++++++++++++++++++++++
/// Работа с POST запросами:
///++++++++++++++++++++++++++++++++++++++++++


C#:
// Если ответ не нужен
request.Post("https://zennolab.com").None();

// Запрос без возврата значения в переменную
request.Post("https://zennolab.com");

// Объявляем var и работаем с ним.
var httpResponse = request.Post("https://zennolab.com");
string html = httpResponse.ToString();

//++++++++++++++++++++++++++++++++++++++++++
// Отправка запроса с параметрами


C#:
var httpResponse = request.Post("https://zennolab.com", new StringContent("referrer=&queryString="));

// Либо объявить StringContent предварительно

var stringContent = new StringContent("referrer=&queryString=");
var httpResponse = request.Post("https://zennolab.com", stringContent);

//++++++++++++++++++++++++++++++++++++++++++
// Отправка мультипарт запроса


C#:
var multipartContent = new MultipartContent()
{
    {new StringContent("Harry Potter"), "login"},
    {new StringContent("Crucio"), "password"},
    {new FileContent(@"C:\hp.rar"), "file1", "hp.rar"}
};

var httpResponse = request.Post("https://zennolab.com", multipartContent);

//++++++++++++++++++++++++++++++++++++++++++
// Отправка JSON в запросе


C#:
var stringContent = new StringContent("{\"login\":\"[email protected]\",\"password\":\"admin123\"}");
var httpResponse = request.Post("https://zennolab.com", stringContent, "application/json");

//++++++++++++++++++++++++++++++++++++++++++
// RequestParams


C#:
var urlParams = new RequestParams
{
    { ["id"] = "zY6vR6hU8kG0wE7u" },
    { ["имя"] = "Игорь" },
    { ["jsonContent"] = "{\"login\":\"[email protected]\",\"password\":\"admin123\"}" }
}
var httpResponse = request.Post("https://zennolab.com", urlParams);

// Либо через объявление

var urlParams = new RequestParams();
urlParams["id"] = "zY6vR6hU8kG0wE7u";
urlParams["имя"] = "Игорь";
urlParams["jsonContent"] = "{\"login\":\"[email protected]\",\"password\":\"admin123\"}";

var httpResponse = request.Post("https://zennolab.com", urlParams);

///++++++++++++++++++++++++++++++++++++++++++
/// Работа с Cookie
///++++++++++++++++++++++++++++++++++++++++++


Для работы с куки необходимо объявить CookieStorage.

C#:
HttpRequest request = new HttpRequest();
request.Cookies = new CookieStorage();
C#:
// Получение нужной куки

HttpRequest request = new HttpRequest();
request.Cookies = new CookieStorage();

string xf_session = null;

using (request)
{
    request.Get("https://zennolab.com");

    var cookies = request.Cookies.GetCookies("https://zennolab.com");
    foreach (Cookie cookie in cookies)
    {
        // Перебор всех кук в лог
        project.SendInfoToLog(String.Format("Name: {0} ::: Value: {1}", cookie.Name, cookie.Value), true);

        // Получаем в переменную куку xf_session
        if (cookie.Name == "xf_session") xf_session = cookie.Value;
    }
}

// Добавление новой или обновление существующей куки
// request.Cookies.Set(string name, string value, string domain, string path = "/");

request.Cookies.Set("pll_language", "en", "zennolab.com", "/");

//++++++++++++++++++++++++++++++++++++++++++
// Сохранение и загрузка кук


C#:
//++++++++++++++++++++++++++++++++++++++++++
// Сохранение в файл

HttpRequest request = new HttpRequest();

// Объявляем новый контейнер, который сохраним в файл.
request.Cookies = new CookieStorage();

// Сохранение CookieStorage в файл .jar
request.Cookies.SaveToFile("D:\\cookie.jar", true);
C#:
//++++++++++++++++++++++++++++++++++++++++++
// Загрузка из файла

HttpRequest request = new HttpRequest();

// Объявлять новый CookieStorage не нужно.
request.Cookies = CookieStorage.LoadFromFile("D:\\cookie.jar");
C#:
//++++++++++++++++++++++++++++++++++++++++++
// Сохранение в массив байт

HttpRequest request = new HttpRequest();
request.Cookies = new CookieStorage();

// Сохранение CookieStorage в массив байт - byte[]
var byteArray = request.Cookies.ToBytes();

// Преобразовываем массив байт в строку - string.
string base64 = Convert.ToBase64String(byteArray);
C#:
//++++++++++++++++++++++++++++++++++++++++++
// Загрузка из массива байт

string base64 = "";

HttpRequest request = new HttpRequest();

// Преобразование строки base64 в массив байт
byte[] decByte = Convert.FromBase64String(base64);

// Загрузка CookieStorage массива байт - byte[].
request.Cookies = CookieStorage.FromBytes(decByte);

//++++++++++++++++++++++++++++++++++++++++++
// Работа с Proxy
//++++++++++++++++++++++++++++++++++++++++++


Задавать проекту прокси можно разными способами, выбирайте удобный в вашем случае.

Библиотека поддерживает работу со следующими протоколами:
  • HTTP
  • Socks4
  • Socks4A
  • Socks5
C#:
// Вариант 1
request.Proxy = ProxyClient.Parse(ProxyType.HTTP, "ip:port:username:password");


// Вариант 2
request.Proxy = new HttpProxyClient("127.0.0.1", 8888, "username", "password");
request.Proxy = new Socks4ProxyClient("127.0.0.1", 8888, "username", "password");
request.Proxy = new Socks4aProxyClient("127.0.0.1", 8888, "username", "password");
request.Proxy = new Socks5ProxyClient("127.0.0.1", 8888, "username", "password");


// Вариант 3, в случае, когда авторизацию можно задать позже
request.Proxy = HttpProxyClient.Parse("127.0.0.1:8888");

request.Proxy.Username = "username";
request.Proxy.Password = "password";
 
Тема статьи
Нестандартные хаки
Номер конкурса статей
Четырнадцатый конкурс статей

Вложения

Для запуска проектов требуется программа ZennoPoster или ZennoDroid.
Это основное приложение, предназначенное для выполнения автоматизированных шаблонов действий (ботов).
Подробнее...

Для того чтобы запустить шаблон, откройте нужную программу. Нажмите кнопку «Добавить», и выберите файл проекта, который хотите запустить.
Подробнее о том, где и как выполняется проект.

Последнее редактирование:

BAZAg

Client
Регистрация
08.11.2015
Сообщения
1 788
Благодарностей
2 453
Баллы
113
Спасибо за материал!
Статью ещё не прочитал, но оформление понравилось.
Да и давно мечтаю разобраться с этой библиотечкой!
 
  • Спасибо
Реакции: radv и RoyalBank
Регистрация
23.03.2015
Сообщения
1 218
Благодарностей
751
Баллы
113
Спасибо, но я до такого ещё не дорос. Нужно как-то победить лень, разобраться со своими завалами и начинать учиться.
Добавил статью в закладки для подробного разбора
 
  • Спасибо
Реакции: fyodor44 и RoyalBank

maloibtc

Client
Регистрация
08.04.2016
Сообщения
365
Благодарностей
91
Баллы
28
То есть чтоб участвовать в конкурсе будет достаточно скопировать описание библиотеки и примерами из гитхаба?))
Не знал.
 

radv

Client
Регистрация
11.05.2015
Сообщения
3 788
Благодарностей
1 952
Баллы
113
Полезная штука. :ay: Все собирался перейти с xNet на leaf.xnet да лень самому было копаться и искать информацию :az:
 
  • Спасибо
Реакции: RoyalBank

RoyalBank

Client
Регистрация
07.09.2015
Сообщения
557
Благодарностей
550
Баллы
93
То есть чтоб участвовать в конкурсе будет достаточно скопировать описание библиотеки и примерами из гитхаба?))
Стоит отметить хорошее описание на самом гитхабе, но этого описания мало, чтобы быстро и просто внедрить библиотеку в реальный проект, а после этого не тратить время на отладку, разбираясь почему сыпятся те или иные ошибки.

В данной статье я постарался обобщить свой опыт работы с библиотекой сделав акцент на реальных потребностях, которые могут возникнуть при написании шаблона. И приведя в пример, те констукты, к которым я пришел за время использования библиотеки.
 

radv

Client
Регистрация
11.05.2015
Сообщения
3 788
Благодарностей
1 952
Баллы
113
Стоит отметить хорошее описание на самом гитхабе, но этого описания мало, чтобы быстро и просто внедрить библиотеку в реальный проект, а после этого не тратить время на отладку, разбираясь почему сыпятся те или иные ошибки.

В данной статье я постарался обобщить свой опыт работы с библиотекой сделав акцент на реальных потребностях, которые могут возникнуть при написании шаблона. И приведя в пример, те констукты, к которым я пришел за время использования библиотеки.
Вот это самое ценное и есть. А сухого описания на гитхабе не всегда хватает.
 
  • Спасибо
Реакции: Alexmd и RoyalBank

Dr.Pipetka

Client
Регистрация
12.12.2017
Сообщения
1 307
Благодарностей
865
Баллы
113
Ну уже дополни сохранение\загрузку кук:-)
 
  • Спасибо
Реакции: dsertr21 и RoyalBank

alex888

Client
Регистрация
13.10.2013
Сообщения
105
Благодарностей
39
Баллы
28
хорошо оформлено, все разложено по полочкам, лично для меня полезная информация, обязательно попробую воспользоваться данной библиотекой, проголосовал за статью, спасибо
 
  • Спасибо
Реакции: RoyalBank

RoyalBank

Client
Регистрация
07.09.2015
Сообщения
557
Благодарностей
550
Баллы
93
  • Спасибо
Реакции: Nike59 и Dr.Pipetka

Meteorburn

Client
Регистрация
23.05.2016
Сообщения
1 472
Благодарностей
575
Баллы
113
У разработчика Leaf есть платная версия стоимостью 100$ с обходом Cloudflare и SSL Fingerprint и поддержкой recaptcha и hcaptcha.
За статью спасибо, но ожидал большего, как уже намекнули выше про описание с GitHub)
 

RoyalBank

Client
Регистрация
07.09.2015
Сообщения
557
Благодарностей
550
Баллы
93
За статью спасибо, но ожидал большего, как уже намекнули выше про описание с GitHub)
Спасибо за обратную связь, в статье ориентировался на тех, кто до этого никогда не работал с этой библиотекой.
 

Akhmet

Client
Регистрация
05.04.2020
Сообщения
24
Благодарностей
10
Баллы
3
Супер, как раз на днях искал, и вот вуаля!
 
Последнее редактирование:
  • Спасибо
Реакции: RoyalBank

Akhmet

Client
Регистрация
05.04.2020
Сообщения
24
Благодарностей
10
Баллы
3
Стоит ли изучать xNet библ или начать сразу с этого?
 

RoyalBank

Client
Регистрация
07.09.2015
Сообщения
557
Благодарностей
550
Баллы
93
  • Спасибо
Реакции: dsertr21 и Akhmet

p-sergei

Client
Регистрация
20.12.2016
Сообщения
542
Благодарностей
262
Баллы
63
Статью не читал, но одобряю :D. Жарю на Xnet, всё хочу уйти с нее на Leaf.xNet, да никак всё не могу собраться с силами да разобраться в чем там отличия. А тут опа и мануальчик вводный. На досуге ознакомлюсь. Заранее спасибо.
 
  • Спасибо
Реакции: RoyalBank

Porosenok

Client
Регистрация
26.09.2010
Сообщения
1 280
Благодарностей
96
Баллы
48
А как отправить контент типа
multipart/form-data; boundary=----WebKitFormBoundary12312312
чтобы там было что-то типа
----WebKitFormBoundary12312312
{"login": "porosenok"}

----WebKitFormBoundary12312312
{"pass": "123456"}

и тд

на гите нашел рекомендацию смотреть .Raw () но что-то посмотрел и ничего не понял
 

RoyalBank

Client
Регистрация
07.09.2015
Сообщения
557
Благодарностей
550
Баллы
93
multipart/form-data; boundary=----WebKitFormBoundary12312312
Если я правильно понял, то WebKitFormBoundary12312312 - это заголовок ContentType, его можно добавить двумя способами, как постоянный для всех запросов - вариант 1, или как временный, только для текущего запроса - вариант 2.


C#:
HttpRequest request = new HttpRequest();

// Вариант 1 - Постоянный заголовок
// request[HttpHeader.ContentType] = "multipart/form-data; boundary=----WebKitFormBoundary12312312";

// Вариант 2 - Временный заголовок, только для текущего запроса.
request.AddHeader("Content-Type", "multipart/form-data; boundary=----WebKitFormBoundary12312312");


var multipartContent = new MultipartContent()
{
    {new StringContent("login"), "porosenok"},
    {new StringContent("pass"), "123456"}
};

var httpResponse = request.Post("https://zennolab.com", multipartContent);
 

Porosenok

Client
Регистрация
26.09.2010
Сообщения
1 280
Благодарностей
96
Баллы
48
Если я правильно понял, то WebKitFormBoundary12312312 - это заголовок ContentType, его можно добавить двумя способами, как постоянный для всех запросов - вариант 1, или как временный, только для текущего запроса - вариант 2.


C#:
HttpRequest request = new HttpRequest();

// Вариант 1 - Постоянный заголовок
// request[HttpHeader.ContentType] = "multipart/form-data; boundary=----WebKitFormBoundary12312312";

// Вариант 2 - Временный заголовок, только для текущего запроса.
request.AddHeader("Content-Type", "multipart/form-data; boundary=----WebKitFormBoundary12312312");


var multipartContent = new MultipartContent()
{
    {new StringContent("login"), "porosenok"},
    {new StringContent("pass"), "123456"}
};

var httpResponse = request.Post("https://zennolab.com", multipartContent);
Спасибо, но увы не срабатывает запрос таким образом. В Фиддлере смотрю там в разделе webforms оно должно быть справа название, слева значение, а там все слева кашей идет
 

RoyalBank

Client
Регистрация
07.09.2015
Сообщения
557
Благодарностей
550
Баллы
93
Спасибо, но увы не срабатывает запрос таким образом. В Фиддлере смотрю там в разделе webforms оно должно быть справа название, слева значение, а там все слева кашей идет
Код выше, как пример. Чтобы запрос работал необходимо смотреть, всю цепочку запросов в фиддлере и переносить все составляющие от кук до заголовков в код.
 

Porosenok

Client
Регистрация
26.09.2010
Сообщения
1 280
Благодарностей
96
Баллы
48
Код выше, как пример. Чтобы запрос работал необходимо смотреть, всю цепочку запросов в фиддлере и переносить все составляющие от кук до заголовков в код.
В том то и дело у меня есть один этот запрос в postman на ура выполняется в таком виде в каком есть. Все куки там уже включены (я их и в код сишарпа добавил естественно). Увы, перенести из-за кривизны этой не получается ((

Еще WebKitFormBoundary слово убралось и свое значение рандом поставилось. Попробовать content-type таким образом задать, но вообще код не стартует:

C#:
var httpResponse = request.Post("https://site.ru", multipartContent, "multipart/form-data; boundary=----WebKitFormBoundary123123123");

ps и сервер мне в ответ отдает то что не хватает некоторых данных, то есть значит то как эти данные передались неверно, сервер их не видит
 

RoyalBank

Client
Регистрация
07.09.2015
Сообщения
557
Благодарностей
550
Баллы
93
В том то и дело у меня есть один этот запрос в postman на ура выполняется в таком виде в каком есть
Как вариант составить такую же строку, как при отправке через StringBuilder и отправлять её.


C#:
StringBuilder sb = new StringBuilder();

sb.Append("----WebKitFormBoundary12312312").Append("\r\n");
sb.Append("Content-Disposition: form-data; name=\"login\"").Append("\r\n");
sb.Append("login").Append("\r\n");
sb.Append("----WebKitFormBoundary12312312").Append("\r\n");
sb.Append("Content-Disposition: form-data; name=\"password\"").Append("\r\n");
sb.Append("password").Append("\r\n");

var content = sb.ToString();


var httpResponse = request.Post("https://site.ru", content, "multipart/form-data; boundary=----WebKitFormBoundary123123123");
 
  • Спасибо
Реакции: semafor
Регистрация
26.05.2020
Сообщения
495
Благодарностей
172
Баллы
43
В начале статьи стоило бы написать, что такое ентот лификснет и чем он может быть полезен и/или лучше чего-то там более известного... Совсем для ламеров, вроде меня...
 

Asmus003

Client
Регистрация
25.03.2018
Сообщения
259
Благодарностей
66
Баллы
28
А чем работа с помощью этой библиотеки отличается от работы на кубиках? в чем ее преимущество (кроме того, что можно впихнуть код в большущий код 1 кубика С#)?
 

BAZAg

Client
Регистрация
08.11.2015
Сообщения
1 788
Благодарностей
2 453
Баллы
113
В начале статьи стоило бы написать, что такое ентот лификснет и чем он может быть полезен и/или лучше чего-то там более известного... Совсем для ламеров, вроде меня...
Библиотека нужна тогда, когда с помощью стандартных средств не получается решить какую-то проблему, например отправляете запрос, а Зенно искажает параметры - из-за чего запрос не доходит. Если же у Вас получается реализовать стандартными методами - то стоит отложить чтение статьи до момента, когда эта информация станет для Вас актуальной.

А чем работа с помощью этой библиотеки отличается от работы на кубиках? в чем ее преимущество (кроме того, что можно впихнуть код в большущий код 1 кубика С#)?
Отличается тем, что бывает что стандартными средствами Зенно не получается выполнить определенные задачи, а библиотека позволяет более гибко работать как с самими соединениями, так и с формированием параметров. Но, как уже писал выше - не стоит заморачиваться до тех пор, пока у Вас в реальности нет проблемы при работе со стандартными методами.
 

Asmus003

Client
Регистрация
25.03.2018
Сообщения
259
Благодарностей
66
Баллы
28
Библиотека нужна тогда, когда с помощью стандартных средств не получается решить какую-то проблему, например отправляете запрос, а Зенно искажает параметры - из-за чего запрос не доходит. Если же у Вас получается реализовать стандартными методами - то стоит отложить чтение статьи до момента, когда эта информация станет для Вас актуальной.


Отличается тем, что бывает что стандартными средствами Зенно не получается выполнить определенные задачи, а библиотека позволяет более гибко работать как с самими соединениями, так и с формированием параметров. Но, как уже писал выше - не стоит заморачиваться до тех пор, пока у Вас в реальности нет проблемы при работе со стандартными методами.
Просто сейчас добавили кубики с Put, Delete и т.д. а с параметрами мне не доводилось мучаться)
 

BAZAg

Client
Регистрация
08.11.2015
Сообщения
1 788
Благодарностей
2 453
Баллы
113
Просто сейчас добавили кубики с Put, Delete и т.д. а с параметрами мне не доводилось мучаться)
Мне уже приходилось встречать ситуации, когда нужно отправить запрос в определенном виде, формировал запрос в этом виде, и в результате оказывалось что Зенно искажала параметры. И никак невозможно было понять что же именно не так. А после использования сборки параметров от данной библиотечки всё заработало.

Также была как-то проблема с запросами - запросы открывали соединения для каждого запроса - что быстро забивало количество открытых соединений и bing выдавал 429 - и это также решалось методом принудительного удержания открытых соединений этой библиотеки.

Такая же шляпа была когда покупались прокси, которые продаются с ограничением количества потоков - при удержании открытым соединения при принудительном закрытии соединений оказалось что нагрузка на прокси уменьшилась в 10 раз (а это значит что можно было в 10 раз больше потоков запускать).

Так что тут дело такое, что пока проблемы нет - то можно не заморачиваться. А когда нужно решить проблему, и стандартным способом не получается - приходится уметь находить обходные пути.
 
Последнее редактирование:

RoyalBank

Client
Регистрация
07.09.2015
Сообщения
557
Благодарностей
550
Баллы
93
А чем работа с помощью этой библиотеки отличается от работы на кубиках? в чем ее преимущество
Я специально сделал статью таким образом, чтобы не сравнивать данную библиотеку с имеющимся функционалом ZP, кубики или код. Т.к. это конкурс статей, цель которого расширять сообщество, что в конечном итоге призвано улучшить продукт. А то, как писать шаблон, кубиками или в коде, исключительно вкусовщина при базовых запросах к функционалу, не выходя за рамки возможностей.

В целом, выше описали моменты, которые позволяет закрыть библиотека. Так же стороннее решение, позволит избежать проблем с обновлением функционала из коробки и его работоспособностью в предыдущих версиях.
Позволяет экономить код в объеме, т.к. не нужно прописывать все по умолчанию. Позволяет сделать грамотную отладку запросов с кодами ответов страницы и другими критериями, не распаршивая регулярками ответ запроса. Ну и скачать файл, можно в две строки.
 
  • Спасибо
Реакции: Asmus003 и Meteorburn

Juniorcpa

Client
Регистрация
27.05.2014
Сообщения
2 031
Благодарностей
1 286
Баллы
113
Прикольно, не знал, что на самом деле всё очень даже не сложно тут.
 
  • Спасибо
Реакции: RoyalBank

Nike59

Client
Регистрация
05.08.2011
Сообщения
122
Благодарностей
122
Баллы
43
У меня были проекты на xNet и я был вполне доволен этой библиотекой. В статье прекрасно представлены возможности более крутой модификации Leaf.xNet. Спасибо за ценную информацию и примеры использования. Буду пробовать!
 
  • Спасибо
Реакции: RoyalBank

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