如何实现自动登陆网站 ( 积分: 100 )

  • 主题发起人 主题发起人 寂寞的鸭子
  • 开始时间 开始时间

寂寞的鸭子

Unregistered / Unconfirmed
GUEST, unregistred user!
我是用WebBrowser控件来实现的,在一个循环里面做WebBrowser.Navigage(url),WebBrowser的OnDocumentComplete事件里面处理登陆用户和密码,但是现在的问题是,循环只有最后一次才会触发OnDocumentComplete事件,这是怎么回事?
 
是不是我的问题描述的不清楚啊?怎么没人帮忙?
再顶一下。
 
现在人气不旺呀,我刚刚完成一个自动登陆考勤的软件,现在公司不能上QQ没法子给你,
 
不要紧,我帮我的源码贴出来,文生你帮我看看有什么问题,软件没在手头上,只能贴点伪代码。
//登陆按钮事件
Procedure Form1.LoginBtnOnClick(Sender : TObject)
var
i : Integer;
begin
for i := 0 to UserList.count - 1 do //UserList是登陆用户列表
begin
Wb.Navigate(URL);//Wb是WebBrowser
UserName := UserList.Strings;
Password := PwdList.Strings;
iState := 0; //iState用来做状态标识
end;
end;

Procedure WbOnDocumentComplete();
begin
if iState = 0 then
begin
//当登陆页面打开时,找到用户和密码输入框,输入相应的值
Wb.Submit;//提交
iState := 1;
end
end;
我的理解是Wb.navigate不是多线程方法,那么在循环体内的每次navigate肯定会触发OndocumentComplete事件,并且是按顺序执行的,但是实际情况却是只执行了最后一次,这是为什么?
 
你所在提交的网页上面有没有FRAME呢?
如果有:用下面的代码找到FRame
uses MSHTML;

procedure TForm1.Button1Click(Sender: TObject);
var
doc,frm: IHTMLDocument2;
iw: IWebbrowser2;
i: integer;
begin
doc := WebBrowser1.Document as IHTMLDocument2;
for i := 0 to doc.frames.length-1 do
begin
iw := GetFrame(i);
frm := iw.Document as IHTMLDocument2;
Memo1.Lines.Add('============== Frame ' + IntToStr(i) +' ==================');
Memo1.Lines.Add(frm.body.outerHTML);
end;
end;

function TForm1.GetFrame(FrameNo: Integer): IWebbrowser2;
var
OleContainer: IOleContainer;
enum: IEnumUnknown;
unk: IUnknown;
Fetched: PLongint;
begin
while Webbrowser1.ReadyState <> READYSTATE_COMPLETE do
Application.ProcessMessages;
if Assigned(Webbrowser1.document) then
begin
Fetched := nil;
OleContainer := Webbrowser1.Document as IOleContainer;
OleContainer.EnumObjects(OLECONTF_EMBEDDINGS, enum);
Enum.Skip(FrameNo);
Enum.Next(OLECONTF_EMBEDDINGS, Unk, Fetched);
Result := Unk as IWebbrowser2;
end
else
Result := nil;
end;
 
再就是单纯的找到网页上面的控件了,找到控件的方法有好多种,然后再填值
下在的代码是我的登陆考勤的代码,填写用户帐号和密码,并点按钮


var
Htm:olevariant;
k:integer;
t:OleVariant;
begin
while WebBrowser1.ReadyState <READYSTATE_COMPLETE do
Application.ProcessMessages;
sleep(2000);
t := WebBrowser1.Document;
htm:=t.all.item(0,varEmpty);
for k := 0 to t.all.length - 1 do
begin
if (uppercase(t.all.item(k).tagName)='INPUT')and(uppercase(t.all.item(k).type)='TEXT') and (uppercase(t.all.item(k).name)='USERNAME') then
begin
t.all.item(k).value:=UserID;
RichEdit1.Lines.Add('填写用户名称:'+UserID+'时间:'+FormatdateTime('c',now));
end;
if (uppercase(t.all.item(k).tagName)='INPUT')and(uppercase(t.all.item(k).type)='PASSWORD') then
begin
t.all.item(k).value:=UserPwd;
RichEdit1.Lines.Add('填写用户密码:'+UserPwd+'时间:'+FormatdateTime('c',now));
end;
if (uppercase(t.all.item(k).tagName)='INPUT')and(uppercase(t.all.item(k).type)='SUBMIT') and (uppercase(t.all.item(k).name)='SUBMIT') then
begin
t.all.item(k).click;
RichEdit1.Lines.Add('点击登陆按钮,时间:'+FormatdateTime('c',now));
while WebBrowser1.ReadyState <READYSTATE_COMPLETE do
Application.ProcessMessages;
sleep(2000);
//WebBrowser1.Navigate('http://169.254.0.15:86//general/table_index.php');
WebBrowser1.Navigate(CUrl+'general/attendance/personal');
end;
end;
end;
 
非常感谢,手头上的机器没装delphi,回去试试。
我的登陆页面是单页面,所以我直接用Form.submit方法提交的。
找控件也是使用doc.all.item(控件名,0)的方法。但是循环之间没有用延时,因为要考虑当时的网络情况。
另外不是很明白你后一段程序里面
while WebBrowser1.ReadyState <READYSTATE_COMPLETE do
Application.ProcessMessages;
sleep(2000);
又有Application.ProcessMessages又有sleep(2000),是何解?
 
不好意思,我是用别的机器上的网
上午没时间给你回

while WebBrowser1.ReadyState <READYSTATE_COMPLETE do
Application.ProcessMessages;
这句保证webbrowser是否将网页完全下载完成
 
sleep(2000), 表示延时2秒,我加这句的目的也是给Webbrowser足够的时间下载网页,其实只用
while WebBrowser1.ReadyState <READYSTATE_COMPLETE do
Application.ProcessMessages;

就可以了,我的QQ:372199229 可以先加上,等我能上网时聊聊



单页面的话就用第二个方法就可以了
====================
来自:文生, 时间:2007-2-28 9:58:49, ID:3673857 | 编辑
再就是单纯的找到网页上面的控件了,找到控件的方法有好多种,然后再填值
下在的代码是我的登陆考勤的代码,填写用户帐号和密码,并点按钮


var
Htm:olevariant;
k:integer;
t:OleVariant;
begin
............................
=========================


就是找到元件,触发相应的事件
 
1/Form.submit方法 我没有用过,我不太清楚
2/要考虑当时的网络情况
所以我用了while WebBrowser1.ReadyState <READYSTATE_COMPLETE do
Application.ProcessMessages;
sleep(2000);
 
后退
顶部