Автоматизация и боты

 Помощь      Поиск      Пользователи

 

Сайт Кибор     Программируемый кликер Кибор     Видео обучение     Заказать бот

 Страниц (1): [1]   

> Описание: Парсинг JSON формата. Получение значений элементов JSON
Kibor
Отправлено: 03 Июня, 2020 - 21:22:07
Post Id



Администратор
Эксперт


Покинул форум
Сообщений всего: 6363
Дата рег-ции: Март 2013  
Откуда: Одесса
Репутация: 250




Реализован парсер JSON

Дополнительные функции для работы с JSON Версия 5.64 Работа с JSON форматом

Парсер JSON формата осуществляется функцией
parserjson(Rez_Json, исходник);
где
Rez_Json - Символьное имя объекта
исходник - string, в котором записан Json формат

Затем по символьному имени можно обращаться к структуре Json:
 Цитата:
parserjson(Rez_Json, исходник);
Rez_Json.products[1].options.15[2] // доступ к элементу JSON


Если элемента не существует, вернется ERROR_SEARCH_JSON
В дальнейшем появятся функции вычисления размеров массивов и тд.

Пример как узнать значение с частично неизвестной частью ключа.

Можно одновременно загружать и создавать несколько Json объектов:
 Цитата:
parserjson(Rez_Json, исходник);
parserjson(Rez_Json_2, исходник1);



Пример
CODE:
/*
{
"clientKey":"dce6bcbb1a728ea8d563de6d169a2057",
"task":
{
"type":"ImageToTextTask",
"body":"BASE64_BODY_HERE!",
"phrase":false,
"case":false,
"numeric":0,
"math":false,
"minLength":0,
"maxLength":0
}
}
*/

string Json="{^"clientKey^":^"" + "dce6bcbb1a728ea8d563de6d169a2057^"," +
"^"task^":" +
"{^"type^":^"ImageToTextTask^"," +
"^"body^":^"BASE64_BODY_HERE!^"," +
"^"phrase^":false," +
"^"case^":false," +
"^"numeric^":0," +
"^"math^":false," +
"^"minLength^":0," +
"^"maxLength^":0}}";

messagebox (Json);

parserjson(Rez_Json, Json);//Создаем объект JSON с символьным именем Rez_Json и Парсим запись JSON с Json

messagebox (Rez_Json.task.case);//Выводим значение объекта JSON



Пример:
CODE:
string исходник="";
string исходник1="";
string Tt;

if (fopen ("C:\json.txt", "r")!=0)//открываем файл для чтения "r"
{
while (freadline(Tt))исходник=исходник+Tt;
fclose();
}


if (fopen ("C:\json - 1.txt", "r")!=0)//открываем файл для чтения "r"
{
while (freadline(Tt))исходник1=исходник1+Tt;
fclose();
}

messagebox (исходник);
messagebox (исходник1);

parserjson(Rez_Json, исходник);
parserjson(Rez_Json_2, исходник1);

//Объект Rez_Json
int n=0;
loop()
{
Tt=Rez_Json.products[1].options.15[n];
if (Tt=="ERROR_SEARCH_JSON")break;//Перебор всего массива до ошибки 47,48, 25, 79, 95
messagebox(Tt);
n++;
}

//Объект Rez_Json_2
messagebox(Rez_Json_2.data[0].attributes[1].value);//2015
messagebox(Rez_Json_2.data[0].images[0].url);//https://www.olx.ua/advert-picture-1.jpg


Соответственно файлы
json.txt
CODE:
{
"user_id" : 10,
"session_id" : "2c2l3h4ii271aojentejtdcmh3",
"products":
[
{
"product_id" : 15,
"options" :
{
"15" : [45, 47],
"18" : 52
},
"quantity" : 1,
"price" : 1500
},
{
"product_id" : 16,
"options" :
{
"15" : [47,48, 25, 79, 95],
"18" : 51
},
"quantity" : 2,
"price" : 1000
}
]
}


