Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 12.12.2013, 12:00
krasnyakjohn krasnyakjohn вне форума
Прохожий
 
Регистрация: 12.12.2013
Сообщения: 13
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию webbrowser - ошибка исключения

Здравствуйте.
Пишу программу, есть такой обработчик клика по кнопке:

Код:
procedure TForm2.Button11Click(Sender: TObject);
var
U,P : Variant;
form:olevariant;
f,i:Integer;
r: TRegExpr;
Doc : IHTMLDocument2;
s:string;
begin
WebBrowser1.Navigate('http://web.iqsms.ru/login/?next=/contacts/');
  while WebBrowser1.ReadyState<>4 do
  Application.ProcessMessages;
  U:=webbrowser1.oleobject.document.getelementbyid('id_username');
  U.value:=Edit3.Text;
  P:=webbrowser1.oleobject.document.getelementbyid('id_password');
  P.value:=Edit4.Text;
  //U.style.display := 'block';
  //P.style.display := 'block';
  for f:=0 to WebBrowser1.OleObject.Document.forms.Length-1 do
  begin
     form:=WebBrowser1.OleObject.Document.forms.Item(f).elements;
        for i:=0 to form.Length-1 do
          if (form.item(i).type='submit')  then
          begin
          form.item(i).click;
          end;
 
  end;
  WebBrowser1.Navigate('http://web.iqsms.ru/contacts/');
  while WebBrowser1.ReadyState<>4 do
  Application.ProcessMessages;
  Doc := WebBrowser1.Document as IHTMLDocument2;  // получили hmtl код страницы
  r := TRegExpr.Create;
  s:=Doc.body.innerHTML;
  r.InputString :=s; // во входяшую строку положили весь html код
  memo3.Text:=s;
try
  r.Expression :='<A href="/deliveries/add-delivery/">(.*?)</A>';
  if r.Exec(s) then
begin
    Groupbox8.Caption:='Отправить смс заказчику';
end
  else ShowMessage('Авторизация не прошла');
    finally
r.Free;
end;
end;

Суть кода: должна произойти авторизация на сайте http://web.iqsms.ru/login/?next=/contacts/

Вот так вот происходит заполнение полей логина и пароля и нажимается кнопка "Войти":

Код:
procedure TForm2.Button11Click(Sender: TObject);
var
U,P : Variant;
form:olevariant;
f,i:Integer;
r: TRegExpr;
Doc : IHTMLDocument2;
s:string;
begin
WebBrowser1.Navigate('http://web.iqsms.ru/login/?next=/contacts/');
  while WebBrowser1.ReadyState<>4 do
  Application.ProcessMessages;
  U:=webbrowser1.oleobject.document.getelementbyid('id_username');
  U.value:=Edit3.Text;
  P:=webbrowser1.oleobject.document.getelementbyid('id_password');
  P.value:=Edit4.Text;
  //U.style.display := 'block';
  //P.style.display := 'block';
  for f:=0 to WebBrowser1.OleObject.Document.forms.Length-1 do
  begin
     form:=WebBrowser1.OleObject.Document.forms.Item(f).elements;
        for i:=0 to form.Length-1 do
          if (form.item(i).type='submit')  then
          begin
          form.item(i).click;
          end;
 
  end;

Но как только я пытаюсь проверить, зашли мы или нет, дописывая код:

Код:
WebBrowser1.Navigate('http://web.iqsms.ru/contacts/');
  while WebBrowser1.ReadyState<>4 do
  Application.ProcessMessages;
  Doc := WebBrowser1.Document as IHTMLDocument2;  // получили hmtl код страницы
  r := TRegExpr.Create;
  s:=Doc.body.innerHTML;
  r.InputString :=s; // во входяшую строку положили весь html код
  memo3.Text:=s;
try
  r.Expression :='<A href="/deliveries/add-delivery/">(.*?)</A>';
  if r.Exec(s) then
begin
    Groupbox8.Caption:='Отправить смс заказчику';
end
  else ShowMessage('Авторизация не прошла');
    finally
r.Free;
end;
end;

То вылазит ошибка:


