•  

ГлавнаяIndyЧастые вопросы по Indy → Помогите новичку с TWebBrowser.Navigate2()

Создано: 16.05.2014 21:50:38 · Исправлено: 16.05.2014 21:50:38 · Прочтений: 1825

Помогите новичку с TWebBrowser.Navigate2() пробую написать алгоритм в котором по количеству строк в таблице SG происходит навигация WebBrowser.Navigate2();
//********************
// выполнение навигации
procedure SendData(TargetData:integer);
begin
....
в которой навигация осуществляется :
GForm.WebB.Navigate2(URLN, Flags, TargetFrameName, PostData, Headers);
ShowMessage(Данные отправлены);
end;
//***************
procedure TGForm.Timer1Timer(Sender: TObject);
var 
i:integer;
begin
For i:=1 to SG.RowCount do
begin
GForm.SendData(i);
end;
end;
//**************
происходит выполнение только первого перехода :(( видимо цикл проходит раньше чем webBrowser справляется с командой... пробовал в цикл ставить задержку sleep(1000*10); не помогло( помогите пож - кто знает.
Navigate2 это асинхронный метод и ваша итерация ни к чему не приведет. Об том что браузер перешел/отправил стрничку/данные вы можете узнать на соответствующем событии браузера и лишь тогда можно вызывать метод Navigate2 снова.
ммм.. в таком случае получается вот такой код: // =((( Но он к сожалению тоже не работает // то ли я что то не допонимаю то- ли sleep() не подходит тут(( //******** // когда навигация закончена FlagComplete:=True;
procedure TGForm.WebBNavigateComplete2(Sender: TObject;
  const pDisp: IDispatch; var URL: OleVariant);
begin
FlagComplete:=True;
end;
//****
procedure ....
....
For i:=1 to SG.RowCount do
begin
  if (FlagComplete) then
    Begin
    SendData(SG.Cell[1,i]);
    FlagComplete:=False;
  end else
  begin
    sleep(1000*5);
  end; 
end;
end; //конец процедуры
// =((( Но он к сожалению тоже не работает // то ли я что то не допонимаю то- ли sleep() не подходит тут((
Вы правы на 100% - не подходит тут ;)
Насколько я понял вам вовсе не нужно отображать данные которые придут назад в браузер. Или я не прав? Может вам просто надо отправить данные по какому то адресу? Тогда воспользуйтесь невизуальными компонентами, которые это могут делать в синхронном режиме.(Indy, Synapse)
просто я в делфи 2 дня только работаю.. расчитываю на помощь подскажите пож какой цикл использовать в данном случае? и как поставить задержку в нём если sleep() не подходит..
да, так и есть отображать не обязательно в данном случае я использую Navigate2() для отправки данных.
Если у вас нормальная среда разработки, то бросайте на форму компоненты TidHTTP, TidAntifreze и пишите приблизительно вот такой код
function TForm1.PostData(AURL, ALogin, APassword: string): Boolean;
var
  aList: TStrings;
begin
  Result := False;

  aList := TStringList.Create;
  try
      aList.Values[login] := ALogin;
      aList.Values[password] := APassword;
      IdHTTP.Post(AURL, aList));
      Result := True
  except
          on e: Exception do
          begin
                //here we handle the exception of incorrect data post
          end;
      end;
  finally
      aList.Free;
  end;
end;
так выскакивает ошибка..
EIdHTTPProtocolException c  сообщением HTTP/1.1 302 Found и т.д....
//********************
procedure ASendDataExecute();
var
aList: TStrings;
AURL,Data1 :String;
begin

  AURL:=URLN;
  Data1:=GForm.SG.Cells[1,1];
  Result := False;
  aList := TStringList.Create;

  try
    begin
      aList.Values[a] := Data1;
      GForm.IdHTTP1.Post(AURL, aList);
      Result := True;
    end;

  except

  end;
end;
10.3.3 302 Found The requested resource resides temporarily under a different URI. Since the redirection might be altered on occasion, the client SHOULD continue to use the Request-URI for future requests. This response is only cacheable if indicated by a Cache-Control or Expires header field. The temporary URI SHOULD be given by the Location field in the response. Unless the request method was HEAD, the entity of the response SHOULD contain a short hypertext note with a hyperlink to the new URI(s). If the 302 status code is received in response to a request other than GET or HEAD, the user agent MUST NOT automatically redirect the request unless it can be confirmed by the user, since this might change the conditions under which the request was issued. Это цитата вашей ошибки. Надо поставить свойство IdHTTP.HandleRedirects := True; и конечно прописать все заголовки(headers). Поскольку нет кода страницы, которая обрабатывает запрос, то ничего конкретнее сказать нельзя :(
Спасибо за ваши советы! для меня пока не понятно как работают TidHTTP, но c TWebBrowser.Navigate2(); отправлять данные получилось - хочу попробывать отправлять данные в цикле .. может есть способы проще, конечно, кусочек рабочего кода в котором в цикле происходит отправка данных мог бы мне помочь решить эту головоломку.
Не понятно вот что: вы говорите что отправляете данные через веб браузер, но не видео как вы это делаете - может как раз в том и загвоздка. И вообще я подозреваю что вам нужно всего лишь метод GET а не Post использовать тогда и проблем не будет.
мне самому не понятно -) суть такова есть адрес интернете: url:=www. .... MyPage.php; который ждёт пременную AText. с помощью кода WebBrowser.Navigate(www. .... MyPage.php?AText:=Hallo World); ничего не произошло, а с помощью перегруженной, переменная заполнилась (Спасибо ресурсам интернета!) WebBrowser.Navigate2(URLN, Flags, TargetFrameName, PostData, Headers); задача состояла в том чтобы отправлять несколько раз - каждый раз разные значения переменной
For i:=1 to SG.RowCount do
begin
AText:=SG.Cells[1,i];
end;
вот не пойму как в цикле подобное выразить.. сейчас приходится пользоваться :
case myNumberData of
    //
    01:SendData(SG.Cells[1,1]); 
    //
    02:SendData(SG.Cells[1,2]);
... и т.д. хоть и работает, но тут есть ограничение на количество строк таблицы... неужели так нельзя сделать?:
For i:=1 to SG.RowCount do
begin
  SendData(SG.Cell[1,i]);
end;

вот в в этом собственно вопрос. -( у меня пока не получилось((
Вам же я ясно сказал что с применением компонента TWebBrowser у вас будут проблеммы с перехватом конца отправки. Потому пользуйтесь инди. Но как я и предполагал вам лишь нужен метод GET. Кстати, пример ваш содержит ошибку WebBrowser.Navigate(www. .... MyPage.php?AText:=Hallo World); должно быть WebBrowser.Navigate(www. .... MyPage.php?AText=Hallo%20World); и код с инди соответственно:
function TForm1.SendData(AURL, AText: string): Boolean;
begin
  Result := False;
  try
      IdHTTP.Get(AURL + ?AText= + UrlEncode(AText));
      Result := True
  except
    on e: Exception do
    begin
        //here we handle the exception of incorrect data post
    end;
end;
...
For i:=1 to SG.RowCount do
begin
  SendData(http://www. .... MyPage.php, SG.Cell[1,i]);
end;
...
ни первым предложенным вами способом , ни вторым отправки данных у меня не происходит, но ошибок нет.
попробую описать ещё раз при переходе на траничку http://MySite.ru/myPage.php //-------- возникает формочка - с вопросом Столица Берлина? и в текстовое поле предлагается ввести (переменная AText) и кнопочка ОК //-------- после того как вы ввели туда некий текст и нажали кнопку ок вы видите формочку Вы действительно считаетет (AText) столицей Берлина? и кнопочка ОК //-------- после нажатия кнопки Вы видите окно - с вопросом Столица Германии? если на один вопрос получается ответить програмно используя WebBrowser.Navigate2(); то на несколько вопросов подряд - программно отчетить не получается. (предложенные вами варианты с использованием indy не срабатывают даже на первый переход) А в цикл
For i:=1 to SG.RowCount do
Begin
SendData(SG.Cells[1,i]);
end;
какую то задержку кроме sleep и проверять отправились ли данные/загрузилась ли страничка и если отправились/загрузилась - то только после этого переходить к следующему обходу в цикле. вот пока у меня это работает таким кодом
if (FlagComplete)and(FlagBoosy) then
  begin
    //Timer1.Enabled:=False;
    FlagBusy:=False;
    Inc(myNumberData);
    case myNumberData of
    // 
    01:SendData(SG.Cells[1,1]);
    //
    02:SendData(SG.Cells[1,2]);
... и т.д. но тут для каждого вопроса я должен править код программы так как вопросов может быть любое количество.
>>> с помощью кода ..MyPage.php?AText:=Hallo World ничего не произошло >>> вам лишь нужен метод GET Эти две фразы противоречат друг другу. Хотя отправка текста методом Get вовсе не так проста, как воображает автор. Там надо в строке адрес строку кодировать особым образом. Ну и как отправлять данные через Indy. Если ничего не понятно, можешь обратиться через электронную почту, или через СЛС - в асе меня не найти.
Не мутите воду.
BRW.Navigate(sl1);
while BRW.ReadyState <> READYSTATE_COMPLETE do Application.ProcessMessages;
Не мутим. Просто хотим предложить правильный способ - с блокирующими сокетами. Можно и асинхронный режим - на неблокирующих сокетах от Internet Component Suite (ссылка в статье на Королевстве больше не работает, придется тебе искать эту библиотеку от Франсуа Пиете в интернете самостоятельно.