Эта статья входит в цикл статей о том как легко научиться писать свои регеры, парсеры, спамеры, накрутчики опросов и прочий софт, автоматизирующий действия в сети. Вобщем-то в этом нет ничего сложного. Писать будем на C#. Нам понадобятся Visual Studio, Firefox, Firebug, Fiddler и ViKing.Engine, который можно скачать тут Следующая статья: продвинутый регер rambler.ru Предыдущая статья: парсер прокси. Сегодня мы напишем регистратор почты на rambler.ru. Этот пример поможет научиться использовать сниффер для анализа запросов, которые посылает браузер. А еще мы научимся скачивать картинки и разгадывать капчу. К тому же на этот раз у нас будет windows-приложение, а не консольное. Итак, поехали. Создаем в Visual Studio проект Windows Application, подключаем ViKing.Engine.dll, добавляем сверху код Code: using ViKing.Engine; using ViKing.Engine.GUI; using System.IO; using System.Text.RegularExpressions; На этот раз мы также добавили строку using ViKing.Engine.GUI, она нам пригодится для того чтобы было просто отображать капчу на экране, в общем сами увидите чуть позже. Теперь откроем firefox и fiddler. Не забудьте включить фидлер в статусной строке фаерфокса (должно быть написано «Fiddler: ForceOn»). Перейдем на рамблер, ткнем зарегистрироваться и заполним форму регистрации: Скриншот Для удобства желательно пометить запрос, который появился в сниффере при открытии формы регистрации клавишей «insert» (на скриншоте у меня он красный). Дальше жмем зарегистрироваться и смотрим что за запрос отправился на сервер: Скриншот Ага, отправился POST-запрос на http://id.rambler.ru/script/newuser.cgi с параметрами Code: skin id back back_immediate uniq_id 6b9f763008ed2b609110f6d50eb92f50 action register user.fname firstname user.lname lastname user.gender 1 user.bday 1 user.bmonth 1 user.byear 1950 user.login mail1245 user.domain rambler.ru x.emailfree mail1245@rambler.ru user.password1 qweqwe user.password2 qweqwe user.question own.question user.own_question question user.answer answer user.email2 user.captcha cfmrnf Мы видим что почти все эти параметры – поля только что заполненной нами формы. Особый интерес для нас представляют user.login – его мы должны сделать случайным user.captcha – нужно будет найти где располагается соответствующая картинка uniq_id – какой-то уникальный id, давайте выясним подробнее что это такое. Для этого посмотрим в сниффер на несколько строк выше, на запрос который браузер сделал при открытии формы регистрации. В ответ на него нам пришел код страницы регистрации. Откроем код страницы в блокноте и поищем там интересующий нас id 6b9f763008ed2b609110f6d50eb92f50. Он находится в 3 местах: Code: Set-Cookie: rrc=6b9f763008ed2b609110f6d50eb92f50; domain=.rambler.ru; path=/; httponly <input name="uniq_id" type="hidden" value="6b9f763008ed2b609110f6d50eb92f50" /> <img id="secimage" title="Введите показанные на картинке символы" src="http://id.rambler.ru/captcha/6b9f763008ed2b609110f6d50eb92f50.jpg" border="0" alt="Введите показанные на картинке символы" width="300" height="60" /> Первая строка располагается в заголовках и устанавливает куки. Возможно если не отправить этот кук в запросе на регистрацию, то он выдаст ошибку. Но для начала попробуем обойтись без куков, вдруг и так сойдет. Вторая строка находится на веб-форме и как-раз она и добавляет наш id в POST-запрос. Третья строка – как это ни удивительно, это тег img с изображением капчи. Адрес по которому он берет картинку содержит наш uniq_id. Это очень удобно, значит можно найти адрес картинки и из него-же вытащить id. Ну чтож, похоже мы нашли все что нам нужно для регистрации, приступим к написанию софта. Последовательность действий должна быть такая 1. Качаем форму регистрации 2. Находим там uniq_id, он же адрес картинки с капчей 3. Качаем картинку 4. Отгадываем капчу 5. Отправляем заполненную форму на серер 6. Все! 1. Скачать форму – проще простого! Смотрим в фидлер на адрес и пишем код: Code: string page = VkRequest.Request("http://id.rambler.ru/script/newuser.cgi").Content; 2. Теперь нужно выдернуть id. Делаем вот так: Code: string id = Regex.Match(page, @"http://id.rambler.ru/captcha/(?<id>\w+).jpg").Groups["id"].Value; Это регулярное выражение, мы с таким уже сталкивались. Оно ищет адрес картинки с капчей, но вместо набора букв в названии картинки, который все время меняется мы написали (?<id>\w+). «\w»означает любую букву или цифру, «+» означает что «\w » нужно повторить 1 или более раз. «(?<id>)» присваивает получившейся комбинации имя «id». Затем команда «.Groups["id"].Value» выдергиает из получившейся комбинации только кусок с названием «id». Таким образом мы получили значение uniq_id. 3. Теперь скачаем картинку с капчей: Code: Image captchaImage = VkRequest.Request("http://id.rambler.ru/captcha/" + id + ".jpg").GetImage(); Обычный GET-запрос, только «.GetImage()» в конце означает что ответ сервера нужно воспринимать как картинку. 4. Для отгадывания картинки можно использовать класс CaptchaWindow из дижка викинга. Перед использованием его нужно инициализировать в конструкторе формы Code: public Form1() { InitializeComponent(); CaptchaWindow.Initialize(this); } Терерь его можно использовать вот так: Code: string captchaAnswer = CaptchaWindow.Show(captchaImage); 5. Теперь давайте сформируем POST-запрос для сервера. Для этого скопируем запрос который мы отправляли через браузер и изменим значения uniq_id, user.login и user.captcha: Code: string post = string.Format( "uniq_id={0}&user.login={1}&user.captcha={2}&user.password1=qweqwe&user.password2=qweqwe&skin=id&back=&back_immediate=&action=register&user.fname=firstname&user.lname=lastname&user.gender=1&user.bday=1&user.bmonth=1&user.byear=1950&user.domain=rambler.ru&x.emailfree=mail1245%40rambler.ru&user.question=own.question&user.own_question=question&user.answer=answer&user.email2=", id, email, captchaAnswer); Я переставил важные параметры в начало запроса для удобства, это можно делать, так как порядок ни на что не влияет. В переменной еmail должен содержаться случайный логин. Самый быстрый способ его сделать такой: Code: string email = Path.GetRandomFileName().Replace(".", ""); Теперь отправим наш запрос на сервер. Для этого вызовем функцию Request с 2 параметрами: Code: var result = VkRequest.Request("http://id.rambler.ru/script/newuser.cgi", post); После этого наша почта должна быть зарегистрирована. Давайте на последок сделаем проверку, успешно ли она зарегалась. Ответ для успешной регистрации у нас в сниффере уже есть, это редирект на проверку куков: Code: HTTP/1.1 302 Found Server: nginx/0.8.52 Date: Thu, 13 Jan 2011 20:55:59 GMT Content-Type: text/html; charset=windows-1251 Connection: keep-alive Keep-Alive: timeout=20 P3P: CP="NON DSP NID ADMa DEVa TAIa PSAa PSDa OUR IND UNI COM NAV" Set-Cookie: rsid=d7869f1f48cfdf521adaf5898dae6821; domain=.rambler.ru; path=/; httponly Set-Cookie: rlogin=mail1245@rambler.ru; domain=.rambler.ru; expires=Thu, 31-Dec-37 23:55:55 GMT; path=/ Set-Cookie: rup=MXbkSZD38i7rheLADZysFSU_; domain=.rambler.ru; expires=Thu, 31-Dec-37 23:55:55 GMT; path=/ Pragma: no-cache, no-store Cache-Control: no-cache Expires: Thu, 01 Jan 1970 00:00:01 GMT Location: http://id.rambler.ru/script/auth.cgi?mode=checkcookie;sid=d7869f1f48cfdf521adaf5898dae6821;back=http%3A%2F%2Fid.rambler.ru%2Fscript%2Fnewuser.cgi%3F%26amp%3Baction%3Dnew_user%26amp%3Bskin%3Did%26amp%3Bback%3D Content-Length: 0 Теперь давайте зарегистрируемся неудачно, например неверно едем капчу. Получим такой ответ: Code: HTTP/1.1 200 OK Server: nginx/0.8.52 Date: Thu, 13 Jan 2011 20:55:59 GMT Content-Type: text/html; charset=utf-8 Connection: keep-alive Keep-Alive: timeout=20 Pragma: no-cache, no-store Cache-Control: no-cache Expires: Thu, 01 Jan 1970 00:00:01 GMT Content-Length: 19382 <!-- This comment will put IE 6, 7 and 8 in quirks mode --> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html lang="ru"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8>"> <meta http-equiv="X-UA-Compatible" content="IE=8"> <link rel="stylesheet" type="text/css" href="/css/id.css" media="all"> <link rel="icon" href="/favicon.ico" type="image/x-icon"> <link rel="shortcut icon" href="/favicon.ico" type="image/x-icon"> <script type="text/javascript"><!-- rg_errors_text = { БЛА-БЛА-БЛА Получается, что когда регистрация неуспешная, нам просто выдают форму регистрации со списком ошибок. Давайте тогда будем считать что если редирект произошел, то все ок, а если нет то была ошибка: Code: if (result.Headers["Location"].Length > 0) textBox1.AppendText(email + " зарегистрирован!\r\n"); else textBox1.AppendText("Ошибка\r\n"); Вот и все! Регистратор готов. Пробуем зарегистрировать программой аккаунт и зайти в него через браузер (пароль «qweqwe»). Все работает! Скачать файл с исходниками можно тут: http://kairos-blog.ru/?p=177
Пару советов. 1. Зачем сохранять капчу? Не проще ли передать через конструктор ссылку на капчу, установить ссылку в свойство ImageLocation и она автоматически загрузится. Плюс, можно установить анимацию загрузки и другие 'эффекты'. 2. Если использовать свою библиотеку для работы с Web, то можно сделать работу с Post запросами поудобнее. Допустим так: Code: HttpRequest.PostParameters postParams = new HttpRequest.PostParameters(); postParams["login"] = "John"; postParams["password"] = "smith"; postParams["nobody"] = string.Empty; HttpRequest.Post("http://agent.ru/test.php", postParams); Тоже касается и отправки MIME-данных. 3. Я для этих целей использую браузер Chrome. В нём можно быстро открыть код страницы, всё будет удобно подсвечено и есть поиск, опять же, с подсветкой. И ещё много других возможностей, помогающих в этом деле. Вообще, интересный цикл статей.
Для того чтобы в следующих уроках разгадывать ее через антигейт. Тут фишка в том, что мы узнали что мы хотим искать уже после того как отправили форму. Браузер отобразит уже другую страницу, а фидлер запоминает все запросы. Я понимаю что можно было искать input с именем uniq_id, но не все знают что такое форма на html и откуда браузер берет параметры которые отправляются в post.
Дак смотри. Открыл ты страницу регистрации, тут же открыл её исходный код, там же, в браузере. Все параметры сохранились. Регистрируешься, ловишь сниффером данные и тут же можешь посмотреть, откуда взялся тот или иной параметр, тем же методом поиска.