Всем привет, Хочу поделиться радостью Изучая C#, решил начать с простых вещей, так что первая статья в этом направлении будет про автоматическую регистрацию почтового ящика на qip.ru. Собственно, как оказалось, все очень даже просто. Первым делом необходимо создать класс для работы с http. Класс нужен для того чтобы облегчить нам отправку и получение http запросов с сохранностью cookie. Code: public class HTTPClient { private CookieCollection Cooks = new CookieCollection(); public HTTPClient(string session_cookiename) { } public void ClearCookie() { } public HttpWebResponse Request(string sUrl) { return Request(sUrl, true); } public HttpWebResponse Request_Post(string path, string post_body) { return Request_Post(path, post_body, true); } public HttpWebResponse Request_Post(string path, string post_body, bool bAutoRedirect) { try { HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(path); httpWebRequest.Proxy = new WebProxy("x.x.x.x", 3128); httpWebRequest.Proxy.Credentials = new NetworkCredential("username", "password","domain"); httpWebRequest.AllowAutoRedirect = bAutoRedirect; httpWebRequest.CookieContainer = new CookieContainer(); if (Cooks != null) { httpWebRequest.CookieContainer.Add(Cooks); } httpWebRequest.Method = "POST"; httpWebRequest.ContentType = "application/x-www-form-urlencoded"; byte[] ByteQuery = System.Text.Encoding.ASCII.GetBytes(post_body); httpWebRequest.ContentLength = ByteQuery.Length; Stream QueryStream = httpWebRequest.GetRequestStream(); QueryStream.Write(ByteQuery, 0, ByteQuery.Length); QueryStream.Close(); HttpWebResponse httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse(); httpWebResponse.Cookies = httpWebRequest.CookieContainer.GetCookies(httpWebRequest.RequestUri); if (httpWebResponse.Cookies != null) { Cooks.Add(httpWebResponse.Cookies); } return httpWebResponse; } catch (WebException ex) { return ex.Response as HttpWebResponse; } } public HttpWebResponse Request(string sUrl, bool bAutoRedirect) { try { HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(sUrl); httpWebRequest.Proxy = new WebProxy("x.x.x.x", 3128); httpWebRequest.Proxy.Credentials = new NetworkCredential("username", "password", "domain"); httpWebRequest.AllowAutoRedirect = bAutoRedirect; httpWebRequest.CookieContainer = new CookieContainer(); if (Cooks != null) { httpWebRequest.CookieContainer.Add(Cooks); } HttpWebResponse httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse(); httpWebResponse.Cookies = httpWebRequest.CookieContainer.GetCookies(httpWebRequest.RequestUri); if (httpWebResponse.Cookies != null) { Cooks.Add(httpWebResponse.Cookies); } return httpWebResponse; } catch (WebException ex) { return ex.Response as HttpWebResponse; } } } Класс содержит CookieCollection и 2 функции возвращающие HttpWebResponse: Одна с POST запросом, вторая без. Так же для автоматического распознования понадобится класс работы с antigate. Отдельное спасибо elw. Code: class anticaptcha { public bool debug = false; public string host = "antigate.com"; public string key; public string proxy = ""; public string proxy_username = ""; public string proxy_password = ""; public int phrase = 0; // у капчи 2-4 слова = 1 public int regsense = 0; // текст капчи чувствителен к регистру = 1 public int numeric = 0; // капча состоит только с цифр = 1, // на капче нет цифр = 2 public int calc = 0; // цифры на капче должны быть сплюсованы = 1 public int min_len = 0; // минимальная длину текста капчи public int max_len = 0; // максимальная длина текста капчи private string proxy_host = ""; private int proxy_port; private string result_headers; private string result_page; private HttpWebRequest ua; private string last_cap_id; public string rec(string filename) { ua = browser("http://" + host + "/in.php"); ua.Method = "POST"; string ext = "pjpeg"; try { ext = new Regex(@"^.+?\.(\w+)$").Match(filename).Groups[1].Value; } catch {} string sBoundary = DateTime.Now.Ticks.ToString("x"); ua.ContentType = "multipart/form-data; boundary=" + sBoundary; string sPostMultiString = ""; sPostMultiString += MultiFormData("method", "post", sBoundary); sPostMultiString += MultiFormData("key", this.key, sBoundary); sPostMultiString += MultiFormData("soft_id", "65", sBoundary); sPostMultiString += MultiFormData("file", filename, sBoundary); sPostMultiString += MultiFormData("phrase", Convert.ToString(phrase), sBoundary); sPostMultiString += MultiFormData("regsense", Convert.ToString(regsense), sBoundary); sPostMultiString += MultiFormData("numeric", Convert.ToString(numeric), sBoundary); sPostMultiString += MultiFormData("calc", Convert.ToString(calc), sBoundary); sPostMultiString += MultiFormData("min_len", Convert.ToString(min_len), sBoundary); sPostMultiString += MultiFormData("max_len", Convert.ToString(max_len), sBoundary); string sFileContent = ""; using (BinaryReader br = new BinaryReader(File.Open(filename, FileMode.Open), Encoding.Default)) { byte[] ba = new byte[32768]; int pos = 0; byte b; while (true) { try { b = br.ReadByte(); } catch (EndOfStreamException ex) { break; } ba[pos] = b; pos++; } byte[] ba2 = new byte[pos]; for (int k = 0; k < pos; k++) { ba2[k] = ba[k]; } sFileContent = Encoding.Default.GetString(ba2); } sPostMultiString += MultiFormDataFile("file", sFileContent, filename, "image/" + ext, sBoundary); sPostMultiString += "--" + sBoundary + "--\r\n\r\n"; byte[] byteArray = Encoding.Default.GetBytes(sPostMultiString); ua.ContentLength = byteArray.Length; ua.GetRequestStream().Write(byteArray, 0, byteArray.Length); try { HttpWebResponse myHttpWebResponse = (HttpWebResponse)ua.GetResponse(); StreamReader myStreamReadermy = new StreamReader(myHttpWebResponse.GetResponseStream(), Encoding.GetEncoding(1251)); result_page = myStreamReadermy.ReadToEnd(); //result_headers = myHttpWebResponse.Headers.ToString(); string[] result = result_page.Split(new char[1] { '|' }); last_cap_id = result[1]; dbg("req " + last_cap_id + ": uploaded!"); while (1 == 1) { string captcha = get(last_cap_id); if (captcha == "") { Thread.Sleep(2000); } else { return captcha; } } } catch (WebException ex) { //Console.WriteLine(ex); return ""; } } public string get(string cap_id) { if (this.req("http://" + host + "/res.php?key=" + key + "&action=get&id=" + cap_id + "&")) { dbg("get " + cap_id + " : " + result_page); try { string[] result = result_page.Split(new char[1] { '|' }); dbg("recorgenized " + cap_id + " : " + result[1]); return result[1]; } catch { return ""; } } return ""; } public string get_balance() { string key = this.key; return get_balance(key); } public string get_balance(string key) { if (this.req("http://" + host + "/res.php?key=" + key + "&action=getbalance")) { dbg("get_balance: " + result_page); return result_page; } return "-1"; } public bool reportbad() { return reportbad(last_cap_id); } public bool reportbad(string cap_id) { if (this.req("http://" + host + "/res.php?key=" + key + "&action=reportbad&id=" + cap_id)) { dbg("reportbad " + cap_id + ": " + result_page); if (result_page.IndexOf("ERROR") >= 0) { return false; } return true; } return false; } public void dbg(string s) { if (this.debug == true) { Console.WriteLine("AC: " + s); } } private bool req(string url) { ua = browser(url); ua.Method = "GET"; ua.KeepAlive = true; try { HttpWebResponse myHttpWebResponse = (HttpWebResponse)ua.GetResponse(); StreamReader myStreamReadermy = new StreamReader(myHttpWebResponse.GetResponseStream(), Encoding.GetEncoding(1251)); result_page = myStreamReadermy.ReadToEnd(); result_headers = myHttpWebResponse.Headers.ToString(); return true; } catch (WebException ex) { //Console.WriteLine(ex); return false; } } private HttpWebRequest browser(string url) { HttpWebRequest ua = (HttpWebRequest)System.Net.WebRequest.Create(url); if (use_proxy()) { WebProxy myProxy = new WebProxy(proxy_host, proxy_port); myProxy.Credentials = new NetworkCredential(proxy_username, proxy_password); ua.Proxy = myProxy; } ua.AllowAutoRedirect = true; ua.Timeout = 10000; ua.UserAgent = "C# Anticaptcha Class (elw)"; ua.Accept = "*/*"; return ua; } private bool use_proxy() { if (String.IsNullOrEmpty(proxy)) { return false; } string[] aProxy = proxy.Split(new char[1] { ':' }); proxy_host = aProxy[0]; proxy_port = int.Parse(aProxy[1]); return true; } public static string MultiFormData(string Key, string Value, string Boundary) { string output = "--" + Boundary + "\r\n"; output += "Content-Disposition: form-data; name=\"" + Key + "\"\r\n\r\n"; output += Value + "\r\n"; return output; } public static string MultiFormDataFile(string Key, string Value, string FileName, string FileType, string Boundary) { string output = "--" + Boundary + "\r\n"; output += "Content-Disposition: form-data; name=\"" + Key + "\"; filename=\"" + FileName + "\"\r\n"; output += "Content-Type: " + FileType + " \r\n\r\n"; output += Value + "\r\n"; return output; } } /* пример использования /* using System.Threading; using System.Net; using System.IO; using System.Text.RegularExpressions; .............. anticaptcha ac = new anticaptcha(); ac.host = "antigate.com"; ac.key = "dd5c63473..ваш.ключ..b67d96b3754a"; // проверяем баланс string balance = ac.get_balance(); Console.WriteLine("current balance = " + balance); // отправляем капчу string cap = ac.rec("some_captcha.jpg"); // можем отправить жалобу, если капча роспозналась неверно ac.reportbad(); .............. /* */ Далее мы запускаем http analyzer и смотрим на то, что и каким образом принимается qip.ru для регистрации Code: NO. Starred OffSet Timeline Duration(s) Method Result Received Type URL RedirectURL 50 False + 0,078 0,595 s POST 200 20,34 K text/html http://www.qip.ru/reg/register 51 False + 0,781 0,501 s GET 200 1,41 K text/javascript http://api.recaptcha.net/challenge?k=6LeUWwgAAAAAAMHS93Je_FMHwGu30Z3T-hrqsCiO 52 False + 0,797 0,204 s GET 407 4,47 K text/html http://count.rbc.ru/p787.gif?r=http%3A//www.qip.ru/reg/register&width=1229&height=983&hash=&rf=http%3A//www.qip.ru/reg/register&rn=0.9010899220605391 53 False + 0,812 0,205 s GET 407 4,47 K text/html http://www.tns-counter.ru/V13a***R%3Ehttp://www.qip.ru/reg/register*rbc_ru/ru/UTF-8/tmsec=rbc_qip/ 56 False + 1,016 0,001 s GET 407 560 text/html http://count.rbc.ru/p787.gif?r=http%3A//www.qip.ru/reg/register&width=1229&height=983&hash=&rf=http%3A//www.qip.ru/reg/register&rn=0.9010899220605391 57 False + 1,031 0,001 s GET 407 560 text/html http://www.tns-counter.ru/V13a***R%3Ehttp://www.qip.ru/reg/register*rbc_ru/ru/UTF-8/tmsec=rbc_qip/ 58 False + 1,031 0,017 s GET 200 352 image/gif http://count.rbc.ru/p787.gif?r=http%3A//www.qip.ru/reg/register&width=1229&height=983&hash=&rf=http%3A//www.qip.ru/reg/register&rn=0.9010899220605391 59 False + 1,047 0,032 s GET 200 494 image/gif http://www.tns-counter.ru/V13a***R%3Ehttp://www.qip.ru/reg/register*rbc_ru/ru/UTF-8/tmsec=rbc_qip/ 60 False + 0,828 0,282 s GET 407 4,47 K text/html http://counter.yadro.ru/hit;start-qip-ru?rhttp%3A//www.qip.ru/reg/register;s1229*983*32;uhttp%3A//www.qip.ru/reg/register;0.8095833998461599 61 False + 1,125 0,017 s GET 200 319 image/gif http://counter.yadro.ru/hit;start-qip-ru?rhttp%3A//www.qip.ru/reg/register;s1229*983*32;uhttp%3A//www.qip.ru/reg/register;0.8095833998461599 62 False + 1,312 0,330 s GET 200 657 text/javascript http://www.google.com/recaptcha/api/challenge?k=6LeUWwgAAAAAAMHS93Je_FMHwGu30Z3T-hrqsCiO&darklaunch=1 63 False + 1,328 0,329 s GET 407 4,47 K text/html http://api.recaptcha.net/image?c=02J47UfMZX6cCuvACiI6SfKDWh4wWwrLm6MGvOWtk_qSs2i0sxYHTPESrR73yZ70m7zcUYsxgSN0b6LKKu3PsCbcuQ7j39YETh-8Cc2CY9d4S-MhroSbHiLEs1DFjQ1PmC_iP6WUodiFJ6iUVJRW_UmqCbcRI8i7VF1vWzgc3mCpAgAqZxbh97zSQR6EBWXtUWgRQ-PesnrZy5Gr21by4jzpQRsASE6oKkDajIT3hlT2o1pETFKYjmBXtQLcG_dXby-yBWF5hXfQnwKvV5cyLJDBNcrxIB 64 False + 1,328 0,032 s GET 200 278 image/gif http://counter.rambler.ru/top100.cnt?1185528 65 False + 1,578 0,048 s GET 200 396 image/gif http://counter.yadro.ru/logo?26.1 66 False + 1,672 0,532 s GET 200 3,25 K image/jpeg http://api.recaptcha.net/image?c=02J47UfMZX6cCuvACiI6SfKDWh4wWwrLm6MGvOWtk_qSs2i0sxYHTPESrR73yZ70m7zcUYsxgSN0b6LKKu3PsCbcuQ7j39YETh-8Cc2CY9d4S-MhroSbHiLEs1DFjQ1PmC_iP6WUodiFJ6iUVJRW_UmqCbcRI8i7VF1vWzgc3mCpAgAqZxbh97zSQR6EBWXtUWgRQ-PesnrZy5Gr21by4jzpQRsASE6oKkDajIT3hlT2o1pETFKYjmBXtQLcG_dXby-yBWF5hXfQnwKvV5cyLJDBNcrxIB 67 False + 1,625 0,329 s GET 407 4,47 K text/html http://rbcgaru.hit.gemius.pl/_1270623070349/rexdot.gif?l=30&id=AjtLm6urvIF2uTw7.v8m36Pe33MGxnsw3wib9RJAMRP.R7&fr=1&fv=WIN%2010%2C0%2C45%2C2&tz=-240&href=http%3A//www.qip.ru/reg/register&ref=http%3A//www.qip.ru/reg/register&screen=1229x983&col=32 70 False + 1,734 0,236 s GET 407 4,47 K text/html http://www.google.com/recaptcha/api/image?c=03AHJ_VusxISEkjwxVAPKICmaPBPTTxmkYI9ZWLen9uOQUMX-uwn0kJiY1Ub3wUO7zPYoXGLBLYOxf5-aGp-lb9ErW69GEbbGkjx6Y0zRErTJKkbieEgTyc_IVybSZXyaP39VrUx0WPxk_8INAvYeXpw9uhjt7ynBcAw 73 False + 1,969 0,032 s GET 200 516 image/gif http://rbcgaru.hit.gemius.pl/_1270623070349/rexdot.gif?l=30&id=AjtLm6urvIF2uTw7.v8m36Pe33MGxnsw3wib9RJAMRP.R7&fr=1&fv=WIN%2010%2C0%2C45%2C2&tz=-240&href=http%3A//www.qip.ru/reg/register&ref=http%3A//www.qip.ru/reg/register&screen=1229x983&col=32 74 False + 1,984 0,033 s GET 407 560 text/html http://www.google.com/recaptcha/api/image?c=03AHJ_VusxISEkjwxVAPKICmaPBPTTxmkYI9ZWLen9uOQUMX-uwn0kJiY1Ub3wUO7zPYoXGLBLYOxf5-aGp-lb9ErW69GEbbGkjx6Y0zRErTJKkbieEgTyc_IVybSZXyaP39VrUx0WPxk_8INAvYeXpw9uhjt7ynBcAw 75 False + 2,016 0,188 s GET 200 3,26 K image/jpeg http://www.google.com/recaptcha/api/image?c=03AHJ_VusxISEkjwxVAPKICmaPBPTTxmkYI9ZWLen9uOQUMX-uwn0kJiY1Ub3wUO7zPYoXGLBLYOxf5-aGp-lb9ErW69GEbbGkjx6Y0zRErTJKkbieEgTyc_IVybSZXyaP39VrUx0WPxk_8INAvYeXpw9uhjt7ynBcAw И что уходит после нажатия кнопки «регистрация» Code: Parameter Name Value username asdasdasd reg_host 0 pwd asdasdasd pwd2 asdasdasd email [email protected] quest 0 reg_quest reg_answer last_name first_name middle_name bday 0 bmonth 0 byear 0 city recaptcha_challenge_field 02NblAb1JGCfoIu1AhL-aqceKDN61Q9_rAeEFSufpyzd910MuEgb8qkMaNmcsFGiZSkYqAvYr4e1JlP3-IVyymHH940SoBuIOBa6Fzpjw5ZMQ7E8pNQy0tFvOxMozVPBFQxqwxOxWFu-_n27cLcWn3yAh1J09wJfyPWgzexcm80WjsD-nmRGZsM1s_XZTNSy5JosHTtgIvVWUFHiPW3fYh3NVwUu2C3RhsyGlzU6lI-mTpUZ6ZxdtPIjnJ5Qe0WpfBuXzGl4YC0VMoChh913dr31n_A_EB recaptcha_response_field presbrey nations Теперь понятно что нужно отправить поэтому приступим к коду. Code: string sHTML = ""; string recaptcha_challenge_field = ""; string cap = ""; HTTPClient client = new HTTPClient("session"); HttpWebResponse httpWebResponse = client.Request("http://www.qip.ru/reg/register",false); if (httpWebResponse != null && httpWebResponse.StatusCode == HttpStatusCode.OK) { Stream stream = httpWebResponse.GetResponseStream(); using (StreamReader reader = new StreamReader(stream, System.Text.Encoding.UTF8)) { sHTML = reader.ReadToEnd(); } // Получаем ID Капчи httpWebResponse = client.Request("http://api.recaptcha.net/noscript?k=6LeUWwgAAAAAAMHS93Je_FMHwGu30Z3T-hrqsCiO"); if (httpWebResponse != null && httpWebResponse.StatusCode == HttpStatusCode.OK) { stream = httpWebResponse.GetResponseStream(); using (StreamReader reader = new StreamReader(stream, System.Text.Encoding.UTF8)) { sHTML = reader.ReadToEnd(); } string pattern = "(\\s)"; string capcha_id = @"(?<=recaptcha_challenge_field"+'"'+" value="+'"'+")(\\S+)(?="+'"'+")"; Regex rx = new Regex(capcha_id); recaptcha_challenge_field = rx.Match(sHTML).Value; } // Получаем Картинку httpWebResponse = client.Request("http://api.recaptcha.net/image?c=" + recaptcha_challenge_field); if (httpWebResponse != null && httpWebResponse.StatusCode == HttpStatusCode.OK) { stream = httpWebResponse.GetResponseStream(); Bitmap b = new Bitmap(stream); b.Save("some_captcha.jpg", System.Drawing.Imaging.ImageFormat.Jpeg); using (StreamReader reader = new StreamReader(stream, System.Text.Encoding.UTF8)) { sHTML = reader.ReadToEnd(); } anticaptcha ac = new anticaptcha(); ac.host = "antigate.com"; ac.key = "ваш ключ на antigate"; ac.proxy = "x.x.x.x:3128"; ac.proxy_username = "username"; ac.proxy_password = "password"; //ac. // проверяем баланс string balance = ac.get_balance(); CultureInfo ciClone = null; ciClone = (CultureInfo)CultureInfo.InvariantCulture.Clone(); ciClone.NumberFormat.NumberDecimalSeparator = "."; ciClone.NumberFormat.NumberGroupSeparator = ","; if(Double.Parse(balance,ciClone) > 0){ // отправляем капчу cap = ac.rec("some_captcha.jpg"); } // можем отправить жалобу, если капча роспозналась неверно //ac.reportbad(); } Regex rx2 = new Regex("(\\s)"); cap = rx2.Replace(cap, "+"); string post_reg = @"bday=0&" + "bmonth=0&" + "byear=0&" + "city=&" + "[email protected]&" + "first_name=&" + "last_name&" + "middle_name&" + "pwd=asdasdasd&" + "pwd2=asdasdasd&" + "quest=0&" + "recaptcha_challenge_field="+recaptcha_challenge_field+"&" + "recaptcha_response_field="+cap+"&" + "reg_answer=&" + "reg_host=0&" + "reg_quest=&" + "username=asdasdasd1234"; httpWebResponse.Close(); httpWebResponse = client.Request_Post("http://www.qip.ru/reg/register", post_reg); if (httpWebResponse != null && httpWebResponse.StatusCode == HttpStatusCode.OK) { stream = httpWebResponse.GetResponseStream(); using (StreamReader reader = new StreamReader(stream, System.Text.Encoding.UTF8)) { sHTML = reader.ReadToEnd(); } } } Вообщем то все. Осталось добавить многопоточность и всем удачи Замечания и предложения приветствуются.
Я так понимаю что статья по мнению некоторых здесь присутствующих это "Как спиздить миллион и не залететь"
удобочитаемасть кода не ахти) последний метод неплохо было бы разбить на несколько и, вообще оформить, в виде одного класса методы для работы с регистрацией... а так идея ничаво)
класс для работы с http Code: много кода класс для работы с antigate Code: много чужого кода смотрим что принимает и отправляет http analyzer Code: и здесь ещё немного кода и это ты называешь статьёй?!
Те кто говорил что это не статья здесь больше чем достаточно чтобы написать автоматический регистратор не только для qip.ru а в принцепе почти для любого сайта Так что извините за мат ХАРЕ Пизд*ть а лучше сами что то талкового напишите
to люди, которые выебываются, говоря, что "а попробуйте сами напишите" Я не говорю, что я мего писатель статей, но это уж извините не статья. Это просто код, который дописав можно было бы выложить в халяве. Не имея этого примера можно понять что к чему, а новечок не поймет ничего. Чтобы была статья, можно добавить: коммента к каждой строчке кода, объяснения зачем каждый метод, дописать многопоточность и т.д...