Вводим captcha в вебмастере Yandex через компонент Indy в Delphi

Параметр key генерируется автоматически при каждом обращении к странице и это обстоятельство следует учитывать при парсинге страницы. Заголовки сообщений при загрузке страницы:

GET /image?key=ee7ce95580d7fb56ac9e3816052281df HTTP/1.1
Host: captcha.yandex.net
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.9.1.3) Gecko/20090824 Firefox/3.5.3
Accept: image/png,image/*;q=0.8,*/*;q=0.5
Accept-Language: ru,en-us;q=0.7,en;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: windows-1251,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Referer: http://webmaster.yandex.ru/

Работа будет осуществляться следующим образом:

  1. Отправляем запрос на сервер.
  2. Получаем ответ и парсим полученные данные в поисках ссылки на каптчу.
  3. Загружаем Captcha в TImage и ждем ввода проверочного кода.
  4. При нажатии на кнопку «Отправить на сервер» делаем запрос методом POST и проверяем, что ответит нам сервер.
  5. Выводим результат работы в Edit.

Укладываем на форму idHTTP, подключаем в uses модуль VBScript_RegExp_55_TLB для работы с RegExp, а также два модуля для работы с графикой JPEG и Gifimg (второй модуль в Delphi 7 может отсутствовать) и в обработчике кнопки «Captcha регистрации сайта» пишем следующий код:

procedure TForm3.Button1Click(Sender: TObject);
var
  List: TStringList;
  R: TRegExp;
  mc: MatchCollection;
  m: Match;
  sm: SubMatches;
  Stream: TMemoryStream;
  JPEG: TJPEGImage;
begin
  List:=TStringList.Create;
  List.Text:=IdHTTP1.Get('http://webmaster.yandex.ru/');//получаем содержимое страницы в переменную
  R:=TRegExp.Create(self);
  R.Pattern:='src="(.*?key.*?)"'; //регулярное выражение для поиска Captcha
  R.Multiline:=true;
  R.IgnoreCase:=true;
  R.Global:=true;
  mc := R.Execute(List.Text) as MatchCollection;
  if mc.Count > 0 then //нашли совпадение
  begin
    m:= mc[0] as Match;
    sm:= m.SubMatches as SubMatches;
    Stream:=TMemoryStream.Create;
    IdHTTP1.Get(sm[0],Stream); //грузим капчу в поток.
    Stream.Position:=0; //устанавливаем ОБЯЗАТЕЛЬНО на ноль
    JPEG:=TJPEGImage.Create;   //создаем jpeg
    JPEG.LoadFromStream(Stream);//загружаем данные из потока
    Image1.Picture.Assign(JPEG);//выводим в Image
  end;
end;

Полдела сделано — каптча выводится в Image. Осталось только правильно её отправить на сервер.

Для этого рассмотрим запрос, который отправляется на сервер при нажатии кнопки «Добавить» формы добавления сайта:

POST /add.xml HTTP/1.1
Host: webmaster.yandex.ru
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.9.1.3) Gecko/20090824 Firefox/3.5.3
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: ru,en-us;q=0.7,en;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: windows-1251,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Referer: http://webmaster.yandex.ru/
Content-Type: application/x-www-form-urlencoded
Content-Length: 64
url=webdelphi.ru&key=3ab4f1280e4afc49181ee3438a5a5c1e&rep=033316

Обратите внимание на сроку после заголовка Content-Length. Как видите — это параметры запроса методом POST:

url — URL нашего файла;
key — ключ Captcha
rep — код Captcha, который мы ввели

Теперь всё, что от нас требуется — правильно сформировать и отправить запрос на сервер. Для примера я создам запрос один-к-одному как и представленный выше.

var ParamList: TStringList;
begin
  if webmaster then
  begin
    ParamList:=TStringList.Create;   //создаем список параметров для отправки
    ParamList.Add('url='+Edit1.Text);
    ParamList.Add('key='+CaptchaKey);
    ParamList.Add('rep='+Edit2.Text);
    ParamList.Add('');
    with IdHTTP1.Request do
    begin
      URL:='http://webmaster.yandex.ru/add.xml';
      Host:='webmaster.yandex.ru';
      UserAgent:='Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.9.1.3) Gecko/20090824 Firefox/3.5.3';
      Accept:='text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8';
      AcceptLanguage:='ru,en-us;q=0.7,en;q=0.3';
      AcceptEncoding:='gzip,deflate';
      AcceptCharSet:='windows-1251,utf-8;q=0.7,*;q=0.7';
      Connection:='keep-alive';
      Referer:='http://webmaster.yandex.ru/';
      ContentLength:=Length(ParamList.Text);
      ContentType:='application/x-www-form-urlencoded';
    end;
    ParamList.Text:=IdHTTP1.Post('http://webmaster.yandex.ru/add.xml',ParamList);
  end
  else
  begin
 
  end;
end;

Теперь можно сделать так:

  1. Если был редирект на одну из страниц с ошибкой, то в результат выносим текст ошибки и перезагружаем Captcha.
  2. Иначе выводим в результат текст об успешном добавлении.

Пишем обработчик события onRedirect:

procedure TForm3.IdHTTP1Redirect(Sender: TObject; var dest: string; var NumRedirect: Integer; var Handled: Boolean; var VMethod: string);
begin
  // Если есть редирект, то 100% допущена ошибка
  Error := true;
  if pos('CAPTCHA_FAILD', dest) > 0 then
    ErrorText:='Неправильно введен код Captcha'
  else if pos('INVALID_URL', dest) > 0 then
    ErrorText := 'Введен некорректный URL'
  else if pos('URL_RETURNED_WRONG_CODE', dest) > 0 then
    ErrorText:=
      'Сервер недоступен, либо возвращает код статуса http, отличный от 200'
  else if pos('HOST_IS_MIRROR_MAIN_MIRROR_IS_INDEXED', dest) > 0 then
    ErrorText := 'Указанный вами сайт является неглавным зеркалом сайта. Главное зеркало сайта уже индексируеся'
  else if pos('URL_IS_ALREADY_INDEXED', dest) > 0 then
    ErrorText:='Сайт уже индексируется';
end;

И немного дописываем обработчик отправки данных на сервер, добавив следующие строки:

Error:=false;//в самом начале обработчика
.....
if Error then
begin
  Edit3.Text:=ErrorText;
  Button1Click(self);
end
1 Звезда2 Звезды3 Звезды4 Звезды5 Звезд (8 оценок, среднее: 5,00 из 5)
Загрузка...
Добавить комментарий