В прошлую субботу я хотел написать код Tumblr Scrapper, избегая Tumblr API, просто для удовольствия. Для этой цели я решил разработать скрипт на Node.js.
К настоящему моменту я понял, что Node.js, возможно, не лучший вариант, и Python послужил бы моим целям быстрее. Тем не менее, это оказалось хорошим предлогом, чтобы поэкспериментировать с промисами JavaScript.
На первый взгляд, эта процедура может показаться не интересной и не стоящей того, чтобы ее делать, учитывая, что на Github есть несколько разборщиков Tumblr. Однако все те, которые я нашел, используют API Tumblr (что, конечно, требует наличия учетной записи, ключа API и т. д.). Ни один из них не разрешит доступ к защищенным паролем Tumblrs. Интересный момент, с которым я столкнулся, изучая это, заключается в том, что аутентификация Tumblr довольно своеобразна.
В качестве примера я буду использовать свой собственный пример страницы Tumblr, чтобы объяснить, как работает защищенная паролем аутентификация Tumblr (по состоянию на сентябрь 2017 г.):
http://victorpassword.tumblr.com и его пароль: victor666
Если мы получим к нему доступ, первое, что нужно отметить, это то, что мы перенаправлены на:
https://www.tumblr.com/blog_auth/victorpassword
где нам представлена форма аутентификации:
Если мы посмотрим на исходный код, то обнаружим, что это довольно простая веб-форма:
<form id=”auth_password” method=”post”> <div id=”password_and_button” class=”input_with_button”> <label for=”password”>Contraseña</label> <input type=”password” name=”password” id=”password” class=”text_field” placeholder=”Introducir contraseña” style=”width: 218px;”> <button type=”submit”>Entrar</button> </div> </form>
Если мы отправим форму с неправильным паролем, мы можем ожидать, что она вернет соответствующий неверный пароль web. Теперь неожиданное поведение происходит, когда мы отправляем правильный пароль.
Конечно, при доступе через браузер я ничего не заметил (у меня тамблер загрузился корректно). Однако, когда я получаю программный доступ, форма каждый раз возвращает одну и ту же конкретную страницу входа; которые я сейчас перейду к описанию.
Проверка сетевого трафика не выявила ничего странного:
Я некоторое время боролся с этим, проверяя файлы cookie, заголовки и сетевой трафик, не понимая, что происходит. Что еще более интригует, так это то, что у меня был лишний запрос от браузера на страницу входа с этими данными в виде:
Откуда взялось это 1505662833:77OCC….? Возможно, его сгенерировал какой-то локальный JavaScript, но… это второй отправка. Первый (как видно на предыдущей картинке) отправляется на сервер в виде обычного текста.
Наконец я еще раз просмотрел страницу входа и… сюрприз! во второй раз, когда мы получаем страницу входа (после того, как мы вводим правильный пароль), мы получаем еще несколько дополнительных вещей. Эти:
<script type="text/javascript"> document.addEventListener('DOMContentLoaded', function() { (function($){ $("form#auth_send").submit(); })(jQuery); }); </script> <div id="form"> <div id="form_content"> <form id="auth_send" method="post" action="http://victorpassword.tumblr.com/"> <input type="hidden" name="auth" value="1505662833:Ry4O9hCHRxZLKqtMtSyy1bxxwso" /> </form> </div> </div>
Вау! они добавляют лишнее скрытое поле с учетными данными и снова автоматически отправляют форму (вот чего мы в браузере ничего не заметили).
Кстати, на этот раз они указывают на: http://victorpassword. tumblr.com, а не https://www.tumblr.com/blog_auth/victorpassword.
Как только мы делаем второй запрос к форме, мы, наконец, получаем ожидаемый файл cookie для следующих обращений к Tumblr:
Несмотря на то, что это не является особенно сложным или хакерским, это не просто и, кажется, не имеет особого смысла. Конечно, у инженеров Tumblr есть свои причины для разработки этой формы двойной отправки. Для меня это до сих пор загадка :)
Если кому интересно, полный код скраппера можно найти здесь: https://github.com/vaguilera/ScrappyTumblr
So, TL;DR:
- Отправьте пароль на: https://www.tumblr.com/blog_auth/‹tumblrname›
- Ищите ввод скрытых данных в форму auth_send
- Разместите эти данные по адресу: https://‹tumblrname›.tumblr.com/
- Возьмите файл cookie авторизации
- Выгода