• 0
Mars M

NetHttpClient vs idHttp

Вопросы

Есть такой вот код для работы с гугл переводчиком:

procedure TfrmMain.GTranslate;
var
  Data: TStringList;
  S: String;
begin
  IdHTTP1.Request.UserAgent :=
    'Mozilla/5.0 (Windows; U; Windows NT 6.1; ru-RU) Gecko/20100625 Firefox/3.6.6';

  Data := TStringList.Create;
  try
    Data.Text := ('client=x'#13#10
                + 'text='
                + Edit1.Text + #13#10
                + 'hl=en'#13#10
                + 'sl=en'#13#10
                + 'tl=ru');
    try
      S := (IdHTTP1.Post('http://translate.google.ru/translate_a/t', Data));
    except
      on E: exception do
        ShowMessage(E.ClassName + ' error raised, with message : ' + E.Message);
    end;
  finally
    Data.Free;
  end;
end;

Работает без проблем.

Переделал его для NetHttpClient, практически один в один и вместо перевода получаю html страницу с гугл капчей.

Типа такой как получаю если заходить через браузер http://translate.google.ru/translate_a/t?client=x&text=Hello&hl=en&sl=en&tl=ru

Так в чем между ними разница что получаю разный результат?

PS: Просто я в проекте и так использую NetHttpClient, хотелось бы на нем и сделать а не плодить кучу однотипных компонентов.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

4 ответа на этот вопрос

  • 0

Вот сделал аналог на THTTPClient:

function TForm1.GoogleTranslate(const AValue : String) : String;
const ConstGoogleUrl = 'http://translate.google.ru/translate_a/t';
var ASource: TStringList;
    AResponce : IHTTPResponse;
    FHTTPClient : THTTPClient;
begin
  FHTTPClient:=THTTPClient.Create;
  FHTTPClient.UserAgent:='Mozilla/5.0 (Windows; U; Windows NT 6.1; ru-RU) Gecko/20100625 Firefox/3.6.6';
  Result:='Translate Error : ';
  ASource:=TStringList.Create;
  ASource.Add('client=x');
  ASource.Add('text=' + AValue);
  ASource.Add('hl=en');
  ASource.Add('sl=en');
  ASource.Add('tl=ru');
  AResponce:=FHTTPClient.Post(ConstGoogleUrl, ASource);
  if Not Assigned(AResponce) then
  begin
    Result:=Result + 'unknow.';
    Exit;
  end;
  if AResponce.StatusCode <> 200 then
  begin
    Result:=Result + AResponce.StatusText;
  end;
    Result:=AResponce.ContentAsString;
end;

Получаю вполне очевидный ответ:

Цитата

Наши системы обнаружили необычный трафик из вашей компьютерной сети. Эта страница проверяет, действительно ли вы отправляете запросы, а не робот.
Эта страница появляется, когда Google автоматически обнаруживает запросы, поступающие из вашей компьютерной сети, которые, как представляется, нарушают <a href="//www.google.com/policies/terms/"> Условия обслуживания </a>. После истечения этих запросов блок истечет. В то же время решение вышеуказанного CAPTCHA позволит вам продолжать использовать наши сервисы. <br> <br> Этот трафик может быть отправлен вредоносным программным обеспечением, подключаемым модулем браузера или скриптом, который отправляет автоматические запросы. Если вы сообщаете свое сетевое подключение, обратитесь к вашему администратору за помощью & mdash; другой компьютер, использующий один и тот же IP-адрес, может быть ответственным. <a href="//support.google.com/websearch/answer/86640"> Подробнее ... <br> <br> Иногда вас могут попросить решить CAPTCHA, если вы используете расширенные термины, которые роботы которые часто используются или отправляют запросы очень быстро.

