none
WebBrowserコントロールからフレームを利用したのページのHTMLソース取得方法 RRS feed

  • 質問

  • WebBrowserコントロールを利用して表示したHTMLのソースを自動的に保存するプログラムをVisual C#2005で作成しようとしています。

    フレームのないページであれば、NavigatedイベントでwebBrowser1.DocumentTextを保存することで目的どおりのプログラムが出来たのですが、フレームを使用したページでは、親のページがフレームの数だけ保存されるだけで、フレーム側のソースが保存できませんでした。

    フレーム側のHTMLソースの取得方法をご存知の方がいらっしゃいましたらご教授いただけないでしょうか?

    よろしくお願いします。

    2006年4月19日 2:15

すべての返信

  • 試してませんが、以下で取得できませんでしょうか?

    HtmlWindow.WindowFrameElement Property 
    http://msdn2.microsoft.com/en-us/library/system.windows.forms.htmlwindow.windowframeelement(VS.80).aspx

    2006年4月19日 10:07
    モデレータ
  • HtmlWindow.Frames でフレームの列挙はできるので(万全を期すなら列挙は再帰的に行う必要があるでしょう)、あとはどうやってその辺からソースを取得するかですね。

    単純にやるなら、HtmlDocument から Body.ParentElement.OuterHtml で取得できますが、これは DOM 解析済みの HTML が返るのでもとのソース通りというわけにはいきません。

    WebBrowser.DocumentStream は、HtmlDocument から IPersistStreamInit と言う COM インターフェイスを取得し、これの Save を IStream を実装するクラスに行うことで目的を達成しているようです。

    // DocumentText はこの DocumentStream から文字列を読み込んでるようですが、エンコーディングが UTF-8 固定ですね……。HtmlDocument.Encoding とか使えばいいのに。

    残念ながらこれらのインターフェイス/実装クラスは公開されていないので(IStream はSystem.Runtime.InteropServices.ComTypes に存在していたっけか)、自前で宣言・実装する必要がありますが。

    // HtmlDocument にも ContentStream とかなんとかそんな感じのプロパティがあって然るべきだと思うんですがね。WebBrowser クラスにしか実装しない意味が分かりません。

    2006年4月19日 15:05
  • trapemiyaさん、回答ありがとうございます。

    WindowFrameElementを試してみましたが、親のHTMLのFrame定義のエレメントが入るようです。とりあえず、これを使うことで、Frameの名前や、取得先のURLは取れるのですが、目的のフレーム内のHTMLを取得する方法は見つかりませんでした。

    静的なページのソース取得であれば、取得先がこれでわかるのでHttpWebRequestでもう一度とりにいく方法もあるかと思うのですが、CGIページの場合、2重送信になってしまうため、あまりいい方法ではないため、悩んでおります。

    何か他にいい方法があればご教授ください。よろしくお願いします。

    2006年4月20日 4:06
  • Hongliangさん、回答ありがとうございます。

    できることなら、オリジナルのソースを取得したいのですが、DOM解析済みのものでも取得できないよりは良いかと思っています。

    不勉強で申し訳ないのですが、どうすればHtmlWindow.FrameからHtmlDocumentを作れるのかを教えていただけないでしょうか?

    //DocumentCompleteイベントや、Navigatedイベントが子フレームのHTMLを取得するタイミングでも呼ばれ、また、EventArgsに取得した子フレームのURLがセットされているのだから、URLだけでなく、取得したDocumentもArgsにセットしてくれてもいいと思うんですが...

    2006年4月20日 4:30
  •  vetj さんからの引用

    不勉強で申し訳ないのですが、どうすればHtmlWindow.FrameからHtmlDocumentを作れるのかを教えていただけないでしょうか?

    Frames は HtmlWindow のコレクションですよね? HtmlWindow には Document プロパティがありますよね?

    2006年4月20日 5:51
  • FramesのDocumentは、親となるフレーム定義のページのFrame定義部分のDocumentになりませんか?Frames.Document.Body.Parent.OuterHtmlを出力してみたのですが、親ページのDom解析後のソースが出力されました。

    フレームページのソース取得をするためにはWebBrowserコントロールは向いていないのでしょうか。

    2006年4月20日 23:59
  • Frames(HtmlWindowCollection)には Document プロパティなんて存在していませんが。


    foreach (HtmlWindow window in webBrowser1.Document.Window) {
        Debug.WriteLine(window.Document.Title);
    }

     

    ではちゃんととれてますね。

    ところで、メモリ上で処理することばかり考えていたので IPersistStreamInit を挙げましたが、ファイルに保存するだけなら System.Runtime.InteropServices.ComTypes.IPersistFile を使えば簡単に実現できます。

    HtmlDocument の DomDocument を IPersistFile にキャストして Save メソッドを使うだけ。

    2006年4月21日 0:45