и подсвечивается строка:
Код:
U.value:=Edit3.Text;

Как я только не пробовал проверять, вошли мы или нет, получаю такую ошибку.
Помогите, пожалуйста.
Ответить с цитированием
  #2  
Старый 12.12.2013, 12:17
Аватар для poli-smen
poli-smen poli-smen вне форума
Профессионал
 
Регистрация: 06.08.2012
Адрес: Кривой Рог
Сообщения: 1,791
Версия Delphi: Delphi 7, XE2
Репутация: 4415
По умолчанию

Цитата:
Сообщение от krasnyakjohn
Вот так вот происходит заполнение полей логина и пароля и нажимается кнопка "Войти":

Код:
.....
  U:=webbrowser1.oleobject.document.getelementbyid('id_username');
  U.value:=Edit3.Text;
.....

То вылазит ошибка:


и подсвечивается строка:
Код:
U.value:=Edit3.Text;

Как я только не пробовал проверять, вошли мы или нет, получаю такую ошибку.
Помогите, пожалуйста.
Скорее всего элемент с таким id не был найден (возможно страница ещё не успела до конца прогрузиться, а может и действительно нет такого элемента на странице). Нужно выполнять проверку найден ли такой элемент, так как в случае если не найден будет получен nil, а при попытке обратиться по этому адресу однозначно получим исключение "Access Violation".

Пример проверки был ли найден элемент у которого id имеет значение "id_username":
Код:
  U:=webbrowser1.oleobject.document.getelementbyid('id_username');
  if not Assigned(U) then raise Exception.Create('Элемент с id "id_username" не найден');
  U.value:=Edit3.Text;
Ответить с цитированием
  #3  
Старый 12.12.2013, 13:47
krasnyakjohn krasnyakjohn вне форума
Прохожий
 
Регистрация: 12.12.2013
Сообщения: 13
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Я же говорю, что половинный код, т.е код, который заполняет по id поля логин и пароль - работает, далее код, который нажимает на "войти" - работает, а когда я пытаюсь проверить вошли мы или нет, т.е как-то зацепиться за элементы страницы, то выдает ошибку.

Я еще пробовал сделать через проверку url, т.е если вошли, то проверяем через Location.Url урл страницы, если он совпадает с тем, который я указал, то вошли.

Так что я, если честно, не понял про проверку id. Потому как эти 2 элемента id_username и id_password 100% есть, так как они заполняются.
Ответить с цитированием
  #4  
Старый 12.12.2013, 13:59
Аватар для poli-smen
poli-smen poli-smen вне форума
Профессионал
 
Регистрация: 06.08.2012
Адрес: Кривой Рог
Сообщения: 1,791
Версия Delphi: Delphi 7, XE2
Репутация: 4415
По умолчанию

Цитата:
Сообщение от krasnyakjohn
Я же говорю, что половинный код, т.е код, который заполняет по id поля логин и пароль - работает, далее код, который нажимает на "войти" - работает, а когда я пытаюсь проверить вошли мы или нет, т.е как-то зацепиться за элементы страницы, то выдает ошибку.
Ты говоришь что всё заполняется. Программа же в этом месте выдаёт ошибку. Кому мне больше верить?
Цитата:
Сообщение от krasnyakjohn
Я еще пробовал сделать через проверку url, т.е если вошли, то проверяем через Location.Url урл страницы, если он совпадает с тем, который я указал, то вошли.
Это уже второстепенная ошибка - сейчас главное избавиться от ошибки доступа, так как это грубая ошибка и в корректно написанной программе таких ошибок возникать не должно практически ни при каких ситуациях.
Цитата:
Сообщение от krasnyakjohn
Так что я, если честно, не понял про проверку id. Потому как эти 2 элемента id_username и id_password 100% есть, так как они заполняются.
Ты проверки всё же поставь - они никогда не помешают, а код станет надёжней. Например даже если у тебя сейчас всё заработает, а завтра владельцы сайта поменяют id элемента с "id_password" на какой нибудь "id_super_password" и у тебя опять посыпятся ошибки и ты опять будешь искать где и что сломалось, а если будет обработка ошибок ты сможешь быстро в нужном месте исправить и всё будет дальше работать.
Ответить с цитированием
  #5  
