В образовательных целях решил написать примитивную голосовалку для l2top.ru_ Вооружившись Delphi7, HTTPAnalyzer'oм и гуглом приступил... Дошел до следующего: получаю страничку и куки (на счет кук - не уверен ) Code: procedure TForm1.Button1Click(Sender: TObject); var ID: String; begin ID:=edit1.text; idhttp1:= TIdHTTP.Create(nil); IdCookieManager1 := TidCookieManager.Create(idHttp1); idHttp1.AllowCookies := true; idHttp1.CookieManager := IdCookieManager1; IdHTTP1.HandleRedirects:=True; idhttp1.Request.Host:='l2top'; idhttp1.Request.Accept:='text/html,*/*'; idhttp1.Request.AcceptCharSet:='windows-1251,utf-8;q=0.7,*;q=0.7'; idhttp1.Request.AcceptLanguage:='ru,en-us;q=0.7,en;q=0.3'; idhttp1.Request.UserAgent:='Mozilla/5.0 (Windows; U; Windows NT 6.1; ru; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7'; idhttp1.Request.Connection:='keep-alive'; //получили страничку и кукисы c1:=idhttp1.Get('http://l2top.ru/vote/'+ID+'/'); memo1.Text:=c1; memo1.Lines.SaveToFile('html/'+ID+'.html'); end; получаю капчу Code: procedure TForm1.BitBtn1Click(Sender: TObject); begin ID:=edit1.text; pref:= edit2.Text; captcha1:=TMemoryStream.Create; captcha2:=TMemoryStream.Create; rnd1:=random(100)+1; rnd2:=random(500)+100; idhttp1.Get('http://l2top.ru/getimg.php?'+IntToStr(rnd1),captcha1); idhttp1.Get('http://l2top.ru/getimg.php?'+IntToStr(rnd2),captcha2); captcha1.SaveToStream(captcha1); captcha1.SaveTofile('img/captcha1.jpg'); Image1.Picture.LoadFromfile('img/captcha1.jpg'); captcha2.SaveToStream(captcha2); captcha2.SaveTofile('img/captcha2.jpg'); Image2.Picture.LoadFromfile('img/captcha2.jpg'); end; из полученой странички (первый кусок кода) извлекаю sec_referer и идентификатор(возможно, не правильно выразился) поля для ввода капчи Code: procedure TForm1.Button3Click(Sender: TObject); begin sec_referer:=idhttp1.Get(edit3.Text); Delete(c1, Pos('<!DOCTYPE', c1), Pos('//--><input name=', c1)+ 17); c1:=Copy(c1, 0, 0 +8); memo2.Text:=c1; //sec_referer Delete(sec_referer, Pos('<!DOCTYPE', sec_referer), Pos('sec_referer', sec_referer)+19); Delete(sec_referer, Pos('<table border=0>', sec_referer), Length(sec_referer)); Delete(sec_referer, Pos('>', sec_referer) -1, Length(sec_referer)-1); memo3.text:=sec_referer; //подготовка данных data:=TStringList.Create; data.Add('referer=http://l2top.ru/'); data.Add('sec_referer='+ sec_referer); data.Add('voteOk=ok'); data.Add(c1+'=' + edit5.Text); //капча data.Add('name='+ edit4.Text); //ник персонажа //отправка post'a post:=idHttp1.Post('http://l2top.ru/vote/'+ID+'/', data); memo1.Lines.Text:=post; memo1.Lines.SaveToFile('html/posted.html'); end; На выходе получаю posted.html, т.е. ту страничку, которую мы увидим после ввода капчи и ника. Просматриваю ее и вижу - "Неправильная строка с картинки". Понял, что неправильно получаю капчу - поскольку она у меня никак не привязана к текущей сессии, а просто в тупую получаю картинку. Так же, подозреваю, что у меня проблемы с куками (не очень понял как правильно с ними работать). К тому же html'ка, созданная первой кнопкой содержит надпись "Внимание!<br>У Вас выключена поддержка cookies, Вы не сможете воспользоваться этой функцией." Вопрос: как правильно в данном случае получить капчу и отправить POST запрос?) P.S. Время от времени POST вообще не отсылается, получаю 503 ошибку и выделение этой строки - "post:=idHttp1.Post('http://l2top.ru/vote/'+ID+'/', data);"
зря стараешься, как я помню нет смысла в автонакрутке на л2топ, т.к. там сначала записываются куки, голосование не учитывается, и повторно голосовать можно будет только через 24 часа... не стОит оно того.
Стараться никогда не зря: в любом случае - опыт пригодится. К тому же, люди продают вполне рабочие накрутчики для л2топ. Да и вообще, мне не нужно какую-то мегонакрутку написать, а примитивную голосовалку, что бы разобраться с куками и прочим.
ID капчи нужно парсить с html кода страницы регистрации а не просто рандомно ставить. там ведь их 2 картинки и айди прописываются в куки как и на любом другом сайте.
Вот форма ввода капчи на странице голосования: Code: <form action='/vote/7348/' id='voteFrom' method='post'> <input type='hidden' name='referer' value='?'> <input type='hidden' name='sec_referer' value='4b30c013d9042c579ca3f67b0980132c0568ae8b'> <table border=0> <tr> <td colspan=2 align='left' style='padding-left: 40px;'> <script type='text/javaScript'> function voteButtnRef(scr, n) { document.getElementById(scr).innerHTML = ''; document.getElementById(scr).innerHTML += "<img src='/getimg.php?"+Math.random()+"' alt='Для просмотра включите отображение картинок' border=0>" document.getElementById(scr).innerHTML += "<img src='/4na.php?"+Math.random()+"' alt='Для просмотра включите отображение картинок' border=0>"; } </script> <span id='kapchaImg'> <img src='/getimg.php?666' alt='Для просмотра включите отображение картинок' border=0> <img src='/vdcp.php?666' alt='Для просмотра включите отображение картинок' border=0> <script type='text/javaScript'> document.write("<img style='position: relative; left: -105px' src='/4na.php?"+Math.random()+"' alt='Для просмотра включите отображение картинок' border=0>"); document.write("<img style='position: relative; left: -205px' src='/4nb.php?"+Math.random()+"' alt='Для просмотра включите отображение картинок' border=0>"); </script> </span><br> <a href='javascript:voteButtnRef("kapchaImg","");'>не видна картинка?</a> </td> </tr> <tr> <td> введите значение с картинок через пробел:<br> <input name='voteOk' type='hidden' value='ok'> <!--// <input name='69c7fbdd' type='text' value='' class='num2' maxlength='14'> //--><!--// <input name='7e16f194' type='text' value='' class='num2' maxlength='14'> //--><!--// <input name='4d849268' type='text' value='' class='num2' maxlength='14'> //--><!--// <input name='e34f7fe2' type='text' value='' class='num2' maxlength='14'> //--><!--// <input name='84c9f186' type='text' value='' class='num2' maxlength='14'> //--><!--// <input name='00ab44cd' type='text' value='' class='num2' maxlength='14'> //--><!--// <input name='0cc0b5b4' type='text' value='' class='num2' maxlength='14'> //--><input name='4044fd0f' type='text' value='' class='num2' maxlength='14'><!--// <input name='a0a0a7bc' type='text' value='' class='num2' maxlength='14'> //--><!--// <input name='c9c08593' type='text' value='' class='num2' maxlength='14'> //--> </td> <td width=90px> <a href='#' onClick='document.getElementById("voteFrom").submit(); return false;'><img src='/images/vote2.gif' alt='Проголосовать'></a> </td> </tr> <tr> <td>имя Вашего персонажа в игре*:<br><input name='name' type='text' value='' class='num2' maxlength=20></td> <td></td> </tr> </table> <p> *Вы можете оставить это поле пустым если не хотите, чтобы данная информация была опубликована в статистике голосования за сервер. ВНИМАНИЕ: не вводите, пожалуйста, вместо имени чара бессмысленный набор символов, в противном случае наш рейтинг оставляет за собой право не учитывать подобные голоса и не показывать их в статистике голосования за сервер. </p> </form> Но... Получение капчи тут видно только в 1 месте: Code: <img src='/getimg.php?666' alt='Для просмотра включите отображение картинок' border=0> <img src='/vdcp.php?666' alt='Для просмотра включите отображение картинок' border=0> getimg.php?666 - это одна капча.... А где же вторая? (vdcp.php?666 - выдает пустую белую картинку)
Вторая, на сколько я теперь понял, это: Code: <script type='text/javaScript'> function voteButtnRef(scr, n) { document.getElementById(scr).innerHTML = ''; document.getElementById(scr).innerHTML += "<img src='/getimg.php?"+Math.random()+"' alt='Для просмотра включите отображение картинок' border=0>" document.getElementById(scr).innerHTML += "<img src='/4na.php?"+Math.random()+"' alt='Для просмотра включите отображение картинок' border=0>"; } </script> Но в чем связь между капчей и страницей? Т.е. как определяется, что к этой странице привязана именно эта капча - по кукам? Вот поснифал аналогичную прогу - получил такое при запросе страницы: _http://img576.imageshack.us/i/71933973.jpg/ _http://img97.imageshack.us/i/81312258.jpg/ _http://img412.imageshack.us/i/98376925.jpg/ _http://img714.imageshack.us/i/36390183.jpg/ Могу предположить, что связь заложена в куки l2x=bla-bla-bla - так ли это? Если так, то мне нужно выцепить этот куки с хедера при запросе страницы и добавить в хедер при запрашивании капчи?
Ах да - и как избавиться от злосчастной надписи "Внимание! У Вас выключена поддержка cookies, Вы не сможете воспользоваться этой функцией.".... IdCookieManager связан с IdHTTP... В чем может быть проблема?
В том, что инди эти куки не сохраняет. Тут 2 варианта - обновить инди или парсить куки и вручную добавлять в запрос.
Добавил в первую кнопку парс куков: Code: idhttp1.Request.RawHeaders.SaveToFile('cookies/request.txt'); idhttp1.Response.RawHeaders.SaveToFile('cookies/response.txt'); cook1:=idhttp1.Response.RawHeaders.Text; Delete(cook1, Pos('Server:', cook1), Pos('l2x=', cook1)-1); cook1:=Copy(cook1, 0, 0 +45); memo4.Text:=cook1; Потом передаю эту куки (l2x=bla-bla-bla) при запросе капчи: Code: idhttp1.Request.CustomHeaders.Text:='Cookie:'+cook1+' amn=1;test_cookie=1'; idhttp1.Get('http://l2top.ru/getimg.php?'+IntToStr(rnd1),captcha1); idhttp1.Get('http://l2top.ru/getimg.php?'+IntToStr(rnd2),captcha2); И в результате все равно получаю "Неправильный ввод капчи"....
Полагаю, что дело совсем в другом (возможно, ошибаюсь), поскольку: проснифал аналогичную программу и увидел, что запрос капчи идет на getimg.php?97, но при этом в сохраненной странице id иной - getimg.php?181 При этом, вторая капча берется (судя по этой проге) с 4nb.php?число... Но на самой странице это "число" вообще не фигурирует - там оно добывается math.random(). upd. Все таки решил последовать совету и спарсил ID капчи: Code: Delete(capID1, Pos('<!DOCTYPE', capID1), Pos('<span id=', capID1)+76); capID1:=Copy(capID1, 0, 3); В конечном результате получил все тоже - "неправильная строка с картинки". Решил просмотреть всю работу с самого начала - возможно, я не правильно передаю куки при запросе капчи? Вот так я это сделал - верно ли это?.. Code: idhttp1.Request.CustomHeaders.Text:='Cookie: '+cook1+' amn=1;test_cookie=1'; idhttp1.Get('http://l2top.ru/getimg.php?'+capID1,captcha1); idhttp1.Get('http://l2top.ru/vdcp.php?'+capID1,captcha3); idhttp1.Get('http://l2top.ru/4nb.php?'+FloatToStr(rnd3),captcha2); cook1 тут - это куки полученный при запросе страницы с голосованием Code: cook1:=idhttp1.Response.RawHeaders.Text; Delete(cook1, Pos('Server:', cook1), Pos('l2x=', cook1)-1); cook1:=Copy(cook1, 0, 0 +45); memo4.Text:=cook1;
Возможно, проблема в следующем... Проанализировав отснифанные хедеры увидел, что при работе браузера передаются куки такого вида: Code: Cookie: l2x=92d83fed59b7378b496657dd863c82386d6bd229; amm=1; test_cookie=1 У меня же (при просмотре снифером) они выглядят так: Code: Cookie:amm=1; l2x=0370996efae9c409767cd1e1462eb9d461010629 Хотя в программе куки передаю так: Code: idhttp1.Request.CustomHeaders.Text:='Cookie:'+cook1+' amm=1;test_cookie=1'; Где cook1 есть строка вида l2x=0370996efae9c409767cd1e1462eb9d461010629; Существенна ли разница в этих 2х куках (отсутствие test_cookie и различный порядок записи)? *upd. Уже выбился из сил - не могу понять в чем проблема: все та же надпись - "Неправильная строка с картинки"... Вроде все верно делаю: запрашиваю страницу, выцепляю куки и id капчи, со всем этим запрашиваю саму капчу, отправляю post запрос - и получаю хрень... *upd2. POST у меня такого вида: Code: data:=TStringList.Create; data.Add('referer=http://l2top.ru'); data.Add('sec_referer='+ sec_referer); data.Add('voteOk=ok'); data.Add(c1+'=' + edit5.Text); data.Add('name='+ edit4.Text); post:=idHttp1.Post('http://l2top.ru/vote/'+ID+'/', data); memo1.Lines.Text:=post; memo1.Lines.SaveToFile('html/posted.html');
В пост запросе должен быть знак "+" межту текстами капч. Посмотри в снифере на свой запрос если он там...
Такс, с этим проблема решена (фух, наконец-то) Все оказалось банально просто... В обработчике кнопки, которая в результате отошлет POST, в самом начале стоял GET запрос страницы голосования, который все портил (поскольку GET уже посылался в самом начале и с полученной страницы парсились ID капчи, а с хедера парсились куки). Вот он, злополучный кусочек: было - Code: procedure TForm1.Button3Click(Sender: TObject); begin sec_referer:=idhttp1.Get(edit3.Text); стало - Code: procedure TForm1.Button3Click(Sender: TObject); begin sec_referer:=c1; Темку пока не закрывайте, продолжу тут писанину о голосовалке для l2top - может кому-то да и пригодится.
Не, обе капчи я ввожу в 1 edit через пробел, так что с этим все в порядке. Ошибку описал в посте выше.