Kibor |
Отправлено: 03 Июня, 2020 - 21:22:07
|
Эксперт
Покинул форум
Сообщений всего: 8217
Дата рег-ции: Март 2013
Откуда: Одесса
Репутация: 357
|
Реализован парсер JSON
Дополнительные функции для работы с JSON (sizejson, readjson, valuejson) Версия 5.64 Работа с JSON форматом
Парсер JSON формата осуществляется функцией
parserjson(Rez_Json, исходник);
где
Rez_Json - Символьное имя объекта
исходник - string, в котором записан Json формат
Возвращает 1 при удаче
-1 если формат 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
}
]
}
|
|
|
Kibor |
Отправлено: 04 Июня, 2020 - 03:31:07
|
Эксперт
Покинул форум
Сообщений всего: 8217
Дата рег-ции: Март 2013
Откуда: Одесса
Репутация: 357
|
Узнать все 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++;
} |
|
|
Kibor |
Отправлено: 04 Июня, 2020 - 05:17:01
|
Эксперт
Покинул форум
Сообщений всего: 8217
Дата рег-ции: Март 2013
Откуда: Одесса
Репутация: 357
|
Пример использования парсера для работы с сервисом anti-captcha.com для решения капчи.
Ключ dce6bcbb1a728ea8d563de6d169a2057 указан для примера.
Это код готовый к использованию:
CODE:
pause (1000);
savescreen(JPG, "C:\capcha.jpg", 653, 332, 995, 448, -1);//Делаем скрин капчи и сохраняем на диск
sleep(100);
string O;
int k=read_captcha("dce6bcbb1a728ea8d563de6d169a2057", "C:\capcha.jpg", #O);
messagebox (k);//Возвращает 1 при решение. <0 при ошибке
messagebox (O);//Решение или текст ошибки
function read_captcha(string KEY, string FL, string #Ot)
{
char BYTE[100000];//Массив байт для загрузки файла с капчей JPG. Потом его используем для JSON запроса
//Загружаем файл с капчей JPG и сразу форматируем его в base64
//первой выполнится функция read_file, вернет размер его и в #file[0] будет уже указатель на массив байт файла
//Затем выполнится функция base64code
string file64=base64code (#BYTE[0], read_file(#BYTE[0], FL));//Перед этим скриним часть экрана с капчей и сохраняем ее в 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^":^""+KEY+"^"," +
"^"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];//Массив для приема ответа
int K=0;
A: 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
}
*/
if (parserjson(Rez_Json, format(#REZ[0]))!=1)//Парсим ответ
{
if (K>2)
{
Ot="Не подключились к сервису";
return -1;
}
K++;
pause(2000);
goto A;
}
//messagebox (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^":^""+KEY+"^",^"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"
}
*/
if (parserjson(Rez_Json, format(#REZ[0]))!=1)//Парсим ответ
{
continue;
}
if (Rez_Json.errorId!="0")//Если есть ошибка
{
//messagebox("errorId "+Rez_Json.errorId);
Ot=Rez_Json.errorId;
//messagebox(format(#REZ[0]));
return -2;
//break;//Выходим из цикла
}
if (Rez_Json.status=="ready")//Если капча решена
{
//messagebox (Rez_Json.solution.text);//Выводим решение
//messagebox (Rez_Json.solution.url);
Ot=Rez_Json.solution.text;
return 1;
//break;//Выходим из цикла
}
}
}
else
{
//messagebox (Rez_Json.errorCode);//Если не верный clientKey
Ot=Rez_Json.errorCode;
return -3;
}
Ot="Ошибка";
return -4;
}
function read_file(char #B[0], string pyt)
{
int size_file=0;
if (fopen (pyt, "rb")!=0)
{
size_file=freadb(#B[0], 10000);
fclose();
}
//messagebox (size_file);
return size_file;
}
Ниже развернутый код
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];//Массив для приема ответа
A: 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
}
*/
if (parserjson(Rez_Json, format(#REZ[0]))!=1)//Парсим ответ
{
pause(2000);
goto A;
}
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"
}
*/
if (parserjson(Rez_Json, format(#REZ[0]))!=1)//Парсим ответ
{
continue;
}
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;
}
|
|
|
Kibor |
Отправлено: 19 Июля, 2020 - 01:08:15
|
Эксперт
Покинул форум
Сообщений всего: 8217
Дата рег-ции: Март 2013
Откуда: Одесса
Репутация: 357
|
Пример как находить значения ключей с неизвестными частями ключа на примере 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");
}
|
|
|
|