json - 1.txt
CODE:
{
"data": [
{
"id": 123,
"status": "active",
"url": "https://www.olx.ua/oferta/url.html",
"created_at": "2018-02-02 09:35:16",
"activated_at": "2018-02-02 09:32:52",
"valid_to": "2018-03-04 09:32:52",
"title": "This is title",
"description": "This is description",
"category_id": 123,
"advertiser_type": "private",
"external_id": 12345,
"external_url": "http://myshop.com/advert/123",
"contact": {
"name": "John",
"phone": 123123123,
"location": {
"city_id": 1,
"district_id": null,
"latitude": 53.123,
"longitude": 17.123
}
},
"images": [
{
"url": "https://www.olx.ua/advert-picture-1.jpg"
},
{
"url": "https://www.olx.ua/advert-picture-2.jpg"
}
],
"price": {
"value": 123,
"currency": "PLN",
"negotiable": false,
"trade": false
},
"salary": null,
"attributes": [
{
"code": "model",
"value": "cts",
"values": null
},
{
"code": "year",
"value": 2015,
"values": null
}
],
"courier": null
}
]
}



Вложенные массивы


Перебор всех массивов Rez_Json.members[?].powers[?] в Json
Файл
 Цитата:
{
"squadName": "Super hero squad",
"homeTown": "Metro City",
"formed": 2016,
"secretBase": "Super tower",
"active": true,
"members": [
{
"name": "Molecule Man",
"age": 29,
"secretIdentity": "Dan Jukes",
"powers": [
"Radiation resistance",
"Turning tiny",
"Radiation blast"

]
},
{
"name": "Madame Uppercut",
"age": 39,
"secretIdentity": "Jane Wilson",
"powers": [
"Million tonne punch",
"Damage resistance",
"Superhuman reflexes"

]
},
{
"name": "Eternal Flame",
"age": 1000000,
"secretIdentity": "Unknown",
"powers": [
"Immortality",
"Heat Immunity",
"Inferno",
"Teleportation",
"Interdimensional travel"

]
}
]
}



Скрипт перебора

CODE:
string исходник="";
string Tt;

if (fopen ("C:\json.txt", "r")!=0)//открываем файл для чтения "r"
{
while (freadline(Tt))исходник=исходник+Tt;
fclose();
}



messagebox (исходник);

parserjson(Rez_Json, исходник);

//Объект Rez_Json
int n=0;
int n1=0;
loop()
{
Tt=Rez_Json.members[n].powers[n1];//Перебор всех массивов Rez_Json.members[?].powers[?] в Json
if (Tt=="ERROR_SEARCH_JSON")
{
if (n1==0) break;
n++;
n1=0;
}
else
{
messagebox(Tt);
n1++;
}
}



Узнаем age объекта у которого powers "Damage resistance"

CODE:
string исходник="";
string Tt;

if (fopen ("C:\json.txt", "r")!=0)//открываем файл для чтения "r"
{
while (freadline(Tt))исходник=исходник+Tt;
fclose();
}



messagebox (исходник);

parserjson(Rez_Json, исходник);

//Объект Rez_Json
int n=0;
int n1=0;
loop()
{
Tt=Rez_Json.members[n].powers[n1];//Перебор всех массивов Rez_Json.members[?].powers[?] в Json
if (Tt=="ERROR_SEARCH_JSON")
{
if (n1==0) break;
n++;
n1=0;
}
else
{
//messagebox(Tt);
if (Tt=="Damage resistance")
{
messagebox(Rez_Json.members[n].age);
break;
}
n1++;
}
}

(Добавление)
Пример

products[1].options.15[0] = 47


 Цитата:
{
"user_id" : 10,
"session_id" : "2c2l3h4ii271aojentejtdcmh3",
"products":
[

{
"product_id" : 15,
"options" :
{
"15" : [45, 47],
"18" : 52
},
"quantity" : 1,
"price" : 1500
},

{
"product_id" : 16,
"options" :
{
"15" : [47,48],
"18" : 51
},
"quantity" : 2,
"price" : 1000
}

]
}
 
 Top
Kibor
Отправлено: 04 Июня, 2020 - 03:31:07
Post Id



Администратор
Эксперт


Покинул форум
Сообщений всего: 6363
Дата рег-ции: Март 2013  
Откуда: Одесса
Репутация: 250




Узнать все name и value массива stats

 Цитата:
{
"playerstats": {
"steamID": "76561198050187807",
"gameName": "ValveTestApp260",
"stats": [
{
"name": "total_kills",
"value": 35179
},
{
"name": "total_deaths",
"value": 30241
},
{
"name": "total_time_played",
"value": 2444377
}
]
}
}




