WebBrowserでソースの書き換え


SIR  2006-04-10 04:06:24  No: 94992

現在WebBrowserコントロールを使って表示しているサイトの
ソースを直接書き換えて表示するアプリを作成しているのですが、
今のところ、
1.ソースを取得し、テキストボックスに表示
2.テキストボックスに表示したソースを変更し、WebBrowserコントロールに返す
まではできたのですが、ここで問題が発生しました。
2.のところで、
    Dim Doc As Object
    Set Doc = WebBrowser.Document
    
    Doc.Write (txtSource.Text)
としているのですが、この後書き換えたHTMLを表示させると画像等が
すべて読み込まれておりません。
試行錯誤した結果、
<a href="http://.../test.html">test</a>
<a href="test.html">test</a>
ソースを書き換えた後に上記リンクをクリックすると、上は正常にリンクでき、
下はリンクできないということから、ロケーションが変わっているっぽいのが
原因だと思うのですが、どのように対処すればよいのかが分かりません。
(書き換える前と後のWebBrowser.LocationURLを確認しても変化ありません。)
お知恵をお貸しできないでしょうか?


あ!  2006-04-10 23:17:17  No: 94993

WebBrowserでダイレクトにDocumentを取得する前に自分のハードデスクにそのサイトをHtmlで保存してから書換えを行ってみてはいかがですか?
IE.[ファイル][名前を付けて保存]で圧縮しないでHtmlで保存すればロケーションが自分のハードデスクになります。プログラムからこれを実行するのはたしかWebbrowserからはできなかったと思います。
IEのオブジェクトを取得してSendMessageかなにかでできると思います。
間違っていたらごめんなさい。


SIR  2006-04-11 10:10:42  No: 94994

お返事ありがとうございます。

ご指摘していただいた方法ですと、IEにてサイトを閲覧しながらその都度、
ソースを書き換えたいページにてHTMLをローカルに保存してそこからIEへ読み込ませる
という感じだと思うのですが、できればIEを使用しない方法を考えています。

具体的には、WebBrowserコントロールにてサイトを閲覧しながら、書き換えたいページにて
ソースをテキストボックスに表示し、書き換えて、WebBrowserで反映させるのが
理想です。
似たようなツールでProxomitronがありますが、正規表現で特定のHTML文を書き換えるなく、
任意のHTML文を自由に書き換えられるようなものを作りたいと思っております。

ただ、
> IEのオブジェクトを取得してSendMessageかなにかでできると思います。
これについては、プログラムからIEのロケーションを強制的に変更できるという
ことなのでしょうか?
もしそうならば、こちらのその方が簡単?に実現できそうだと思うのですが。。。


あ!  2006-04-11 16:02:04  No: 94995

>できればIEを使用しない方法を考えています。
WebBrowserもIEではないでしょうか?

>> IEのオブジェクトを取得してSendMessageかなにかでできると思います。
>これについては、プログラムからIEのロケーションを強制的に変更できるという
>ことなのでしょうか?
違います、IEからハードデスクに保存という手順がWebBrowserのコマンドにないのでダイレクトにIEのツールバーにSendKeyみたいにKeyを送っているだけです、
SendKeyだとタイミングが難しいのと不確実なのでSendMessageを使っただけです。


魔界の仮面弁士  2006-04-11 18:49:28  No: 94996

> この後書き換えたHTMLを表示させると画像等が
> すべて読み込まれておりません。
document.write() を使ったり、document そのものを変更した場合、
元のロケーションは引き継がれません。そのため、<img src=""> などは、
相対 URL ではなく、絶対 URL にて記述せねばなりません。

もしもロケーションを引き継ぐのであれば、このように書く事ができます。

Option Explicit

Private Sub Form_Load()
    WebBrowser1.Navigate "http://www.google.co.jp/"
End Sub

Private Sub Command1_Click()
    With WebBrowser1.Document.images(1)
        .src = "/intl/ja_jp/images/local_res_logo3.gif"
        .Width = 150
        .Height = 55
    End With
End Sub

Private Sub Command2_Click()
    Dim Doc As Object, Body As Object
    Dim Img As Object, Div As Object
    Set Doc = WebBrowser1.Document
    Set Body = Doc.Body
    
    Set Div = Doc.createElement("DIV")
    Div.Style.TextAlign = "center"
    Set Img = Doc.createElement("IMG")
    Img.src = "/intl/ja_ALL/images/images_hp.gif"
    Img.Width = 276
    Img.Height = 110
    Img.alt = "新しいイメージ"

    Div.appendChild Img
    Body.insertBefore Div, Body.firstChild