Конечно подбор HTTP Headers и других параметров может и обманет не надолго сервис, но на это надеяться не стоит. В Гугле работают отнюдь не дураки, и вряд ли они создавали свой сервис перевода (с отличным API кстати) просто так. Сервис платный (20 долларов США за 1 000 000 символов , но с пробным бесплатным периодом. Если вы хотите 100% работающее решение, то лучше воспользоваться им https://translate.google.com/intl/ru/about/forbusiness.html

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

Я уперся рогом и все таки смог найти решение для вас. Гугль любит разработчиков, и обычно оставляет им возможность пользоваться сервисами бесплатно. И в этот раз чутьё не подвело. Вот решение:

unit Unit1;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
  FMX.Controls.Presentation, FMX.ScrollBox, FMX.Memo,
  System.JSON,
  System.Net.HTTPClient,
  System.NetEncoding;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    procedure FormShow(Sender: TObject);
  private
    { Private declarations }

  public
    { Public declarations }
    function GoogleTranslate(const AValue : String) : String;
  end;

var
  Form1: TForm1;

implementation

{$R *.fmx}

procedure TForm1.FormShow(Sender: TObject);
Var S : String;
begin
  S:=GoogleTranslate('Hello world!');
  Memo1.Lines.Add(S);
end;

function TForm1.GoogleTranslate(const AValue : String) : String;
const ConstSourceLang  = 'en';
      ConstTargetLang  = 'ru';
var AResponce : IHTTPResponse;
    FHTTPClient : THTTPClient;
    AAPIUrl : String;
begin
  AAPIUrl:='https://translate.googleapis.com/translate_a/single?client=gtx&sl=' + ConstSourceLang +
            '&tl=' + ConstTargetLang + '&dt=t&q=' + TNetEncoding.URL.Encode(AValue);
  FHTTPClient:=THTTPClient.Create;
  FHTTPClient.UserAgent:='Mozilla/5.0 (Windows; U; Windows NT 6.1; ru-RU) Gecko/20100625 Firefox/3.6.6';
  Result:='Translate Error : ';
  AResponce:=FHTTPClient.Get(AAPIUrl);
  if Not Assigned(AResponce) then
  begin
    Result:=Result + 'unknow.';
    Exit;
  end;
  if AResponce.StatusCode <> 200 then
  begin
    Result:=Result + AResponce.StatusText;
  end;
  try
    Result:=TJSONArray(TJSONArray(TJSONArray(TJSONObject.ParseJSONValue(AResponce.ContentAsString)).Items[0]).Items[0]).Items[0].Value;
  except
    Result:=Result + 'error parse JSON.';
    Exit;
  end;
end;

end.

Подправил код, сделал покрасивее и убрал deprecated encode.

Изменено пользователем Евгений Корепов

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

Евгений Корепов, проверил, вроде работает. Спасибо :)

На счет 20 долларов США за 1 000 000 символов  это конечно хорошо, но во фришном софте использовать платные решения не хочется :)

1 час назад, Евгений Корепов сказал:

 Гугль любит разработчиков, и обычно оставляет им возможность пользоваться сервисами бесплатно. И в этот раз чутьё не подвело.

А где почитать про эту бесплатную возможность от гугла, желательно от самого гугла? Ну что бы хоть быть в курсе к чему быть готовым?

 

Тут кстати нашел ещё решения с парсингом страницы, тоже вроде работает, но разумеется помедленней, хотя во фришном софте это не так важно.

