![]() |
|
|
|||||||
| Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
![]() |
|
|
Опции темы | Поиск в этой теме | Опции просмотра |
|
#1
|
|||
|
|||
|
Хочу написать парсер ключевых слов из вордстата яндекса на Delphi, авторизовался, сохранил все куки, отправляю запрос с ключевым словом по которому хочу получить выборку и тут мне приходит JSON ответ в две строки, одна строка длинной 30+ тыс символов вот ее начало, небольшой кусочек:
PHP код:
И вторая строка это какая то функция чтобы убрать все лишние символы и привести к нормальному виду, оно же должно быть такого вида, да? PHP код:
Вот вся функция: PHP код:
Смотрел снифером аналоги парсеров вордстата и видел что там точно такие же POST запросы и ответ приходит точно такой же, значит они как то переводят данные в читабельный вид, ковыряю эти две строчки второй день очень нужна помощь. В приложении txt файл с полным JSON ответом от wordstat.yandex |
|
#2
|
||||
|
||||
|
Если не ошибаюсь, очпохоже что ответ на питоне приходит, попробовал расшифровать немного с помощью
Код:
//Функция выполняет преобразование вида:
//'\u0421\u043a\u0430\u0439\u0440\u0438\u043c' -> WideString('Скайрим').
function UStrToWideStr(const aUStr : AnsiString) : WideString;
var
i, j, Len : Integer;
begin
Len := Length(aUStr) div 6;
SetLength(Result, Len);
j := 3;
for i := 1 to Len do begin
Result[i] := WideChar( StrToInt('$' + Copy(aUStr, j, 2)) shl 8
+ StrToInt('$' + Copy(aUStr, j + 2, 2)) );
Inc(j, 6);
end;
end; |
|
#3
|
|||
|
|||
|
Я вот думаю может тут и вовсе не нужно ничего декодировать...
Почему когда смотришь исходной код с результатами в нём нет ключевых фраз, а если сделать "исследовать элемент" и в инспекторе посмотреть, то в нём можно найти всю разметку и все ключевые фразы, правда русские символы прописаны вот в таком виде %D1%81 но это не беда, беда получить этот DOM код в Delphi Код:
<a class="b-link b-phrase-link__link" href="/#!/?words=%D1%81%D0%BA%D0%B0%D1%87%D0%B0%D1%82%D1%8C">скачать</a> Последний раз редактировалось and.enk, 01.07.2017 в 18:57. |
|
#4
|
||||
|
||||
|
1) Заходим на страницу яндекс вордстата.
2) Открываем консоль (ctrl+shift+i в хроме). 3) Что-нибудь вводим в строке яндекса, чтоб инициировать запрос. 4) На вкладке консоли "Network" видим ответ примерно того вида, что в первом посте. Там JSON с полями data и key. 5) Находим в коде страницы люто обфусцированный Javascript. Впору бы загрустить (копать 20к строк обфусцированного кода на JS - то еще удовольствие), однако замечаем, что в этом коде только один раз встречается операция XOR (которая есть почти в любом шифровании). 6) Понимаем, что этот XOR - и есть расшифровка. Ручками деобфусцируем код и получаем что-то вроде этого: PHP код:
8) Пишем в консоли var response = <ответ сервера> 9) Вставляем в консоль этот код расшифровки, нам печатается результат: PHP код:
11) PROFIT Последний раз редактировалось Bargest, 01.07.2017 в 22:42. |
| Этот пользователь сказал Спасибо Bargest за это полезное сообщение: | ||
and.enk (02.07.2017)
| ||
|
#5
|
|||
|
|||
|
Спасибо, мне это помогло, правда пришлось подставить response.key и response.data руками в переменные и заменить, почему то у меня в хроме response.length = 0, хотя куки находит... Или я что то с Response не то делал, первый раз с JS в консоле сталкиваюсь.
Главное увидел в браузере расшифрованный текст и это радует. Вопрос теперь в другом, как лучше всего выполнить функцию которая приходит в ответе сервера из поля key? Я видел она генерирует какой то набор символов, который нужен чтобы дополнить ключ для расшифровки текста из поля data. В гугле нашёл что функцию eval можно выполнить с помощью TEvaluator из JEDI Code Library или выполнить JS через TwebBrouser, но с TwebBrouser не хочется... |
|
#6
|
||||
|
||||
|
Поискать примеры через какой-нибудь ScriptControl.
Предлагают так: Код:
procedure TForm1.Button1Click(Sender: TObject);
var
ScriptControl: Variant;
Value: Variant;
begin
ScriptControl := CreateOleObject('ScriptControl');
ScriptControl.SitehWnd := Handle;
ScriptControl.Language := 'JScript';
Value := ScriptControl.Eval('new Date();'); // сюда впихать response.key
ShowMessage(VarToStr(Value));
end; |
| Этот пользователь сказал Спасибо Bargest за это полезное сообщение: | ||
and.enk (05.07.2017)
| ||
|
#7
|
|||
|
|||
|
Добрался сегодня до компа наконец-то..
Код:
procedure TForm1.Button1Click(Sender: TObject);
var
ScriptControl: Variant;
Value: Variant;
begin
ScriptControl := CreateOleObject('ScriptControl');
ScriptControl.SitehWnd := Handle;
ScriptControl.Language := 'JScript';
Value := ScriptControl.Eval('new Date();'); // сюда впихать response.key
ShowMessage(VarToStr(Value));
end;Код полностью рабочий, генерируется недостающий кусочек для ключа расшифровки В консоле хрома у меня получилось расшифровать закодированный текст вашим кодом, пробовал в делфи расшифровать этим кодом Код:
var
key, text, longkey, result: string;
i: integer;
toto, c: char;
begin
for i := 0 to (length(text) div length(key)) do
longkey := longkey + key;
for i := 1 to length(text) do
begin
toto := chr((ord(text[i]) xor ord(longkey[i]))); // XOR алгоритм
result := result + toto;
end;
end;ничего не получилось, как вот этот кусочек строки нужно прописать в Delphi Код:
result = result + String.fromCharCode(response.data.charCodeAt(i) ^ rkey.charCodeAt(i % rkey.length)) |
|
#8
|
||||
|
||||
|
Видимо key неверный. User-Agent надо брать тот же, с которым идет запрос к серверу, а точнее первые 25 его символов. Опять же, если выполнить navigator.userAgent.substr(0, 25) в хроме, то можно увидеть "Mozilla/5.0 (Windows NT 1".
А далее легко - как-нибудь так: Код:
for i := 1 to length(text) do
text[i] := chr(ord(text[i]) xor ord(key[((i-1) mod length(key)) + 1]));Последний раз редактировалось Bargest, 05.07.2017 в 23:23. |
|
#9
|
|||
|
|||
|
С ключом для расшифровки я разобрался, я вставляю в консоль хрома ваш код выше со своими данными, т.е. там уже стоит готовый кей и текст который им зашифрован, всё расшифровывается без проблем, но когда я подставляю те же самые текст и кей
Код:
for i := 1 to length(text) do
begin
text[i] := chr(ord(text[i]) xor ord(key[((i-1) mod length(key)) + 1]));
result := result + text[i];
end;
memo17.Text:=result;мне приходит вот такой результат Код:
%7B%22=Z В приложении скидываю код, если его вставить в консоль хрома и нажать enter всё расшифруется, а Delphi не хочет |
|
#10
|
||||
|
||||
|
Всё работает.
Код:
{тут объявлена DecodeBase64}
var rkey: string;
ttext: string;
i: integer;
begin
rkey := 'Mozilla/5.0 (Windows NT 6595d22397c0b1998.VO1MmJfamekbMplQO3URqsOY-fp5VDKdVYPfZLAQUIz85hA2Aod_OJ7Vz5cVtSuUXaMoByuHOA3VWwNKP_d_RVXBg34uVCCyvY1D9AbxwDqJ5HjCy91NgAQbjM-k5WIc87a9ad7bee75';
ttext := 'aFg4TF5eAkBbWlVOXHJbXEFcNlYXDHESBFZMRxZXXEdpVgRVRwMLHAtvc30DfEh4VERfJk5QfxwNIjtmJTYQByp8H1RVBhdheVZzHWBDYwpkFWVsOH0Q';
ttext := DecodeBase64(ttext);
for i := 1 to length(ttext) do
ttext[i] := chr(ord(ttext[i]) xor ord(rkey[((i-1) mod length(rkey)) + 1]));
WriteLn(ttext);
end.Цитата:
В примере я расшифровал только начало текста, чтобы не писать километровую строку. Поскольку в онлайн-компиляторе паскаля нету никакого unescape или парсера json, я предварительно сделал unescape javascript'ом и перевел в base64, а в примере использовал раскодирование из base64 (делфи нет под рукой). В предыдущем сообщении я не просто так писал про Цитата:
Тебе, соответственно, нужно либо найти способ сделать unescape строки ttext в делфи, либо не парить себе мозги и использовать для вытаскивания строки из ответа сервера готовый JSON-парсер, который есть в новых делфях. В прошлом же сообщении я кидал ссылки на документацию про этот JSON-парсер. Последний раз редактировалось Bargest, 06.07.2017 в 20:37. |