Старый 12.12.2013, 13:59
krasnyakjohn krasnyakjohn вне форума
Прохожий
 
Регистрация: 12.12.2013
Сообщения: 13
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Цитата:
Сообщение от poli-smen
Скорее всего элемент с таким id не был найден (возможно страница ещё не успела до конца прогрузиться, а может и действительно нет такого элемента на странице). Нужно выполнять проверку найден ли такой элемент, так как в случае если не найден будет получен nil, а при попытке обратиться по этому адресу однозначно получим исключение "Access Violation".

Пример проверки был ли найден элемент у которого id имеет значение "id_username":
Код:
  U:=webbrowser1.oleobject.document.getelementbyid('id_username');
  if not Assigned(U) then raise Exception.Create('Элемент с id "id_username" не найден');
  U.value:=Edit3.Text;

Попробовал вставить ваш код.

Ошибку дает:
[Error] Unit2.pas(605): Incompatible types
Ответить с цитированием
  #6  
Старый 12.12.2013, 14:01
krasnyakjohn krasnyakjohn вне форума
Прохожий
 
Регистрация: 12.12.2013
Сообщения: 13
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Цитата:
Сообщение от poli-smen
Ты говоришь что всё заполняется. Программа же в этом месте выдаёт ошибку. Кому мне больше верить?

Но ошибка вылазит после добавления кода проверки на "зашли или нет".
Т.е закрываю это окно с ошибкой и синим цветом подсвечивается та строка, которую я указал.
Ответить с цитированием
  #7  
Старый 12.12.2013, 14:46
Аватар для poli-smen
poli-smen poli-smen вне форума
Профессионал
 
Регистрация: 06.08.2012
Адрес: Кривой Рог
Сообщения: 1,791
Версия Delphi: Delphi 7, XE2
Репутация: 4415
По умолчанию

Цитата:
Сообщение от krasnyakjohn
Попробовал вставить ваш код.

Ошибку дает:
[Error] Unit2.pas(605): Incompatible types
Действительно, не заметил что ты используешь позднее связывание, а не раннее. Тогда в проверке нужно использовать VarIsClear вместо Assigned:
Код:
if VarIsClear(U) then raise Exception.Create('Элемент с id "id_username" не найден');
Ответить с цитированием
  #8  
Старый 12.12.2013, 14:56
krasnyakjohn krasnyakjohn вне форума
Прохожий
 
Регистрация: 12.12.2013
Сообщения: 13
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Цитата:
Сообщение от poli-smen
Действительно, не заметил что ты используешь позднее связывание, а не раннее. Тогда в проверке нужно использовать VarIsClear вместо Assigned:
Код:
if VarIsClear(U) then raise Exception.Create('Элемент с id "id_username" не найден');

Сделал, теперь ошибки нет, но поля перестали заполняться и кнопка не нажимается, но зато выскакивает ShowMessage Авторизация не прошла.
Ответить с цитированием
  #9  
Старый 12.12.2013, 15:04
krasnyakjohn krasnyakjohn вне форума
Прохожий
 
Регистрация: 12.12.2013
Сообщения: 13
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Может когда я второй раз перехожу по адресу опять идет поиск этих полей, но почему? Я ничего не понимаю.
Ответить с цитированием
  #10  
Старый 12.12.2013, 15:14
Аватар для poli-smen
poli-smen poli-smen вне форума
Профессионал
 
Регистрация: 06.08.2012
Адрес: Кривой Рог
Сообщения: 1,791
Версия Delphi: Delphi 7, XE2
Репутация: 4415
По умолчанию