https://sourceforge.net/projects/agoogletranslat/

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти

  • Похожий контент

    • От Sashar333
      Здравствуйте! Вопрос такой:
      Есть процедура:
      Если переменные inn,capcha и capchaToken указаны правильно то Idhttp работает как надо, если inn или capcha не верны то прим Idhttp.post программа выдает ошибку:

      а хочется получить данные как в анализаторе:

      Как можно это сделать? 
    • От Anasazi
      Всем доброго времени суток. Возникла необходимость решить такую задачу: в таблице базы MySQL хранится список изображений и их URL. Необходимо получить этот список массивом. Затем загрузить изображения и поочередно с интервалом показать их в TImage.
      Понимаю, что получить список изображений правильнее при помощи PHP скрипта, но в каком виде скрип должен вернуть данные, чтобы в Delphi получить из них массив не знаю.
      Раньше для получения изображений использовал такую процедуру. Но вопрос, где хранить изображения перед демонстрацией их в TImage? Создавать несколько MemoryStream?
      procedure LoadWebImage(url: string; image: TBitmap);
      var
        idhttp : TNetHTTPClient;
        ms : TMemoryStream;
      begin
       IdHTTP := TNetHTTPClient.Create(nil);
        ms := TMemoryStream.Create;
        try
          idhttp.Get(url, ms);
          ms.Position := 0;
          image.LoadFromStream(ms);
        finally
          ms.Free;
          idhttp.Free;
        end;
      end;
    • От Кирилл
      Добрый день!
      Возникла необходимость из программы на Android отправлять запросы на web сервер и получать ответ.
      Пробую использовать TidHTTP:
      - кинул на форму компонент TidHTTP;
      - вызываю:  
      procedure TForm1.btSendClick(Sender: TObject); var list: TStringList; s: string; begin list := TStringList.Create; try list.Add('1'); try s := IdHTTP1.Post('http://127.0.0.1', list); ShowMessage(s); except on E: Exception do ShowMessage('Error: ' + E.Message); end; finally FreeAndNil(list); end; end; - в результате программа закрывается. Без всяких сообщений.
      Запускал на смартфоне Samsung Galaxy A3 (2016) Android 6.0.1.
      В чем может быть проблема?
       
       
       
       
       
       
    • От giveaway
      При написании кода под Windows я обычно использую WinNT, чтобы определить, выходит ли пользователь в Интернет через файрвол, а также для проверки сертификата сайта, когда клиент подключается к нему. Чем можно заменить WinNT под Firemonkey, чтобы выполнить эти задачи – проверку наличия файрвола и проверку сертификата сайта? Спасибо.
    • От Rusland
      Как реализовать показ ProgressBar при загрузке фотографии на сервер? Интересует как именно определять сколько байт передано?
      Используется компонент NetHTTPClient.
    • От Rusland
      Вроде видел где-то пример передачи через NetHTTPClient файла (*.png или *.jpg) на сервер, но не могу вспомнить где.
      Помогите с кодом отправки файла.
       
      PS. Инди компоненты не интересуют, не хочется их инспользовать
    • От R.is
      Подскажите пожалуйста как избежать данную проблему, пытаюсь загрузить исходный код страницы IdHTTP1.Get('сайт') а Indy говорит что ее не существует 
      http/1.1 404 not found  
    • От Rusland
      На NetHTTPClient пытаюсь назначить обработчик OnValidateServerCertificate:
       
      type TFrmMain = class(TForm) ... procedure OnAuthEvent(const Sender: TObject; AnAuthTarget: TAuthTargetType; const ARealm, AURL: string; var AUserName, APassword: string; var AbortAuth: Boolean; var Persistence: TAuthPersistenceType); procedure OnValidateServerCertificate(const Sender: TObject; const ARequest: TURLRequest; const [Ref] Certificate: TCertificate; var Accepted: Boolean); function TFrmMain.GetResponse2(aURL: string): TResponser; var Ss: TStringStream; NetHTTPClient2:TNetHTTPClient; Respon: IHTTPResponse; begin try NetHTTPClient2:=TNetHTTPClient.Create(nil); NetHTTPClient2.OnAuthEvent:=OnAuthEvent; NetHTTPClient2.OnValidateServerCertificate:=OnValidateServerCertificat; // ошибка компиляции ... with NetHTTPClient2 do begin Ss:=TStringStream.Create('', TEncoding.UTF8); Respon:=Get(aURL,ss); end; finally NetHTTPClient2.Free; end; end; procedure TFrmMain.OnValidateServerCertificate( const Sender: TObject; const ARequest: TURLRequest; const [Ref] Certificate: TCertificate; var Accepted: Boolean); begin Accepted:=true; end; Получаю ошибку: Incompatible types: 'Parameter lists differ'  
      Как правильно сделать?
    • От Rusland
      Так как не получается работать с IdHTTP в сервисе, решил попробовать компонент NetHTTPClient. Бросил NetHTTPClient1 на форму.
      Хочу открыть адрес https://ya.ru
      В папку \Win32\Debug положил libeay32.dll и ssleay32.dll (они рабочие, проверены с IdHTTP)
       
      Код (пока тестирую на обычном приложении, а не в сервисе):
      Получаю access violation в System.Net.HTTPClient в строке 1965 
      if (Result.Value.Chars[0] = '"') and (Result.Value[High(Result.Value)] = '"') then видимо из-за того что Result.Value пустой. 
      А если попробовать открыть https://mail.ru такого не происходит и страница нормально скачивается.
       
      В чем проблема?
  • Последние посетители   0 пользователей онлайн

    Ни одного зарегистрированного пользователя не просматривает данную страницу