aleksvarga Ответов: 1

Как сделать так, чтобы мой webresponse не возвращал тарабарщину?


Итак, я просматриваю это уже несколько часов и не могу понять, что происходит не так. Я использовал PostMan для создания запроса GET на ту же ссылку, и он действительно вернул некоторые хорошо проанализированные HTML-данные. При использовании PostMan я использую точно такие же заголовки, как и при работе с кодом, но по какой-то причине, когда я делаю это с кодом, он возвращает тарабарщину.

"\u001f�\b\0\0\0\0\0\0\u0003�R�n�0\u0010��+�{�ZԲ,7m\u0012C�m�I\0���\b\u0002�\\EL%R W��ǿ��m 9� qf�Ŭv�x���˷\u001f�W�p\u05eeO��\0\U000d02be/QHi\a�\u001e'E�~}\u0002P4$�\u0004\u0002�\u0005�F8O\\��uz��+���TVi�J|�秧p@\u007f��R��7����@\nI\u0004�\u07b2��\u0004�\aTd�ॣ\u0011\u001d�����[�\b�\u001a&\u0013:xҊ�R�VKJ#��6��hS\u001fܨ��\u0019tb���{)\r�\\�\n���ߨ�'h\u001c�%fG����Ak�{��2�T�����6��z.[;�څ��8;��$?V��>\vӠ�< ���\u0016%z�\f��6\u0010\u001e[�\r\u0011\a��]��=�𣑠�&\a����~<Z?\u0006gߧ���ى~]d{�W\u0013~H�5qw�@^\u0015�J�(�?\u0018��F\\��\ng\u0018�I\u001eW?�o���E���&�x7��7��\u0017� �'�/����|���Kb��c��ʪq�dZt�r�!��>�ό�\u001aȹ\u0002\0\0"


Однако.. Почтальон возвращает это.
[Визуальное представление]


Вот код, который делает запрос
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://accounts.spotify.com/en/login");

            request.Method = "GET";
            request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8";
            request.Headers.Add("Accept-Encoding", "gzip, deflate, br");
            request.UserAgent = "Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.108 Safari/537.36";
            request.Headers.Add("Accept-Language", "sv-SE,sv;q=0.9,en-US;q=0.8,en;q=0.7");


            var loginResp = request.GetResponse();
            string cont = null;

            Stream fAnswer = loginResp.GetResponseStream();
            StreamReader sr = new StreamReader(fAnswer, Encoding.UTF8);

            //This right here is what returns the gibberish.
            cont = sr.ReadToEnd();


Что я уже пробовал:

Я пробовал играть с настройками кодировки и менять заголовки.

Jochen Arndt

Похоже, что ответ сжат. Попробуйте сделать это без заголовка "Accept-Encoding".

1 Ответов

Рейтинг:
6

Thomas Daniels

Вы принимаете gzip и сдуваете ответы, так что эта "тарабарщина" на самом деле является сжатым ответом. Однако это не проблема, вы можете сказать HttpWebRequest автоматически распаковать его:

request.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;

Я вижу, что вы также принимаете "br", и я не смог найти для этого автоматическую декомпрессию, так что, вероятно, неплохо удалить "br" из ваших принятых кодировок, если только вы не хотите сами позаботиться о декомпрессии, если вам случится получить ответ "br".


aleksvarga

О, Ничего себе! Большое вам спасибо!
А как насчет печенья? Он вообще не возвращает никаких печений, но на почтальоне это происходит.
https://ghostbin.com/paste/rz7ss

Thomas Daniels

Я могу воспроизвести, что не получаю печенье, но что такое печенье, которое получает почтальон? Не видя этого, я понятия не имею, почему .Печенье пустое.

aleksvarga

Файл cookie, который он получает, - это своего рода csrf_Token
https://i.imgur.com/xxj4vi3.png

Thomas Daniels

Ах. Цель такого файла cookie-избежать подделки межсайтовых запросов (вы можете посмотреть его для получения более подробной информации). Во всяком случае, я понятия не имею, почему его нет .Cookies... но его все еще можно получить с помощью заголовков: response.Headers[HttpResponseHeader.SetCookie].

aleksvarga

О да! Это действительно имеет смысл, и это очень умно!
Так что-то вроде этого?
строка cookies = ответ.Заголовки[HttpResponseHeader.Cookie посредством setcookie];
Потому что SetCookie устанавливает заголовки? И поскольку он должен включать только 1, нам не нужно иттерировать через него? Пожалуйста, исправьте мои ошибки, если они там были, потому что я все еще пытаюсь учиться.

Thomas Daniels

Да, эта строка работает, потому что Headers[...] возвращает строку.

Однако на самом деле этого недостаточно: заголовок Set-Cookie сообщает вам имя всех файлов cookie (в данном случае одного), их значение и дополнительные свойства. Распечатайте значение на консоли и посмотрите, как оно выглядит, а затем вы сможете увидеть, что вы хотите извлечь из него и как его разобрать.

aleksvarga

Ах, так если бы там было больше печенья, я бы разбирал его лучше!
Быстрый вопрос, так что когда я на самом деле пытаюсь войти в spotify..
По словам скрипача "https://accounts.spotify.com/api/login-это то место, куда я отправляю свои парамы. и параметры оздоровительная помню=истина&амп;логин=логин&усилителя;пароль=пароль&амп;csrf_token=theToken.. Если бы я поместил его в чистую форму url, было бы это так?

Обратите внимание, как я ставлю знак "?" после /login.. Вот в чем я не уверен.
https://accounts.spotify.com/api/login?emember=true&username=username&password=password&csrf_token=theToken