Цитата:
Сообщение от krasnyakjohn
Сделал, теперь ошибки нет, но поля перестали заполняться и кнопка не нажимается, но зато выскакивает ShowMessage Авторизация не прошла.
От добавления проверки перестало заполняться? Что-то мало верится.
Может перестало заполняться так как стали появляться ошибки типа "Элемент с id "id_username" не найден" - тогда конечно - это срабатывают проверки и заполняться при этом не должно, так как некуда.
Цитата:
Сообщение от krasnyakjohn
Может когда я второй раз перехожу по адресу опять идет поиск этих полей, но почему? Я ничего не понимаю.
Заполнение этих полей ведь находится только в обработчике события Button11Click ?
Ответить с цитированием
  #11  
Старый 12.12.2013, 15:24
krasnyakjohn krasnyakjohn вне форума
Прохожий
 
Регистрация: 12.12.2013
Сообщения: 13
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Да.. сложно поверить, но это так.

Если из обработчика удалить этот код:
Код:
WebBrowser1.Navigate('http://web.iqsms.ru/contacts/');
  while WebBrowser1.ReadyState<>4 do
  Application.ProcessMessages;
  Doc := WebBrowser1.Document as IHTMLDocument2;  // получили hmtl код страницы
  r := TRegExpr.Create;
  s:=Doc.body.innerHTML;
  r.InputString :=s; // во входяшую строку положили весь html код
  memo3.Text:=s;
try
  r.Expression :='<A href="/deliveries/add-delivery/">(.*?)</A>';
  if r.Exec(s) then
begin
    Groupbox8.Caption:='Отправить смс заказчику';
end
  else ShowMessage('Авторизация не прошла');
    finally
r.Free;
end;
end;

То происходит заполнение полей и нажимается кнопка входа. (Я это в webbrowser'е вижу, т.е происходит авторизация, а когда добавляю этот код, то не происходит и пишет "Авторизация не прошла")
Ответить с цитированием
  #12  
Старый 12.12.2013, 15:35
krasnyakjohn krasnyakjohn вне форума
Прохожий
 
Регистрация: 12.12.2013
Сообщения: 13
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Да, вот если убрать тот код, который я написал выше, то работает и авторизация проходит, если еще раз нажать "войти" с теми же данными, то прога вываливается на вашей проверке, что естественно, потому как страница открылась другая и естественно этих полей с таким id там нет.
Ответить с цитированием
  #13  
Старый 12.12.2013, 20:53
krasnyakjohn krasnyakjohn вне форума
Прохожий
 
Регистрация: 12.12.2013
Сообщения: 13
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Помогите..пожалуйста
Ответить с цитированием
  #14  
Старый 12.12.2013, 22:44
Аватар для poli-smen
poli-smen poli-smen вне форума
Профессионал
 
Регистрация: 06.08.2012
Адрес: Кривой Рог
Сообщения: 1,791
Версия Delphi: Delphi 7, XE2
Репутация: 4415
По умолчанию

Цитата:
Сообщение от krasnyakjohn
Код:
.....
  for f:=0 to WebBrowser1.OleObject.Document.forms.Length-1 do
  begin
     form:=WebBrowser1.OleObject.Document.forms.Item(f).elements;
        for i:=0 to form.Length-1 do
          if (form.item(i).type='submit')  then
          begin
          form.item(i).click;
          end;
 
  end;
Вот это место мне ещё не нравится. После того как мы нашли кнопку и кликнули по ней нужно тут же прерывать оба цикла, ведь по клику, я так понимаю, начнётся подгрузка страницы и по этой же причине желательно перед продолжением выдержать некоторую паузу.
Других недочётов я пока не вижу.
Ответить с цитированием
  #15  
Старый 13.12.2013, 22:09
krasnyakjohn krasnyakjohn вне форума
Прохожий
 
Регистрация: 12.12.2013
Сообщения: 13
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Цитата:
Сообщение от poli-smen
Вот это место мне ещё не нравится. После того как мы нашли кнопку и кликнули по ней нужно тут же прерывать оба цикла, ведь по клику, я так понимаю, начнётся подгрузка страницы и по этой же причине желательно перед продолжением выдержать некоторую паузу.
Других недочётов я пока не вижу.

Бред, вчера работало с вашими проверками, а сегодня не может найти id_username, хотя на сайте ничего не поменялось..
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

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

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 23:36.


 

Сайт

Форум

FAQ

Соглашения

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2025