Скрипт
CODE:
string Json="{"+
"^"playerstats^": {"+
"^"steamID^": ^"76561198050187807^","+
"^"gameName^": ^"ValveTestApp260^","+
"^"stats^": ["+
"{"+
"^"name^": ^"total_kills^","+
"^"value^": 35179"+
"},"+
"{"+
"^"name^": ^"total_deaths^","+
"^"value^": 30241"+
"},"+
"{"+
"^"name^": ^"total_time_played^","+
"^"value^": 2444377"+
"}"+
"]"+
"}"+
"}";

messagebox (Json);

parserjson(Rez_Json, Json);

int n=0;
while (Rez_Json.playerstats.stats[n].name!="ERROR_SEARCH_JSON")
{
messagebox (Rez_Json.playerstats.stats[n].name+" = "+Rez_Json.playerstats.stats[n].value);
n++;
}



Или с файла

CODE:
string исходник="";
string Tt;

if (fopen ("C:\json.txt", "r")!=0)//открываем файл для чтения "r"
{
while (freadline(Tt))исходник=исходник+Tt;
fclose();
}



parserjson(Rez_Json, исходник);

int n=0;
while (Rez_Json.playerstats.stats[n].name!="ERROR_SEARCH_JSON")
{
messagebox (Rez_Json.playerstats.stats[n].name+" = "+Rez_Json.playerstats.stats[n].value);
n++;
}
 
 Top
Kibor
Отправлено: 04 Июня, 2020 - 05:17:01
Post Id



Администратор
Эксперт


Покинул форум
Сообщений всего: 6363
Дата рег-ции: Март 2013  
Откуда: Одесса
Репутация: 250




Пример использования парсера для работы с сервисом anti-captcha.com для решения капчи.
Ключ dce6bcbb1a728ea8d563de6d169a2057 указан для примера.

CODE:

char BYTE[100000];//Массив байт для загрузки файла с капчей JPG. Потом его используем для JSON запроса

