Вытаскиваем данные из вкладки "Трафик" (плагин + код c#)

volody00

Client
Регистрация
06.09.2016
Сообщения
918
Благодарностей
953
Баллы
93
Введение

Начну с того, что такое трафик, как с ним работать и решение какой проблемы предлагает мой плагин. Более подробно этой темы я уже касался тут, поэтому здесь пробежимся кратко.

Итак, когда мы переходим на какую-то страницу, браузер вместо нас отправляет запросы на сервер и получает ответы. Благодаря разработчикам Zennoposter все эти данные можно достать (урл запроса, заголовки запроса/ответа, тело запроса/ответа).
125202

Первым делом нам нужно включить монитор трафика. Его достаточно прописать один раз где-нибудь в начале шаблона.
C#:
instance.UseTrafficMonitoring = true;
Далее, когда нам нужно собрать запросы, то мы получаем массив всех этих данных и вытаскиваем именно то, что нам требуется. Пример для страницы https://zenno.club/discussion/
C#:
string headers = string.Empty, cookies = string.Empty, body = string.Empty;

//собираем все запросы из вкладки трафик
var trafficList = instance.ActiveTab.GetTraffic();

//проходимся по ним в цикле
foreach(var s in trafficList)
{
    //получаем урл
    string url = s.Url;
  
    //сравниваем урл
    if(url == "https://zenno.club/discussion/")
    {
        //дожидаемся прогрузки
        s.WaitResponse(10, 2);
      
        //достаем заголовки ответа
        headers = s.ResponseHeaders;
      
        //достаем куки
        cookies = s.ResponseCookies;
      
        //достаем тело
        if(s.ResponseBody != null) body = System.Text.Encoding.UTF8.GetString(s.ResponseBody);
      
    }
}

//выводим в лог
project.SendInfoToLog(headers);
project.SendInfoToLog(cookies);
project.SendInfoToLog(body);

/*
чтобы поместить в зенковские переменные
project.Variables["headers"].Value = headers;
project.Variables["cookies"].Value = cookies;
project.Variables["body"].Value = body;
*/
Но что, если мы хотим собрать данные с ещё одного запроса (на этой же странице), например, https://zenno.club/discussion/styles/class/fonts/icons/material-icons/css/materialdesignicons.min.css ? Вы можете подумать, что копипастим в новый кубик c#, поменяв урл, и всё будет гуд, но не тут-то было…
125203

Получаем пустоту. Дело в том, что, вызывая метод GetTraffic(), мы очищаем весь трафик. Когда мы создали новый кубик c# и "скопипастили" код, то он пытается найти уже новые запросы. И вот тут возникает проблема у тех, кто не знает c#, ибо методом тыка "натыкать" может быть не так просто.

У нас с вами есть пару вариантов. Первый – модифицировать первый кубик так, чтобы можно было собрать сразу несколько запросов. На форуме был найден такой сниппет, собирающий данные в таблицу

C#:
var traffic = instance.ActiveTab.GetTraffic();
var tt = project.Tables["trafficTable"];

tt.AddRow(new List<string>()
{
    "Method",
    "ResultCode",
    "Url",
    "ContentType",
    "RequestHeaders",
    "RequestCookies",
    "RequestBody",
    "ResponseHeaders",
    "ResponseCookies",
    "ResponseBody"
});

foreach(TrafficItem t in traffic)
{
    var row = new List<string>()
    {
        t.Method,
        t.ResultCode.ToString(),
        t.Url,
        t.ResponseContentType,
        t.RequestHeaders,
        t.RequestCookies,
        t.RequestBody,
        t.ResponseHeaders,
        t.ResponseCookies,
        t.ResponseBody == null ? "" : Encoding.UTF8.GetString(t.ResponseBody, 0, t.ResponseBody.Length)
    };
    
    tt.AddRow(row);
}
Второй – воспользоваться project.Context, дабы сохранить данные со "старого трафика". Давайте покажу, как это. В первом кубике нам надо будет в конце добавить одну строчку
C#:
string headers = string.Empty, cookies = string.Empty, body = string.Empty;

var trafficList = instance.ActiveTab.GetTraffic();

foreach(var s in trafficList)
{
    string url = s.Url;
  
    if(url == "https://zenno.club/discussion/")
    {
        s.WaitResponse(10, 2);
        headers = s.ResponseHeaders;
        cookies = s.ResponseCookies;
        if(s.ResponseBody != null) body = System.Text.Encoding.UTF8.GetString(s.ResponseBody);
      
    }
}


project.SendInfoToLog(headers);
project.SendInfoToLog(cookies);
project.SendInfoToLog(body);

//сохраняем контекст в "переменную" с именем network
project.Context["network"] = trafficList;
А во втором кубике собирать данные уже не с помощью метода GetTraffic(), а именно из project.Context.
C#:
string headers = string.Empty, cookies = string.Empty, body = string.Empty;

//подгружаем данные из переменной "network"
var trafficList = project.Context["network"];

foreach(var s in trafficList)
{
    string url = s.Url;
  
    if(url == "https://zenno.club/discussion/styles/class/fonts/icons/material-icons/css/materialdesignicons.min.css")
    {
        s.WaitResponse(10, 2);
        headers = s.ResponseHeaders;
        cookies = s.ResponseCookies;
        if(s.ResponseBody != null) body = System.Text.Encoding.UTF8.GetString(s.ResponseBody);
      
    }
}


project.SendInfoToLog(headers);
project.SendInfoToLog(cookies);
project.SendInfoToLog(body);
В принципе, проблему это решает. Но чем мне не нравится project.Context, так это тем, что при его использовании вы не сможете пользоваться пошаговой отладкой в c# (по крайне мере в PM, может быть в VS ситуация получше).

Оба варианта имеют право на жизнь, но я решил предложить вам ещё более удобную штуку.

Плагин

Суть его очень простая. Он соберет все запросы и все данные в формате json, ну а далее вы можете вытаскивать что душе угодно с помощью кубика "парсить json".

Итак, первым делом добавляем плагин к себе в проект. Идём в настройки->плагины->добавить плагины и выбираем плагин
125204

Теперь создаем кубик c# и включаем мониторинг трафика

instance.UseTrafficMonitoring = true;

Переходим на нужную страницу, используем плагин и распаршиваем полученный json.
Реализация на c#

На c# есть вариант как с project.Context, так и с сохранением в json. Первым делом надо будет вам добавить библиотеку Newtonsoft.json. Для этого заходим в ссылки из gac -> добавить -> C:\Program Files\ZennoLab\RU\ZennoPoster Pro V7\7.7.ваша_версия\Progs и там находим Newtonsoft.json

125205

Важно:
  • Не забыть прописать перед вызовом класса instance.UseTrafficMonitoring = true;
  • Для использования в других кубиках следует переносить через project.Context. P.S. При отладке project.Context ведет себя капризно и может выдавать ошибку "Выполнение действия CSharp OwnCode: получаем тело уже другого запроса из другого кубика. Возникло непредвиденное исключение при выполнении привязки динамической операции". Так что иметь в виду и выполнять без остановки.


public bool GetTraffic(string url = "", string searchType = "contains", bool searchAllUrl = true, int maxTimeout=30, bool stopMonitoring = true, int wait=1, bool waitAllurls = false) – мониторит трафик на протяжении указанного времени.

Задача метода – записать весь трафик в список trafficList.

Также мы можем задать список урл для проверки, есть ли они в трафике и узнать это исходя из того, что вернёт метод.

Данный метод всегда вызываем первым, т.к. остальные работают исключительно с trafficList, а не с самим трафиком.

Метод перезаписывает список trafficList, т.к. происходит вызов зенковского GetTraffic!

Параметры:

  • url [""] – список урл, которые ищем. Если пустой, то вернём true, если в трафике будет найден хотя бы 1 запрос. Можно передать 1 урл. Можно передать несколько урл через точку с запятой.
  • searchType ["contains"] – тип поиска. "contains" [по умолч], "regex", "startsWith", "endsWith", "exactMatch"
  • searchAllUrl [true] – надо ли нам отыскать все урл (если задано несколько). Если да, то вернёт true только в том случае, если будут найдены все урл. Если нет, то вернёт true в том случае, если будет найден хотя бы один запрос.
  • maxTimeOut [30] – сколько секунд максимум мониторим трафик. Если заданы урл, мониторинг прекратится после того, как они будут найдены.
  • stopMonitoring [true] – прекратить ли мониторинг трафика, если на протяжении 3-4 секунд новые запросы в трафике больше не появляются. Всегда false, если задан список урл, но при этом заканчивает работу, если все урл найдены.
  • wait [1] - Сколько "кругов" (1 круг = 1 секунда) ждать появления новых запросов, прежде чем прервем метод. Чем меньше ставим, тем быстрее отработает метод, но повышается вероятность упустить какие-то запросы, которые могут появиться чуть позже "основной" пачки.
  • waitAllurls - Ждать прогрузки всех урл, а не только тех, которые указали мы [false]
Возвращаемое значение:
  • true или false в зависимости от ситуации, описанной выше
  • По окончании работы ВСЕ запросы из монитора трафика сохраняются в список trafficList
==

public string GetBody(string url, string searchType = "contains") – ищем урл в списке TrafficList и получаем тело запроса. Можно задать только 1 урл.

Параметры:
  • url – искомый урл
  • searchType ["contains"] – тип поиска. contains" [по умолч], "regex", "startsWith", "endsWith", "exactMatch"
Возвращаемое значение:
  • "" – если урл не найден
  • тело запроса в string
==

public void Clear() – принудительная очистка списка TrafficList

public string GetJsonFromTraffic(string url = "", string searchType = "contains", bool searchAllUrl = true, int maxTimeout=30, bool stopMonitoring = true, int wait=1, bool waitAllurls = false) – сохраняем весь трафик в строку json. Параметры аналогичны GetTraffic(). Если запросы не найдены, вернет "".

public NetworkObjectList GetObjectFromJson(string json) – из json помещаем данные обратно в объект. Т.е. этот метод используется после GetJsonFromTraffic().

Примеры использования методов смотрите в прикрепленном шаблоне.

В видео я покажу вам, как вы можете расширить данную библиотеку, поработав с общим кодом.

 

Вложения

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

seodamage

Client
Регистрация
08.09.2014
Сообщения
224
Благодарностей
67
Баллы
28
спасибо, для одной тапалки пригодиться. она там на юнити написана и из запросов как раз можно понять когда сессия устарела.
 

russya

Client
Регистрация
08.07.2014
Сообщения
743
Благодарностей
78
Баллы
28
На зеннодроид нельзя так отлавливать трафик?
 

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