WebBrowser画面の選択部分のソースの取得は?

解決


武田  2006-01-04 06:45:00  No: 19479

あけましておめでとうございます。本年もご指導をよろしくお願いいたします。
環境はWinXP Delphi6  Personalで、WebBrowserで表示しています。
早速ですが、ブラウザ(例Sleipnir)などで、画面のソース表示がありますが、中でも選択範囲のソース表示をしたいのですが、解決しません。

過去ログを参考に全体のソースは下記で取得できました。
memo1.Text:= OLEVariant(TformWebBrowser(ActiveMDIChild).WebBrowser1.Document as IHTMLDocument2).Body.InnerHTML;
選択部分を取得では、
 TformWebBrowser(ActiveMDIChild).WebBrowser1.ExecWB(OLECMDID_COPY , OLECMDEXECOPT_DODEFAULT);
 memo1.Text:= Clipboard.AsText;
とやってみましたが、文字列を取得できますが、ソースを取得できませんでした。
選択部分のソースを取得する方法をご指導いただけないでしょうか。m(_ _)m


白いおもち  2006-01-04 11:25:12  No: 19480

selection.createRange  で選択部分を取得できますよ

procedure XXX(Value: IHTMLDocument2);
var
  xAll: IHTMLElementCollection;
  xElement: IHTMLElement;
begin
  xAll := Value.all as IHTMLElementCollection;
{
  Memo1.Lines.Add( 'activeElement' );
  Memo1.Lines.Add( Value.activeElement.tagName );
  Memo1.Lines.Add( Value.activeElement.outerHTML );
  Memo1.Lines.Add( Value.activeElement.innerText );
}
  Memo1.Lines.Add( 'selection' );
  Memo1.Lines.Add( (Value.selection.createRange as IHTMLTxtRange).text );
  Memo1.Lines.Add( (Value.selection.createRange as IHTMLTxtRange).htmlText );
end;

参考
http://s.drmg.net/chd/dhtmldiver/htm/4_2_6_sourceviewer.htm


武田  2006-01-05 00:38:21  No: 19481

白いおもちさん、早速のご指導有り難うございました。
助かりました。正月の支えた餅がす〜っつと取れたみたいです。
また教えてください。m(_ _)m


武田  2006-01-05 06:50:52  No: 19482

