Собственно, делаю автозаполнитель для одного сайта. Там есть recaptcha, которую надо обойти. Приблизительно я знаю как: взять любую рекапчу, решить ее и выдрать Challenge id, затем как-то подменить этот самый challenge id на сайте и ввести уже заранее подготовленный ответ. Но как осуществить эту подмену? P.S. делаю программу на делфи.
использовать поиск по форуму. Недавно во всех подробностях рассматривали. Сцылко на тему: Я ТУТ!! откуда берется 6LegWAEAAAAAANJcmtbLTuHlG7AbDzLPxvimCw_Z это API ключ для твоего сайта (в данном случае для ЖЖ) ищется он в исходниках страницы P.S. и совет на счет "юзай сниффер" остается в силе и для тебя
сниффером нашел это поле: Code: <input name="recaptcha_challenge_field" id="recaptcha_challenge_field" value="03AHJ_Vuu4V042dWy73RsqRs8wLNadtM9vhPvMYVnKyISSKIaaR_pAwMi6OkK3GKOhx3CveNmKx2wKnZ_eqj2w4-mBHekberjRHq1VlXvZ2jtoZeqo-rkOrMDznyfjlPLqNxgno7nOe7zI_OrjkoujJY4cbSBpt28QMw" type="hidden"> мне именно надо узнать, как поменять value этого поля на свое, а это подробно не расписано в той теме:
Эм... ну с этого и нужно было начинать, а зачем тебе его подменять тогда, если ты из TWebBrowser можешь картинку выдрать и не лезть в это поле? Но, раз хочешь именно менять его, ща найду примерчик. Только учти, что одну и ту же recapch'у много раз юзать не получится Code: procedure SetFieldValue(WebBrowser:TWebBrowser; //установить значение поля, по его имени const fieldName: string; const newValue: string;var loaded:boolean; var result:boolean; const instance: integer=0); var field: IHTMLElement; inputField: IHTMLInputElement; selectField: IHTMLSelectElement; textField: IHTMLTextAreaElement; submitField: IHTMLButtonElement; HtmlCollection: IHtmlElementCollection; HtmlDocument,Document: IHtmlDocument2; HtmlElement: IHtmlElement; i,j:integer; theForm: IHTMLFormElement; ovElements: OleVariant; a:boolean; s:string; begin result:=false; document := WebBrowser.Document as IHTMLDocument2; for j:=0 to NumberOfForms(document)-1 do begin theForm := GetFormByNumber(WebBrowser.Document as IHTMLDocument2,j); field := theForm.Item(fieldName,instance) as IHTMLElement; if Assigned(field) then begin begin if field.tagName = 'INPUT' then //Если тип элемента 'Input' и begin inputField := field as IHTMLInputElement; if (inputField.type_ = 'button') then //и тип Баттон begin result:=true; field.click; //то кликнуть exit; end; if (inputField.type_ = 'submit') then // и тип сабмит begin result:=true; field.click; //то кликнуть exit; end else if (inputField.type_ <> 'radio') and //и тип радио (inputField.type_ <> 'checkbox') //или тип чекбокс then begin result:=true; inputField.value := newValue; exit; end else begin result:=true; inputField.checked :=newValue = 'checked'; //то "отметить" exit; end; end else if field.tagName = 'SELECT' then //тип селект begin result:=true; selectField := field as IHTMLSelectElement; selectField.value := newValue; //то выбрать NewValue exit; end else if field.tagName = 'TEXTAREA' then //если текстериа, то begin result:=true; textField := field as IHTMLTextAreaElement; textField.value :=textField.value+chr(13)+chr(10)+ newValue; //добавить строку exit; end; end; end else //если тип элемента не 'Input' begin HtmlDocument := Webbrowser.document as IHtmlDocument2; HtmlCollection := HtmlDocument.All; HtmlCollection := HtmlCollection.Tags('A') as IHTMLElementCollection; for I := 0 to HtmlCollection.Length - 1 do begin HtmlElement := HtmlCollection.Item(i, 0) as IHtmlElement; s:=HtmlElement.InnerText; if UpperCase(s) = upperCase(fieldName) then //то пытаемся найти ссылку с таким текстом begin result:=true; HtmlElement.click; //и кликаем по ней exit; end; end; end; end; end; посмотри, это пытался сделать универсальную процедуру для заполнения полей. Может говнокод. Было давно, и сейчас разбираться некогда (ползунок вправо сдвинь - там комментарии кое-какие есть).
А какой смысл в подмене? Если на стороне сайта проверка не пройдет. потому что используются 2 ключа - открытый (в коде страницы) и закрытый который на сайте находиться (в php скриптах (ну или в тех на чем написан сайт)).
slesh, у меня сейчас заработало xophet, крайне благодарен за такую интересную процедурку. и радиобатоны, и чекбоксы, и селекты...
Не,не хранится в скриптах: recaptcha_challenge_field присваевается после выполнения java-скрипта (т.е. на стороне браузера). Скрипт выполняясь делает запрос на гугл используя api-key, получает значение recaptcha_challenge_field и присываевает его соотв. полю, и подгружая картинку показывает ее нам. А потом уже мы отправляем recaptcha_challenge_field и свой ответ сайту, а сайт делает запрос гуглу на предмет совпадания ecaptcha_challenge_field и ответа и если совпадает, то разрешает регистрацию. (Надеюсь понятно объяснил...) Не за что (эт у меня такой автопостер был ). Но я лично в TWebBrowser'e разочаровался, так что если проект какой-то серьезный, и без браузера не обойтись, то я бы смотрел в сторону Gecko.
пример работы с рекапчей Code: using System.Net.Sockets; using System.Net; using System.Web; // получить капчу bool GetCaptcha(string user_agent, out string image, out string challenge, out string link_captcha) { image = null; challenge = null; link_captcha = null; try { // страница регистрации HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://smsaero.ru/users/register/"); request.Host = "smsaero.ru"; request.Referer = "http://www.smsaero.ru/"; request.UserAgent = user_agent; HttpWebResponse response = (HttpWebResponse)request.GetResponse(); StreamReader readStream = new StreamReader((Stream)response.GetResponseStream(), Encoding.UTF8); string req = readStream.ReadToEnd(); // ответ link_captcha = "http://www.google.com/recaptcha/api/noscript" + FindString(req, "http://www.google.com/recaptcha/api/noscript", "\""); // страница с капчей, получаем картинку request = (HttpWebRequest)WebRequest.Create(link_captcha); request.Referer = "http://smsaero.ru/users/register/"; request.UserAgent = user_agent; response = (HttpWebResponse)request.GetResponse(); readStream = new StreamReader((Stream)response.GetResponseStream(), Encoding.UTF8); req = readStream.ReadToEnd(); // ответ challenge = FindString(req, "image?c=", "\""); image = "http://www.google.com/recaptcha/api/image?c=" + challenge; // загрузка капчи request = (HttpWebRequest)WebRequest.Create(image); request.Referer = link_captcha; request.UserAgent = user_agent; response = (HttpWebResponse)request.GetResponse(); Stream str = response.GetResponseStream(); byte[] inBuf = new byte[100000]; int bytesReadTotal = 0; FileStream fstr = new FileStream("captcha\\" + challenge + ".jpg", FileMode.Create, FileAccess.Write); while (true) { int n = str.Read(inBuf, 0, 100000); if ((n == 0) || (n == -1)) { break; } fstr.Write(inBuf, 0, n); bytesReadTotal += n; } str.Close(); fstr.Close(); return true; } catch { } return false; } string FindString(string src, string str1, string str2) { int begin = src.IndexOf(str1); int end = 0; if (begin != -1) { begin += str1.Length; end = src.IndexOf(str2, begin); } else return null; string res = null; if (end != -1) res = src.Substring(begin, end - begin); return res; }
Ребят а рабочии пример по recaptcha v2 там где вылазит 3на3 4на4 картинки никто не подкинет? а тос мотрю уже и сервисы подтянулись.Как емулировать выбор етих картинок хз)
Говорят что авторизированому пользователю в G+ recaptcha v2 не показывается, т.е. он сразу распознается как не бот, но это зависит от настроек recaptcha v2. Ну, а так, геморное это дело - https://github.com/neuroradiology/InsideReCaptcha