本來以為網(wǎng)頁里的edit,memo等都和程序里的一樣,可以用句柄來控制,但后來才明白,它是不存在句柄的! 查了好久,前幾天看到一個(gè)關(guān)于QQ自動(dòng)申請(qǐng)的例子.主要就是控制網(wǎng)頁各種操作的!總結(jié)了一下,做出一個(gè)論壇灌水機(jī): 首先要在uses中引用mshtml單元. 代碼及分析如下: var hform:IHTMLFormelement; hdoc:ihtmldocument2; hall:ihtmlelementcollection; Hinput:IHTMLinputelement; iw:iwebbrowser2; hlen,tmploop:integer; vk:oleVariant; dispatch:IDispatch; begin if Assigned(webbrowse1) then ///保證網(wǎng)頁里有內(nèi)容;即已經(jīng)打開一個(gè)網(wǎng)頁! begin hdoc:=webbrowse1.document as ihtmldocument2; hall:=hdoc.get_all; hlen:=hall.get_length; ////以上幾步的操作為:將瀏覽器控件里的內(nèi)容賦給hdoc.取其所有標(biāo)識(shí),并算出總數(shù); ////下面的操作為:按總數(shù)循環(huán)找到用戶名和密碼的edit;并賦值; for tmploop:=0 to hlen-1 do begin vk:=tmploop; dispatch:=hall.item(vk,0); if succeeded(Dispatch.QueryInterface(IHTMLInputelement,hinput)) then ///如果此標(biāo)識(shí)是一個(gè)edit控件..... begin ////下面這里的uppercase是必需的!防止因大小寫的不同而判斷失誤! ///下面的"TEXT"是由網(wǎng)頁里的內(nèi)容來確定的.也就是說你要判斷就必需根據(jù)具體網(wǎng)頁代碼來! ///密碼框和用戶名處是一樣的! if uppercase(hinput.Type_)='TEXT' then hinput.value:='tresss' else if uppercase(hinput.type_)='PASSWord' then hinput.value:='tresss'; end; if succeeded(dispatch.QueryInterface(IHTMLFormElement,hform)) and (uppercase(hform.name)='THEFORM') then ///此處是form提交.如果從html發(fā)現(xiàn)只有一個(gè)form的話那第二個(gè)條件是非必需的! ///而且也不一定要判斷name屬性,也可以根據(jù)其它屬性來判斷. Hform.submit; end; ////for end; end; //if end; end; 到此,,一個(gè)自動(dòng)登陸的例子就作好了..如果要實(shí)現(xiàn)灌水的話,,可以將hinput:ihtmlinputelement換成htext:ihtmltextareaelement,也就相當(dāng)于memo控件.將用戶名的賦值換成是發(fā)言的賦值就好;當(dāng)然這里還可以換成是其它的,如單選等...具體內(nèi)容可以查看mshtml里的列表! 本來到這里已經(jīng)夠了.但是后來發(fā)現(xiàn)--原來論壇里是有框架--frame的.好長(zhǎng)一段時(shí)間被此困擾著,后來在csdn上問了一下,有人給出了解決方法,試了一下很不錯(cuò)! 上面的代碼里可以加入: var ...... ...... iw:iwebbrowser2; begin ..... iw:=getframe(3); //此步即是取得webbrowse里的第二個(gè)框架; ///而后的操作都是一樣的,也就是上面的操作的作用是將一個(gè)框架里的內(nèi)容來作為一個(gè)網(wǎng)頁來處理; hdoc:=iw.document as ihtmldocument2; hall:=hdoc.get_all; ...... ...... ///getframe() 函數(shù)如下需要在uses里加入activex單元:
Function TFrmain.GetFrame(FrameNo:Integer):IWebbrowser2; var OleContainer:IOleContainer; enum:IEnumUnknown; unk:IUnknown; Fetched:PLongint; begin while webbrowse1.ReadyState<>READYSTATE_COMPLETE do application.PRocessMessages; if Assigned(webbrowse.document) then begin Fetched:=nil; OleContainer:=webbrowse.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;
還有要說明的一點(diǎn)就是網(wǎng)頁里框架的跳轉(zhuǎn)!依然是使用的navigate 但是需要兩個(gè)參數(shù)! webbrowse.navigae('要轉(zhuǎn)到的網(wǎng)頁地址',flag1,flag2); 其中兩個(gè)參數(shù)的類型是:olevariant; 第一個(gè)參數(shù)不需要賦值,它控制的是網(wǎng)頁打開的其它選項(xiàng)(如:在新網(wǎng)頁中打開.等). 我們所要操作的是第二個(gè)參數(shù).這里你要先打開網(wǎng)頁的源文件,查看他的frame的name屬性!記住所要控制的frame的name把它的值賦給flag2就可以了!這樣就是在一個(gè)frame中打開一個(gè)網(wǎng)頁! 這樣的話,加上一個(gè)timer再加上一些代碼就可以作成一個(gè)完整的灌水機(jī)了! |