如何求得含有多層 Frame 的網頁中全部 INPUT 項目?(150分)

  • 主题发起人 主题发起人 jiichen
  • 开始时间 开始时间
J

jiichen

Unregistered / Unconfirmed
GUEST, unregistred user!
拜大富翁之前的文章所賜,已能求得一網頁中的 INPUT 的值了,
但遇上有 frame 的網頁就沒辦法了,之前相關文章資訊太少,
或寫的很簡潔,對我這個初學者而言,實在看不懂,請高手相助,謝謝!

最後方法中能含有使用 IHTMLFramesCollection2 的相關語法!
如果使用 OleVariant 也行,不過我便要重寫了 :(

半成熟品在此,為一自動申請免費空間的軟體!
<a href="http://home.kimo.com.tw/lookbook2000/GetSpaces1.htm">
http://home.kimo.com.tw/lookbook2000/GetSpaces1.htm</a>

 
55555555...自問自答 !

hf2:IHTMLFramesCollection2;

hf2:=doc.frames;

for i:=0 to hf2.length-1 do
begin
....
end;


有時會發現,無框架之網頁其 hf2.length 並不等於 0
這是為什麼呢!因為有些網頁使用了 iFrame 的技術,
而它也含在內,所以
在判斷時要加一步
if not SUCCEEDED(spDisp.QueryInterface(IHTMLIFrameElement ,iiFrameEle))then
來排除,...

可是又發現有的網頁卻能突破此封鎖,奇怪,
可惜只研究至此,就偷懶地
使用 try...except 來封鎖錯誤訊息了!

由於使用時大都利用 IDispatch,所以
寫個小程序將全部物件都放在一起,
不管有無框架都通吃,
不過還是有缺點,應該有方法可將它們
都放進一個 IHTMLElementCollection
這樣要用時再利用 OleVariant 來找就方便多了。

iec:IHTMLElementCollection;
item:OleVariant;

item:=all.item(pp,0); // pp 可為 index 或 name

看看高手是否願意再補述一番。


var
ObjList:array of IDispatch;
ObjListCount:integer;

procedure TForm1.UpdateObj;
var
doc:IHTMLDocument2;
begin
// 更新網頁上的物件至 ObjList
//
SetLength(ObjList,3000);
ObjListCount:=0;

doc:=web.Document as IHTMLDocument2;

if doc<>nil then
UpdateObj2(doc);
end;


procedure TForm1.UpdateObj2(doc:IHTMLDocument2);
var
tmpDoc:IHTMLDocument2;
all: IHTMLElementCollection;
spDisp:IDispatch;
i:integer;
HtmlWin:IHTMLWindow2;
iFrameB2:IHTMLFrameBase2;
iFramei:IHTMLIFrameElement;
iFrame:IHTMLFrameElement;
begin
//
all:=doc.Get_all;

for i := 0 to all.length-1 do
begin
application.ProcessMessages;
spDisp:=all.item(i,0);

ObjList[ObjListCount]:=spDisp;
inc(ObjListCount);
if (High(ObjList)-ObjListCount)<50 then
SetLength(objList,High(ObjList)+1000);

// Frame...
// 避開 iFrame 成員

if not SUCCEEDED(spDisp.QueryInterface(IHTMLIFrameElement ,iFramei))then
begin
if SUCCEEDED(spDisp.QueryInterface(IHTMLFrameElement ,iFrame)) and
SUCCEEDED(spDisp.QueryInterface(IHTMLFrameBase2 ,iFrameB2)) then
begin
spDisp:=iFrameB2.contentWindow;

if SUCCEEDED(spDisp.QueryInterface(IHTMLWindow2 ,HtmlWin))then
begin
if HtmlWin<>nil then
begin
try
if SUCCEEDED(HtmlWin.document.QueryInterface(IHTMLDocument2 ,tmpDoc)) then
begin
UpdateObj2(tmpDoc);
end;
except
end;
end;
end;
end;
end;
end; // for
end;




 
嗯!還是沒人回答,不過我已經解出了,
先不講怎樣求得全部 Frame 的內容,再出各新題!

如何將網頁上的圖片複製至 TBitmap 內?
要求一: 不可使用 TNMHTTP 之類的來利用圖片 url 來抓取,
因為 url 會改變,並且網站會搭配其他條件來秀出不同的圖,
這樣就跟網頁上的圖形不同了。
此圖形的類型有兩種(至少),
一是 IHtmlImgElement , 無疑問是圖形
一是 IHtmlInputElement ,Type=image 的圖形

此問題目前分數已提高至 300 分了,請參考
http://www.delphibbs.com/delphibbs/DispQ.asp?LID=435982
兩題共 300 分!

 
找出其SRC,在CACHE中找吧,哈哈。
开玩笑
 
在 cache 不失為一種法子,不過要如何得知想要的圖片
位於 cache 中的哪一個檔呢?

 
附加功能 将问题提前
 
能告诉我你是如何得到input的值吗?多谢!
dana@shd.com.cn
 
唉!都沒啥收穫....

好吧!反正各人手法不同,便 Post 出來大家看看吧!
當然啦!有好的方法,或找出什麼問題,一樣給分。


底下是我 GetSpaces 中的一段。



function TForm1.ParsmDoc2(doc2:IHtmlDocument2):boolean;
var
idoc2:IHtmlDocument2;
iweb2:IWebBrowser2;

pDisp:IDispatch;

all:IHTMLElementCollection;

i : integer;
oi:OleVariant;

vr:boolean;
begin
//
//
result:=false;
vr:=true;

if doc2=nil then
exit;

try
all:=doc2.all;

SrcText.add(doc2.body.innerText);
SrcHtml.add(doc2.body.innerHtml);
except
exit;
end;

for i := 0 to all.length-1 do
begin
oi:=i;
pDisp:=all.item(oi,0);

// ======== 重要的一步 =======
// 依自己需求而定~


// 接著審核是否有需遞迴之物----------
if Succeeded(pDisp.QueryInterface(IWebBrowser2,iweb2)) then
begin
idoc2:=(iweb2.document as IHtmlDocument2);
vr:=ParsmDoc2(idoc2);
end;

if Succeeded(pDisp.QueryInterface(IHtmlDocument2,idoc2)) then
begin
idoc2:=(iweb2.document as IHtmlDocument2);
vr:=ParsmDoc2(idoc2);
end;

//-------------------------------------
end; // for

result:=true and vr;
end; // procedure


 
jiichen,看来你对DHTML对象模型编程有些研究,能告诉我如何在Delphi中实现网页中的
submit按钮的OnClick事件?
 
一般是使用 IHTMLElement.click; 即可。
 
多人接受答案了。
 
后退
顶部