白いおもちさん、解決を出しましたが、(もし、ごらんになっておられたら、)どうせなら白いおもちさんの方式で全文のソースを取得できないかと試みましたが、getElementsByTagName(で未定義とでます。
もし、よろしければ教えていただけないでしょうか。
Memo1.Lines.Add( (document.getElementsByTagName('HTML')[0].outerHTML ).htmlText );
勝手ながら、よろしくお願いいたします。


白いおもち  2006-01-05 08:28:06  No: 19483

IHTMLDocument2 には getElementsByTagName がないみたいです。(参考:MSHTML_TLB.pas)
IHTMLDocument3 には getElementsByTagName があるので、こっちに変えてみてください。
(なんで、IHTMLDocumentは1〜5 まであるのでしょうか?
また、それらはどのように使い分けするのでしょうか?
たれか教えてください)
とにかく、下のコードで getElementsByTagName が使えました。
'A' の代わりに 'HTML' を入れるとhtmlタグ下のソースが得られます。
ただし、Webサーバー上にあるhtmlファイルに書かれたそのままの形ではなく
整形された形で得ることになるようです。

///////////////
var
  I: Integer;
  xDoc3: IHTMLDocument3;
  xAll: IHTMLElementCollection;
  xElement: IHTMLElement;
begin
  xDoc3 := ie.ieObject.Document as IHTMLDocument3;
  xAll := xDoc3.getElementsByTagName('A') as IHTMLElementCollection;
  Memo1.Lines.Add( IntToStr( xAll.length ) );
  for I := 0 to (xAll.length -1) do
  begin
    xElement := xAll.item(I, varEmpty) as IHTMLElement;
    //Memo1.Lines.Add( xElement.tagName );
    Memo1.Lines.Add( IntToStr(I) + ':' + xElement.outerHTML );
  end;
///////////////

----------
役立つリンク:

COM Event Sink Generator
http://www.techvanguards.com/
もしくは、
TieAutomationコンポーネント 
http://www33.ocn.ne.jp/~takoyakusi/delphi/InternetProg.html
で、イベントシンク

ページの中でのOnClick、OnMouseOver、OnMouseOut とかのイベントの実装の仕方(何語?)
http://www.effie.co.il/default.asp?sec=printview&topic=delphiasp&lang=he

エレメント階層を調べる
http://www.microsoft.com/japan/msdn/library/default.asp?url=/japan/msdn/library/ja/jpisdk/dhtml/doc_object/doc_object.asp


白いおもち  2006-01-05 08:35:34  No: 19484

// 上のURLずれてた。正しくは、
// エレメント階層を調べる
// http://www.microsoft.com/japan/msdn/library/ja/jpisdk/dhtml/doc_object/scripting_elements_collections.asp
// おまけ

procedure TForm1.Button4Click(Sender: TObject);
var
  I,J,K,L: Integer;
  xDepth: Integer;
  xMsg: String;
  xDocument: IHTMLDocument2;
  xAll: IHTMLElementCollection;
  xElementBefore: IHTMLElement;
  xElement: IHTMLElement;
  xElementBeforeParent: IHTMLElement;

  xNode: TTreeNode;
begin
  Form2.Visible := True;
  Form2.TreeView1.Items.Clear;  // Tree
  xNode := Form2.TreeView1.Items.AddChild(nil, 'root');  // Tree

  xDepth := 0;
  L := 1;
  xDocument := ie.ieObject.Document as IHTMLDocument2;
  xAll := xDocument.all as IHTMLElementCollection;

  //xMsg := (xAll.item(0, varEmpty) as IHTMLElement).tagName;

  Form2.TreeView1.Items.BeginUpdate;  // Tree

  for I := 0 to (xAll.length-1) do
  begin
    xElement := xAll.item(I, varEmpty) as IHTMLElement;

    // I = 0 は特別扱い
    if I > 0 then
    begin

      xElementBefore := xAll.item(I-1, varEmpty) as IHTMLElement;
      xElementBeforeParent := xElementBefore.parentElement;

      // 1つ前のエレメントが現在のエレメントを含んでいる場合
      if xElementBefore.contains( xElement ) then
      begin

        // 階層をひとつ下げる
        xDepth := xDepth +1;
        L := 1;  //

      end
      else
      // 現在のエレメントを含んでいない場合
      begin

        // 現在のエレメントを含む親(xElementBeforeParent)が現れるまで、1つ前のエレメントの親から順番に階層を上げていく
        for J := xDepth downto 1 do
        begin

          xNode := xNode.Parent;  // Tree

          if (I = xAll.length) or (xElementBeforeParent.contains( xElement )) then
          begin
            L := L +1;
            Break;
          end;
          xElementBeforeParent := xElementBeforeParent.parentElement;

        end;
        xDepth := J;

      end;

      xMsg := xMsg + #13#10;

      for K := 1 to xDepth do
      begin
        xMsg := xMsg + '━';
      end;
      xMsg := xMsg + IntToStr(I) + '-' + IntToStr(xDepth) + '-' + IntToStr(L) + ' ';

    end;
      xMsg := xMsg + xElement.tagName + ':' + Copy(xElement.innerText, 1, 128); // 文字列が長い場合カット

    ////////////////////////
    // Tree

    xNode := Form2.TreeView1.Items.AddChild(xNode, xElement.tagName);

    // いろいろ属性表示
    if xElement.innerText <> '' then
      Form2.TreeView1.Items.AddChild(xNode, '[ innerText ]' + Copy(xElement.innerText, 1, 128) );
    if xElement.outerHTML <> '' then
      Form2.TreeView1.Items.AddChild(xNode, '[ outerHTML ]' + Copy(xElement.outerHTML, 1, 128) );
    if xElement.id <> '' then
      Form2.TreeView1.Items.AddChild(xNode, '[ id ]' + Copy(xElement.id, 1, 128) );
    if xElement.className <> '' then
      Form2.TreeView1.Items.AddChild(xNode, '[ className ]' + Copy(xElement.className, 1, 128) );

    Form2.StatusBar1.SimpleText := ' ' + IntToStr( Round( I / (xAll.length-1) * 100 ) ) + ' %';
    ////////////////////////
  end;

  // ツリーを展開
  for K := 0 to (Form2.TreeView1.Items.Count -1) do
  begin
    Form2.TreeView1.Items.Item[K].Expand(False);
  end;

  Form2.TreeView1.Items.EndUpdate;  // Tree

  Memo1.Lines.Add(xMsg);

end;


武田  2006-01-06 07:15:08  No: 19485

白いおもちさん、早速詳細なご指導有り難うございました。
これをじっくり検討してみます。
と、申しますのは、FireFoxのスクラップブックやWeBoxの選択部分だけ取り込む機能がありますが、それを試みてみようと思っています。
勉強になりました。有り難うございました。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加