//Загружаем файл с капчей JPG и сразу форматируем его в base64
//первой выполнится функция read_file, вернет размер его и в #file[0] будет уже указатель на массив байт файла
//Затем выполнится функция base64code
string file64=base64code (#BYTE[0], read_file("C:\tab.jpg"));//Перед этим скриним часть экрана с капчей и сохраняем ее в C:\tab.jpg функцией savescreen

string json;//Строка для JSON запроса


//Формируем JSON запрос согласно документации anti-captcha.com
/*
{
"clientKey":"dce6bcbb1a728ea8d563de6d169a2057",
"task":
{
"type":"ImageToTextTask",
"body":"BASE64_BODY_HERE!",
"phrase":false,
"case":false,
"numeric":0,
"math":false,
"minLength":0,
"maxLength":0
}
}
*/
json="{^"clientKey^":^"dce6bcbb1a728ea8d563de6d169a2057^"," +
"^"task^":{^"type^":^"ImageToTextTask^"" +
",^"body^":^""+file64+"^",^"phrase^"" +
":false,^"case^":false,^"numeric^":0,^"math^"" +
":false,^"minLength^":0,^"maxLength^":0}}";

int aW=size(json);//Узнаем размер JSON запроса


strcpy(#BYTE[0], json);//Записываем JSON запрос в массив байт

messagebox(json);

string Header="Content-Type: application/x-www-form-urlencoded";//Формируем какой то заголовок

char REZ[100000];//Массив для приема ответа

sendgetweb(#REZ[0], "My bot", "POST", "https:/^/api.anti-captcha.com", "createTask", Header, #BYTE[0], aW);//Отправляем на anti-captcha.com и получаем ответ

//messagebox (format(#REZ[0]));

//Ответ такого формата
/*
{
"errorId":0,
"taskId":7654321
}
*/
parserjson(Rez_Json, format(#REZ[0]));//Парсим ответ




if (Rez_Json.errorId=="0")//Если нет ошибки
{
string id=Rez_Json.taskId;//Сохраняем полученный ID


//messagebox (id);

pause(3000);//Пауза

loop(50)
{
pause(2000);//Пауза в цикле между запросами решения

//Формируем запрос на ответ о решение капчи куда записываем наш clientKey и полученный taskId
/*
{
"clientKey":"dce6bcbb1a728ea8d563de6d169a2057",
"taskId": 7654321
}
*/
json="{^"clientKey^":^"dce6bcbb1a728ea8d563de6d169a2057^",^"taskId^": "+id+"}";
aW=size(json);//Узнаем размер JSON запроса
strcpy(#BYTE[0], json);//Записываем JSON запрос в массив байт

messagebox(json);

sendgetweb(#REZ[0], "My bot", "POST", "https:/^/api.anti-captcha.com", "getTaskResult", Header, #BYTE[0], aW);//Отправляем на anti-captcha.com и получаем ответ

//messagebox (format(#REZ[0]));


//Ответ такого формата
/*
{
"errorId":0,
"status":"ready",
"solution":
{
"text":"deditur",
"url":"http:\/\/61.39.233.233\/1\/147220556452507.jpg"
},
"cost":"0.000700",
"ip":"46.98.54.221",
"createTime":1472205564,
"endTime":1472205570,
"solveCount":"0"
}
*/
parserjson(Rez_Json, format(#REZ[0]));//Парсим ответ


if (Rez_Json.errorId!="0")//Если есть ошибка
{
messagebox("errorId "+Rez_Json.errorId);
break;//Выходим из цикла
}
if (Rez_Json.status=="ready")//Если капча решена
{
messagebox (Rez_Json.solution.text);//Выводим решение
messagebox (Rez_Json.solution.url);
break;//Выходим из цикла
}
}
}
else
{
messagebox (Rez_Json.errorCode);//Если не верный clientKey
}




function read_file(string pyt)
{
int size_file=0;
if (fopen (pyt, "rb")!=0)
{
size_file=freadb(#BYTE[0], 10000);
fclose();
}
return size_file;
}
 
 Top
Kibor
Отправлено: 24 Июня, 2020 - 19:41:52
Post Id



Администратор
Эксперт


Покинул форум
Сообщений всего: 6363
Дата рег-ции: Март 2013  
Откуда: Одесса
Репутация: 250




Для парсинга файла большого размера следует считывать его в бинарном режиме.
Формат сохранения ANSI
Выделять память для массива char следует с запасом.

CODE:
char исходник[10485760];
int g=0;
if (fopen ("C:\foreign_names.txt", "rb")!=0)
{
g=freadb(#исходник[0], 10485760);
fclose();
}
g=g-1;
исходник[g]=0;

//messagebox (g);

messagebox (parserjson(Rez_Json, format(#исходник[0])));

int W=sizejson(Rez_Json);
new string Key[W];
new string Value[W];
messagebox (W);

int E=readjson (Rez_Json, #Key[0], #Value[0]);
messagebox (E);

string S=Key[200000]+" = "+Value[200000];//Должно быть более 200000 пар КЛЮЧ ЗНАЧЕНИЕ
messagebox (S);
 
 Top
Kibor
Отправлено: 19 Июля, 2020 - 01:08:15
Post Id



Администратор
Эксперт


Покинул форум
Сообщений всего: 6363
Дата рег-ции: Март 2013  
Откуда: Одесса
Репутация: 250




Пример как находить значения ключей с неизвестными частями ключа на примере market.csgo.com, market.dota2.net и т.д..

Парсим(для просмотра ссылки Вам необходимо авторизоваться)
Данный запрос выдает более 1 000 000 пар Ключ - Значение.

Пример ответа:

 Цитата:
{
success: true,
time: 1565103435,
currency: "RUB",
items: {
1434515088_0: {
price: "0.50",
buy_order: "0.10",
avg_price: "0.74",
popularity_7d: "47",
market_hash_name: "Arcane Defiance Loading Screen",
ru_name: "Загрузочный экран «Arcane Defiance»",
ru_rarity: "Common",
ru_quality: "Standard",
text_color: "D2D2D2",
bg_color: "",
},
3884947406_188530139: {
price: "0.60",
buy_order: "0.10",
avg_price: "0.94",
popularity_7d: "13",
market_hash_name: "Armor of Utter Eradication",
ru_name: "Armor of Utter Eradication",
ru_rarity: "Uncommon",
ru_quality: "Standard",
text_color: "D2D2D2",
bg_color: "",
}
}
}


В ответе присутствует неизвестный ключ (выделен красным)
Задача - найти значения всех ключей market_hash_name, посмотреть их цену (price) и если она менее 50, записать их в файл в формате:

 Цитата:
items.3920670035_188530139.market_hash_name = Tec-9 | Isaac (Field-Tested)
items.3920670035_188530139.price = 42.30

items.3920670037_188530139.market_hash_name = Souvenir SCAR-20 | Sand Mesh (Minimal Wear)
items.3920670037_188530139.price = 17.19

items.3920670038_188530139.market_hash_name = Souvenir SCAR-20 | Sand Mesh (Minimal Wear)
items.3920670038_188530139.price = 17.19

items.3920670043_302028390.market_hash_name = AWP | Safari Mesh (Well-Worn)
items.3920670043_302028390.price = 11.23

items.3920670048_302028390.market_hash_name = USP-S | Night Ops (Field-Tested)
items.3920670048_302028390.price = 22.48


Будет использоваться регулярное выражение. Поскольку размер JSON довольно велик, требует на выполнение несколько минут.

CODE:
//https://market.csgo.com/api/v2/prices/class_instance/RUB.json
new char S[300000000];
if (sendgetweb(#S[0], "Mozilla/4.0 (compatible; MSIE 6.0b; Windows NT 5.0; .NET CLR 1.0.2914)", "GET", "https:/^/market.csgo.com", "api/v2/prices/class_instance/RUB.json")>0)
{
new string T[1];
T[0]=format(#S[0]);
delete S;
messagebox ("Получили JSON с сайта.");

parserjson(Rez_Json, T[0]);//Парсим ответ
delete T;
messagebox ("Распарсили JSON.");

int W=sizejson(Rez_Json);//Узнаем количество пар Ключ Значение

new string Key[W];
new string Value[W];

int E=readjson (Rez_Json, #Key[0], #Value[0]);//Заполняем массивы string Ключами и Значениями
messagebox ("Получили список всех пар Ключ - Значение JSON. Количество пар = "+format(E));

string f;
double price;
if (fopen (tempfolder()+"sorts.txt", "w")!=0)
{
/*
Пример искомых ключей:
items.2727741750_302028390.market_hash_name
items.310776501_0.market_hash_name
items.3884947400_143865972.market_hash_name
*/
for (int n=4; n<E; n++)
{
if (regexsearch(1, #f, Key[n], "(items.)(.*)(.market_hash_name)"))//Ищем ключи с неизвестным ???????????? "items.????????????.market_hash_name"
{
price=formatsn(Value[n-4]);//Узнаем цену
if (price>0 && price<50)//Если цена менее 50 и более 0
{
fwrite(Key[n]+" = "+Value[n]);//Записываем Название
fwrite(ENDL);
fwrite(Key[n-4]+" = "+Value[n-4]);//Записываем Прайс
fwrite(ENDL); fwrite(ENDL);
}
}
}
fclose();
}
delete Key;
delete Value;
start(tempfolder()+"sorts.txt");
}
 
 Top
Zireael
Отправлено: 19 Июля, 2020 - 11:43:40
Post Id



Пользователь
Эксперт


Покинул форум
Сообщений всего: 2536
Дата рег-ции: Нояб. 2017  
Репутация: 284




 Цитата:
new char S[1000000000];

При запуске пишет Out of memory.
Ответ около 60мб, выделять 1гб явно нет смысла.
 
 Top
Kibor
Отправлено: 19 Июля, 2020 - 11:50:42
Post Id



Администратор
Эксперт


Покинул форум
Сообщений всего: 6363
Дата рег-ции: Март 2013  
Откуда: Одесса
Репутация: 250




 Zireael пишет:
При запуске пишет Out of memory.
Ответ около 60мб, выделять 1гб явно нет смысла.


У вас наверно в настройках Кибор стоит сразу много памяти. У меня 200 мб, все работает.
Это просто пример. Уменьшил в 3 раза в примере.
 
 Top
phpmax
Отправлено: 20 Августа, 2020 - 22:30:53
Post Id



Пользователь
Прохожий


Покинул форум
Сообщений всего: 8
Дата рег-ции: Май 2019  
Репутация: 0




Спасибо!!! Этого очень не хватало при работе с сервером из бота
 
 Top
Страниц (1): [1]
Сейчас эту тему просматривают: 1 (гостей: 1, зарегистрированных: 0)
« О программе Кибор »


Все гости форума могут просматривать этот раздел.
Только администраторы и модераторы могут создавать новые темы в этом разделе.
Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.
 




Powered by