Thomas Daniels

Нет, вы не можете поместить эти параметры в URL-адрес. Запрос на вход в систему должен быть POST-запросом, тогда как размещение параметров в URL-адресе сделает его GET-запросом. Смотрите здесь, чтобы сделать запрос POST: https://stackoverflow.com/questions/4015324/how-to-make-http-post-web-request

aleksvarga

Ааааа! Ух ты, какая мозговая вспышка у меня только что была! Я думал, что использование вашего веб-браузера сделает запрос POST, потому что вы знаете, что отправляете данные на сервер, но на самом деле он просто просит получить!
Чтобы сделать пост, мне нужно сделать это через код!
Ух ты, честно говоря, большое тебе спасибо за то, что помог мне с этим, ты такая легенда!

Thomas Daniels

Пожалуйста, я рад, что смог помочь!

aleksvarga

Последний вопрос.. Как должен протекать код?
Это создаст вам запросы WebRequest > получайте маркер > создавайте пост запросы WebRequest с маркером у нас с самого начала? Потому что этот POST-запрос генерирует новый токен.

Thomas Daniels

Да, этот рабочий процесс звучит правильно. Я не думаю, что вам следует беспокоиться о новом токене в почтовом запросе, если только вы не отправляете какие-то другие формы.

aleksvarga

Если бы я мог проголосовать за разработчика года, у вас был бы мой голос!

Thomas Daniels

Спасибо :)

aleksvarga

Я постоянно получаю это исключение: удаленный сервер вернул ошибку: (400) плохой запрос.'
Я что-то пропустил? Я чувствую, что это может быть, что я не устанавливаю некоторые заголовки.
https://ghostbin.com/paste/27gd4
И я изменил строку username = "username" только потому, что мне не хотелось сливать свое имя и пароль :P

Thomas Daniels

Вы не анализируете заголовок Set-Cookie. Вы не можете просто "хранить и забывать", все гораздо сложнее. Цитирую мой предыдущий комментарий:

"
Однако на самом деле этого недостаточно: заголовок Set-Cookie сообщает вам имя всех файлов cookie (в данном случае одного), их значение и дополнительные свойства. Распечатайте значение на консоли и посмотрите, как оно выглядит, а затем вы сможете увидеть, что вы хотите извлечь из него и как его разобрать."

aleksvarga

О! Потому что строка заголовка Set-Cookie содержит много ненужной информации!
"csrf_token=tokenHere;Version=1;Domain=accounts.spotify.com;Path=/;Безопасный"
Поэтому я бы просто хотел извлечь или "разобрать" эту часть - "csrf_token=tokenHere"

Thomas Daniels

На самом деле вам нужна только часть "tokenHere", тогда ваш текущий код, вероятно, будет работать (если часть csrf_token= сохранена, то ваш запрос может иметь две строки csrf_token= в теле, если вы не измените свой код). Проблема, вызвавшая плохой запрос, действительно была "случайным материалом" (по крайней мере, я так думаю - я не пробовал код с моими учетными данными Spotify).

Thomas Daniels

Чтобы продолжить мой предыдущий комментарий: Я сам взглянул на содержимое заголовка Set-Cookie. Я думаю, что вы можете легко извлечь csrf_token следующим образом: разделить на знак = и на точку с запятой с помощью .Split ('=',';') и взять второй элемент этого массива (первый будет "csrf_token", второй-фактический токен).

aleksvarga

Да, похоже, это сработает!
Итак, суть вопроса, почему я получал плохой запрос, заключается в том, что он публиковал этот случайный материал в конце

;Версия=1;Domain=accounts.spotify.com;Path=/;Secure" с правильным запросом?

aleksvarga

Хм.. все еще дает мне исключение 400 Bad request, и теперь я передаю это как params

remember=true&username=myUsername&password=myPassword&csrf_token=AQAw7R_6HRfwLdhrcofiUA08cbNCFY8_sfzsidzdpkjnn2q12mkffl6ecrcjq5dlr5vni17olfszumdblw

И я передаю его вот так
https://ghostbin.com/paste/epbgj
Я убедился, чтобы проверить, что csrf_Token является правильным.
Хм ... Интересно, где он спотыкается..

Thomas Daniels

Похоже, что Spotify возвращает 400, если ваше имя пользователя или пароль неверны. Вы это проверяли?

Тем не менее, поймите, что вы, вероятно, используете страницу входа в Spotify таким образом, что она не была создана для использования (но я понятия не имею, что делает ваше приложение, так что это всего лишь предположение); возможно, Spotify Web API есть что-нибудь для тебя? Этот API создан для того, чтобы запрашиваться программно, в то время как я сомневаюсь, что для страницы входа в систему вы пытаетесь достичь.

aleksvarga

Я хотел изучить веб-автоматизацию и хотел использовать "реальный веб-сайт", чтобы я мог применить свои знания к другим веб-сайтам, и есть много книжных сайтов, которые я хотел бы автоматизировать свой ежедневный вход в систему, у которых нет API, так что это должен быть единственный способ.
Однако таким образом я узнаю о жетонах колодца и т. д.

Здесь вы можете увидеть весь исходный код с действительным именем пользователя и паролем, которые я только что создал для тестирования. Я чувствую, что здесь есть какая-то большая ошибка, которую я упускаю.
https://ghostbin.com/paste/v3gvt

Thomas Daniels

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

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

aleksvarga

Да, это прекрасно, я действительно ценю ту помощь, которую вы оказали до сих пор! Похоже, что это как-то связано с Javascript и что мне придется сделать какой-то ручной синтаксический анализ, но я буду продолжать в том же духе!
Спасибо!