End Sub

> (書き換える前と後のWebBrowser.LocationURLを確認しても変化ありません。)
WebBrowser 側からは判断できません。HTMLDocument 側に問い合わせてください。
    MsgBox WebBrowser1.Document.location.href
    MsgBox WebBrowser1.LocationURL

----
> IE.[ファイル][名前を付けて保存]で圧縮しないでHtmlで保存すれば
当方の IE では、『圧縮』して保存するという機能が見当たりませんでしたが、
「Web ページ、HTML のみ」モードで保存した場合は、WebBrowser.document を 
IPersistFile.Save() した場合と、同等の HTML ファイルが生成されます。
このモードでは、<img src="相対URL">等は変化しません。
一方、「Web ページ、完全」モードで保存した場合は、画像等が
保存名.files フォルダに保存され、<img>等は、それを利用して
表示するように変化しますね。

> ロケーションが自分のハードデスクになります。
# デスク(desk)ではなく、ディスク(disc/disk)ですよね。

> プログラムからこれを実行するのはたしかWebbrowserからはできなかったと思います。
IOleCommandTarget.Exec の呼び出しだけが目的であれば、
WebBrowser.ExecWB() が使えるかも。(OLECMDID_SAVEAS とか)


SIR  2006-04-12 12:19:48  No: 94997

お返事ありがとうございます。

あ!さんの仰っていることがなんとなく判りました。
ただ、やっぱりその方法ですと、ロケーションはハードディスクからになってしまい、
例えば、ロケーションをチェックして外部からの場合は、TOPページに飛ばす構成の
サイトでは不具合がでるかなと思いまして、ロケーションを閲覧しているサイトのまま
書き換えられないかと思っています。

魔界の仮面弁士さんの提示して下さったソースをこちらで確認致しましたところ
きちんと画像が切り替わり動作確認が取れました。
ただ、この場合取得したソースを変更し、反映させるのが難しいかなと思いまして、
変更したソース全体を、WebBrowserコントロールに送り付けられないかと考えています。

また、こちらの方でも動作についていまいち判っていないのですが、下記のようなソースを
見まして、現在ちょっと試していて、
http://support.microsoft.com/default.aspx?scid=kb%3Bja%3B272760

下記のコードを作りましたがGoogle等ではエラーが出てしまいますが、簡単な構成のサイトでは
うまく動作し、ロケーションの問題も出ませんでした。

Option Explicit

Private Sub Form_Load()
    WebBrowser1.Navigate "http://www.kisaragiweb.jp/pi/index.htm"
End Sub

Private Sub Command1_Click()
    Dim strTmp As String
    Dim strScript As String
    Dim Doc As Object
    
    strTmp = WebBrowser1.Document.All.tags("html")(0).outerHTML
    
    ' ページの最後に変更したことを示すサインを入れる。
    strTmp = Replace(strTmp, "</body>", "<font size=50>変更しています。</font></body>", , , vbTextCompare)
    
    strTmp = Replace(strTmp, "\", "\\")
    strTmp = Replace(strTmp, Chr(34), "\" & Chr(34))    'Chr(34) ->「"」
    strTmp = Replace(strTmp, Chr(39), "\" & Chr(39))    'Chr(39) ->「'」
    
    strTmp = Replace(strTmp, vbCrLf, "\n")  '他にもChr(10)とChr(13)を書き換えた方が良さそう?
    
    strScript = ""
    strScript = strScript & "<span style=" & Chr(34) & "display:none" & Chr$(34) & ">h</span>"
    strScript = strScript & "<script defer=true language=" & Chr(34) & "javascript" & Chr(34) & ">"
    strScript = strScript & "function insertMyHTML(){"
    strScript = strScript & "   var alltext = " & Chr(34) & strTmp & Chr(34) & ";"
    strScript = strScript & "   document.open();"
    strScript = strScript & "   document.write(alltext);"
    strScript = strScript & "   document.close();"
    strScript = strScript & "}"
    strScript = strScript & "</script>"
    
    Set Doc = WebBrowser1.Document
    
    Doc.documentElement.insertAdjacentHTML "beforeEnd", strScript
    Doc.parentWindow.execScript "insertMyHTML()", "jscript"
End Sub

Google等でのエラーの原因はjscriptを使ってソースを吐き出すため、
「"」や「'」を「\"」や「\'」に変えなくてはならないという風な類のものかと
思ったのですが、jscriptにはちょっと疎くて、本当にその類のものなのか、
それとも、そもそもが複雑なソースは吐き出せないのか分からず、試行錯誤しています。


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

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






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