Antigate в несколько потоков

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by @leks@, 2 Sep 2011.

  1. @leks@

    @leks@ New Member

    Joined:
    28 Nov 2009
    Messages:
    32
    Likes Received:
    0
    Reputations:
    0
    Привет всем помогите первыйраз столнулся с этим
    пищу приложения работает 10 потоков и нужно отправить 10 капчий
    Code:
    
    id_c:=Pars('captcha","',responseres.Text,'"]');
    FS:=TFileStream.Create('captcha.jpg',FMCreate);
    HTTP.Get('http://site.ru/get_image?id='+id_c,FS);
    FS.Free;
    
    
    но так картинки заменяються
    как правильно в сделать чтоб водельном потоке отправлялась капча....
     
  2. Kaimi

    Kaimi Well-Known Member

    Joined:
    23 Aug 2007
    Messages:
    1,732
    Likes Received:
    811
    Reputations:
    231
    Ну так не записывай картинку в файл, а сразу отправляй на антигейт. В чем проблема то?
     
    _________________________
  3. Chrome~

    Chrome~ Elder - Старейшина

    Joined:
    13 Dec 2008
    Messages:
    936
    Likes Received:
    162
    Reputations:
    27
    Можно отправлять капчу из рабочего потока, и когда придет ответ сразу же продолжать работу. Такой вариант не подходит?

    По поводу проблемы: используй TMemoryStream вместо TFileStream.
     
  4. ZdezBilYa

    ZdezBilYa Elder - Старейшина

    Joined:
    29 Aug 2008
    Messages:
    198
    Likes Received:
    75
    Reputations:
    19
    Создавать разные файлы для капчи. Этож очевидно)
     
  5. @leks@

    @leks@ New Member

    Joined:
    28 Nov 2009
    Messages:
    32
    Likes Received:
    0
    Reputations:
    0
    это не пойдет рандомить имя капчи не вариант....
     
  6. @leks@

    @leks@ New Member

    Joined:
    28 Nov 2009
    Messages:
    32
    Likes Received:
    0
    Reputations:
    0
    помогите разабраться
    Code:
    Jpg:=TJPEGImage.Create;
    MStr:=TMemoryStream.Create;
    HTTP.Get('http://site.ru/get_image?id='+id_c,MStr);
    MStr.Seek(0,soFromBeginning);
    Jpg.LoadFromStream(MStr);
    
     captcha := recognize(ExtractFilePath(Application.ExeName) + '\captcha.jpg', Form1.Edit1.Text, false, false, false, 0, 0);
    
    вместо captcha.jpg что делать
     
  7. waik

    waik Elder - Старейшина

    Joined:
    2 Nov 2008
    Messages:
    405
    Likes Received:
    163
    Reputations:
    12
    номер потока ставь в имя файла капчи.
     
  8. @leks@

    @leks@ New Member

    Joined:
    28 Nov 2009
    Messages:
    32
    Likes Received:
    0
    Reputations:
    0
    как узнать номер потока
     
  9. Chrome~

    Chrome~ Elder - Старейшина

    Joined:
    13 Dec 2008
    Messages:
    936
    Likes Received:
    162
    Reputations:
    27
    Да какой номер потока?
    ТС, если ты используешь функцию recognize из программы-примера работы с antigate, то тебе ее придется немного изменить.
     
  10. @leks@

    @leks@ New Member

    Joined:
    28 Nov 2009
    Messages:
    32
    Likes Received:
    0
    Reputations:
    0
    Так подскажи что изменить та...
     
  11. Chrome~

    Chrome~ Elder - Старейшина

    Joined:
    13 Dec 2008
    Messages:
    936
    Likes Received:
    162
    Reputations:
    27
    Выложи код функции, посмотрю. Сейчас нету возможности скачать из антигейта самому.
     
  12. @leks@

    @leks@ New Member

    Joined:
    28 Nov 2009
    Messages:
    32
    Likes Received:
    0
    Reputations:
    0
    Code:
    function recognize(filename: string; apikey: string; is_phrase: boolean;
      is_regsense: boolean; is_numeric: Boolean; min_len: integer; max_len: integer): string;
    var
      ftype, tmpstr, captcha_id: string;
      i: integer;
      http: TIdHTTP;
      multi: Tidmultipartformdatastream;
    begin
      if FileExists(filename) = false then begin result := 'ERROR: file not found'; exit; end;
      result := 'ERROR';
      ftype := 'image/pjpeg';
      if strpos(Pchar(filename), 'jpg') <> nil then ftype := 'image/pjpeg';
      if strpos(Pchar(filename), 'gif') <> nil then ftype := 'image/gif';
      if strpos(Pchar(filename), 'png') <> nil then ftype := 'image/png';
    
      multi := Tidmultipartformdatastream.Create;
      multi.AddFormField('method', 'post');
      multi.AddFormField('key', apikey);
      multi.AddFile('file', filename, ftype);
      if is_phrase = true then multi.AddFormField('phrase', '1');
      if is_regsense = true then multi.AddFormField('regsense', '1');
      if is_numeric = true then multi.AddFormField('numeric', '1');
      if min_len > 0 then multi.AddFormField('min_len', inttostr(min_len));
      if max_len > 0 then multi.AddFormField('max_len', inttostr(max_len));
    
      http := TIdHTTP.Create(nil);
      tmpstr := http.Post('http://antigate.com/in.php', multi);
      http.Free;
      multi.Free;
      captcha_id := '';
      if strpos(Pchar(tmpstr), 'ERROR_') <> nil then begin result := tmpstr; exit; end;
      if strpos(Pchar(tmpstr), 'OK|') <> nil then captcha_id := AnsiReplaceStr(tmpstr, 'OK|', '');
      if captcha_id = '' then result := 'ERROR: bad captcha id';
      for i := 0 to 20 do
      begin
        Application.ProcessMessages;
        sleep(5000);
        http := TIdHttp.Create(nil);
        tmpstr := http.Get('http://antigate.com/res.php?key=' + apikey + '&action=get&id=' + captcha_id);
        http.Free;
        if strpos(Pchar(tmpstr), 'ERROR_') <> nil then begin result := tmpstr; exit; end;
        if strpos(Pchar(tmpstr), 'OK|') <> nil then
        begin
          result := AnsiReplaceStr(tmpstr, 'OK|', '');
          exit;
        end;
        Application.ProcessMessages;
      end;
      result := 'ERROR_TIMEOUT';
    end;
    function Pars(T_, ForS, _T: string): string;
    var
      a, b: integer;
    begin
      Result := '';
      if (T_ = '') or (ForS = '') or (_T = '') then
        Exit;
      a := Pos(T_, ForS);
      if a = 0 then
        Exit
      else
        a := a + Length(T_);
      ForS := Copy(ForS, a, Length(ForS) - a + 1);
      b := Pos(_T, ForS);
      if b > 0 then
        Result := Copy(ForS, 1, b - 1);
    end;
    
     
  13. Chrome~

    Chrome~ Elder - Старейшина

    Joined:
    13 Dec 2008
    Messages:
    936
    Likes Received:
    162
    Reputations:
    27
    В объявлении функции вместо
    Code:
    filename: string;
    напиши
    Code:
    Stream: TStream;
    и далее при вызове функции recognize первым параметром передавай TMemoryStream с капчей.

    Вот это все стоит убрать:
    Code:
      ftype := 'image/pjpeg';
      if strpos(Pchar(filename), 'jpg') <> nil then ftype := 'image/pjpeg';
      if strpos(Pchar(filename), 'gif') <> nil then ftype := 'image/gif';
      if strpos(Pchar(filename), 'png') <> nil then ftype := 'image/png';
    И вместо этой строчки:
    Code:
      multi.AddFile('file', filename, ftype);
    нужно записать:
    Code:
      multi.AddObject('file', 'application/octet-stream', '', Stream, 'captcha.jpg');
    Если на последней поправке будет выдавать ошибку - обнови Indy, так как метод AddObject с такими параметрами появился в последних версиях.
     
  14. zoke

    zoke Member

    Joined:
    5 Sep 2010
    Messages:
    90
    Likes Received:
    9
    Reputations:
    5
    Скачивай с id_c в название и загружай так же на антикапчу

    в delphi не разу не писал, но из своего опыта c# должно получиться что-то вроде этого.

    Code:
     captcha := recognize(ExtractFilePath(Application.ExeName) + '\' + id_c + '.jpg', Form1.Edit1.Text, false, false, false, 0, 0);
     
  15. @leks@

    @leks@ New Member

    Joined:
    28 Nov 2009
    Messages:
    32
    Likes Received:
    0
    Reputations:
    0

    Code:
    if FileExists(filename) = false then begin result := 'ERROR: file not found'; exit; end;
    это тоже удалить ругаеться
    и indy щас обновлю проверю..
     
  16. Chrome~

    Chrome~ Elder - Старейшина

    Joined:
    13 Dec 2008
    Messages:
    936
    Likes Received:
    162
    Reputations:
    27
    Все остальные строчки, где встречается filename можешь закомментировать или удалить, так как они уже не играют весомой роли.
     
  17. @leks@

    @leks@ New Member

    Joined:
    28 Nov 2009
    Messages:
    32
    Likes Received:
    0
    Reputations:
    0
    Code:
    captcha := recognize( что сюда то пихать, Form1.Edit1.Text, false, false, false, 0, 0);
    ругаеться или я не правильно ее вызываю..

    малость уже туплю
     
  18. Chrome~

    Chrome~ Elder - Старейшина

    Joined:
    13 Dec 2008
    Messages:
    936
    Likes Received:
    162
    Reputations:
    27
    Объект типа TMemoryStream с телом капчи. Судя по предыдущим постам, он в вас называется MStr. Дальше пробуйте сами разбираться.
     
  19. @leks@

    @leks@ New Member

    Joined:
    28 Nov 2009
    Messages:
    32
    Likes Received:
    0
    Reputations:
    0
    Спасибо разабрался... последний касяк обновил инди пишет "Error reading IdHTTP1.AuthRetries если кто может помочь что за фигня
     
  20. Kandi

    Kandi Member

    Joined:
    18 Nov 2009
    Messages:
    344
    Likes Received:
    17
    Reputations:
    0
    Я может не заметил, но какая у Вас Delphi\Rad ???
    Вообще делается всё просто в каждом потоке создается собственная локальная переменная например
    Code:
    procedure MY;
    var
      HTTP : TIdHTTP;
    begin
      HTTP := TIdHTTP.Create(nil);
      try
        { Здесь получаем капчу например обычным HTTP который вы создали локально - т.е. у каждого потока свой HTTP }
        HTTP.Get('mycaptcha.ru', MS); // MS -> TMemoryStream;
        CodeCaptcha := SendCaptcha(MS1, KeyAntiGate, false, false, false, 0, 0);
      finally
        HTTP.Free;
      end;
    end;
    
    Функция распознания:
    Code:
    function SendCaptcha(MS: TMemoryStream; apikey: string; is_phrase,
      is_regsense, is_numeric: boolean; min_len, max_len: integer): string;
    var
    tmpstr,captcha_id: String;
    i: integer;
    http: TIdHTTP;
    multi: Tidmultipartformdatastream;
    begin
    
    multi:=Tidmultipartformdatastream.Create;
    multi.AddFormField('method','post');
    multi.AddFormField('key',apikey);
    //multi.AddFile('file',filename,ftype);
    multi.AddObject('file', 'image/pjpeg', MS, 'captcha.jpg' );
    if is_phrase=true then multi.AddFormField('phrase','1');
    if is_regsense=true then multi.AddFormField('regsense','1');
    if is_numeric=true then multi.AddFormField('numeric','1');
    if min_len>0 then multi.AddFormField('min_len',inttostr(min_len));
    if max_len>0 then multi.AddFormField('max_len',inttostr(max_len));
    http:=TIdHTTP.Create(nil);
    tmpstr:=http.Post('http://antigate.com/in.php',multi);
    http.Free;
    multi.Free;
    captcha_id:='';
    if strpos(Pchar(tmpstr),'ERROR_')<>nil then begin result:=tmpstr; exit; end;
    if strpos(Pchar(tmpstr),'OK|')<>nil then captcha_id:=AnsiReplaceStr(tmpstr,'OK|','');
    if captcha_id='' then result:='ERROR: bad captcha id';
    for i:=0 to 20 do
      begin
      sleep(5000);
      http:=TIdHttp.Create(nil);
      tmpstr:=http.Get('http://antigate.com/res.php?key='+apikey+'&action=get&id='+captcha_id);
      http.Free;
      if strpos(Pchar(tmpstr),'ERROR_')<>nil then begin result:=tmpstr; exit; end;
      if strpos(Pchar(tmpstr),'OK|')<>nil then
        begin
        result:=AnsiReplaceStr(tmpstr,'OK|','');
        exit;
        end;
      end;
    result:='ERROR_TIMEOUT';
    end;
    
    По уму ставишь в цикл пока капча не будет введена верно как только верная, т.е. сервер глотнул её выходим из цикла.

    P.S. Тип файла переделай, а то я делал только под Jpeg да бы уменьшить немного код :rolleyes: да и мне остальные расширения были не нужны)