HPのhtmlファイルを保存し、そのファイルの必要事項を検索して
抜粋し、表示させたいのですが、inetコントロールを使用して
ファイルを保存するとhtmlタグも一緒に保存される為、思い通りに
処理ができません。
何かよい方法がありましたらご教授お願いします。
HTMLをダウンロードしているんですから、当然タグは消えません。
消してから処理をしたいのなら、自分で消すしかないでしょう。
(正規表現を使えば簡単に消せますけどね、DLLとか)
早速のご返答ありがとうございます。
具体的にどのように処理するのが最善でしょうか。
また、このような処理を行う場合、
・ファイルをダウンロードして処理
・直接データを取得(Inet.GetChunk)して処理
どちらが一般的なのでしょうか。
先日始めたばかりなのでご指摘お願いします。
こういう事でしょうか?
Option Explicit
Private Sub Form_Load()
'別途プロジェクト→コンポーネントで Microsoft Internet Control に
'チェックを入れてWebBrowserコントロールをフォームに貼り付けて下さい。
'HTMLファイルを表示
WebBrowser1.Navigate "http://www.bcap.co.jp/hanafusa/top.htm"
End Sub
Private Sub Command1_Click()
Text1.Text = WebBrowser1.Document.body.innerText
End Sub
通りすがりに失礼
これは便利ですね。
勉強になりました
上記のコードを試した所希望通りの結果が得られましたが、
以下のようにしたところ問題が発生しました。
Private Sub Command1_Click()
WebBrowser1.Navigate "http://www.bcap.co.jp/hanafusa/top.htm" ①
Text1.Text = WebBrowser1.Document.body.innerText ②
End Sub
(注:form_load()の①のコードはコメントアウトしてます)
【問題点】
webbrowserコントロールには指定したサイトが表示されましたが、
textコントロールには"ページが表示されません…"等のエラー時の
メッセージが表示されました。
デバックで②にブレークポイントを設定して行うとtextコントロール
に正常なデータが表示されました。
【別問題点】
デバック作業を繰り返し行うとメモリー不足の警告がでますが、
メモリーを解放する処理を入れる必要はあるのでしょうか。
(注:webbrowserコントロールを使用してから事象が発生しました)
お手数ですがよろしくお願いします。
わたしの言った方法での返信だけ
>2003/06/12(木) 22:41:54
> 早速のご返答ありがとうございます。
> 具体的にどのように処理するのが最善でしょうか。
この方法の場合、ごく普通にダウンロードしてください。
その時点では、タグ入りのテキストファイル(HTML)ですね。
ですから、ダウンロードを済ませた後でそれから処理をしていくことになると思います。
そのあと、タグを削除していくことになります。
VBだけでやるのならば、InStrで<を探しつつ、>がでたら<から>までを削除、というめんどくさい処理をしていくしかないでしょうね。
(たまたま表示できている<を見つけて消してしまったというのは、HTMLの作者が悪いのです、気にしないでいきましょう。
文中に表示する<や>は、ちゃんと特殊文字で書かないといけないんですjから)
正規表現を使えば、こんなことをしなくてもすみます。
BRegExpというDLLを使えば、正規表現を使って置き換えられますから、
<から>までを消すような正規表現を使って消してしまいましょう。
わたしの言った方法は、とりあえず環境に依存しません。
WebBrowserを使った方法だと、WebBrowserコントロールが使えない環境、もしくは言語では、使えません。
(これが使えない環境は、いまさらないと思いますけど、コントロールの呼び出しができない、または面倒な言語なら、いくつか知ってます)
まあ、わたしはWebBrowserを使ったことがないから、
その方法を思いつかなかっただけなんですけどね。
> textコントロールには"ページが表示されません…"等のエラー時の
> メッセージが表示されました。
WebBrowserはページを「非同期」で表示します。
つまり、NavigateメソッドやNavigate2メソッドでページに移動しても、
それが表示されきらないうちに、次の行が実行されてしまう可能性が
あるというわけです。
Navigate系メソッドの完了は NavigateComplete系イベント、そして
文書の読み込み完了はDocumentCompleteイベントの発生によって
判定できます。まずは、これらを利用してみてください。
もし、何らかの理由でイベントを使う事ができないようであれば、
とりあえずは、「WebBrowser.Busy が False になり、かつ、
WebBrowser.Document.readystate が complete になる」まで、
DoEventsを挟んだループ処理で待機させるという方法でも、
判定する事が可能だと思います。
なお、ページを保存するに当たっては、
・フレーム(FRAME)やインラインフレーム(IFRAME)を利用したページ
・スクリプトやクッキーなどの利用によって、内容が変化するページ
などの扱いに注意して下さい。
(そうしたページは扱わない、というのであれば良いのですが)
フレームを使ったページの場合、フレームによって呼ばれる
別ページの内容を、再帰的に取得していく必要があります。
また、スクリプトが使われているページなどでは、単純に
HTMLソースを(Inet, ServerXMLHTTP, VB.UserControlなど)で
ダウンロードしただけでは、スクリプト実行前のテキスト情報しか
取得出来ませんので、実質、InternetExplorerオブジェクトもしくは
WebBrowserコントロールに頼る事になるでしょう。
# スタイルシートでdisplay:noneなどが指定されたエレメントが
# 出現した場合の処理なども必要ですから、厳密に作りこもうとすると
# 結構、面倒な事になるかと思います。ある程度の妥協は必要かも。
> (たまたま表示できている<を見つけて消してしまったというのは、HTMLの作者が悪いのです、
そうとは言い切れないのでは無いでしょうか。
テキストデータは、#PCDATAな領域だけではなく、CDATAな領域に
出現する可能性もありますから。。。CDATA部であれば、"<"が
実態参照なしで出現しても、文法的には問題無いような気がします。
> テキストデータは、#PCDATAな領域だけではなく、CDATAな領域に
出現する可能性もありますから。。。
CDATAというと、タグの中の値の文字列のことですよね?
あれもたしか、実体参照にしないとまずいとされています。
よくHTMLからCGIを呼び出すとき、href="…何とか&何とか…" とか書きますが、
これも本当は、…何とか&何とか… と書かなければいけません
(&のままでもいいのは、ただの偶然)
と書いてありました。
(Anothor HTML Lintの解説ページより)
# 話題が脱線しています。申し訳ありません>元質問者どの
> CDATAというと、タグの中の値の文字列のことですよね?
「タグの中の値」の定義が曖昧ですが、もしかして、属性値の事でしょうか?
> よくHTMLからCGIを呼び出すとき、href="…何とか&何とか…" とか書きますが、
これは確かにその通りです。a要素のhref属性の値は、参照している
文字として扱われますので、文字実体参照の開始記号「&」を
普通の文字として使うには、文字を参照しなければならなりません。
しかし、要素の内容になっているCDATAの場合は、
すべて単なる文字データとして扱われる事になっています。
例えばXHTMLであれば、 <![CDATA[〜〜〜]]>で囲まれた区間は、
「&」や「<」を使っても文法違反ではありません。また、
HTMLのSTYLE要素などの場合も同様です。
# というか、この区間内で実態参照を使ってしまうと、
# 本当に&という文字列として扱われてしまいます。(^_^;)
非同期の点ですが、ロジック処理上イベントを使わずに
ループさせる方法で試した所無事正常に処理できました。
DLLを使用した正規表現の方法は、現状の自分のスキルレベルでは
まだハードルが高い為、もう少し勉強してから試したいと思います。
皆様、いろいろご指導、ご意見ありがとうございました。
テキストで保存されたHTMLからタグを取り除くというのは、
正規表現を使うとか使わないとか以前の問題で
相当骨が折れるとおもいます、
どんな形式で書いているか
たとえば&の後はamp;やlt;なども可能ですが
16進でも可能で、それもいちいち変換しなければならないし、
HTMLのコメント内では-->以外は何かいても大丈夫ですし
(まぁ最初にコメントを全部とっちゃえば良いんですが)
HTMLの完全なリファレンスが横にないと厳しそうですね
暇人なので、こんなものを書いて見ました(笑)
&とかの変換はしていません
関数二つは一つにすることができますが、
引数チェックがめんどうだったので(笑)
遊びで作ったので、否定的な意見は勘弁してください ( ;o;)ノ
(Form)Textボックス1つ-MultiLine、ボタン1つ
Private Sub Command1_Click()
Dim txt As String
Dim tmp As String
Open "Filename.htm" For Input As #1
txt = ""
While EOF(1) = False
Line Input #1, tmp
txt = txt & vbCrLf & tmp
Call EraseHTMLcomment(txt)
Call EraseAnyTag(txt)
Text1.Text = txt
Wend
End Sub
Public Function EraseHTMLcomment(ByRef strDat As String)
Dim StartPos As Long
Dim EndPos As Long
Dim tmpStr As String
StartPos = InStr(strDat, "<!--")
While StartPos <> 0
EndPos = InStr(StartPos, strDat, "-->")
If EndPos > StartPos + 2 Then
If StartPos <> 1 Then 'コメント以前
tmpStr = Left(strDat, StartPos - 1)
Else
tmpStr = ""
End If
If Len(strDat) > EndPos + 2 Then 'コメント後
tmpStr = tmpStr & Mid(strDat, EndPos + 3)
End If
strDat = tmpStr
StartPos = InStr(StartPos, strDat, "<!--")
Else
StartPos = 0
End If
Wend
End Function
Public Function EraseAnyTag(ByRef strDat As String)
Dim StartPos As Long
Dim EndPos As Long
Dim tmpStr As String
StartPos = InStr(strDat, "<")
While StartPos <> 0
EndPos = InStr(StartPos, strDat, ">")
If EndPos > StartPos Then
If StartPos <> 1 Then 'タグ前
tmpStr = Left(strDat, StartPos - 1)
Else
tmpStr = ""
End If
If Len(strDat) > EndPos Then 'タグ後
tmpStr = tmpStr & Mid(strDat, EndPos + 1)
End If
strDat = tmpStr
StartPos = InStr(StartPos, strDat, "<")
Else
StartPos = 0
End If
Wend
End Function
脱線の返信になりますけど。
>魔界の仮面弁士 さん
> 例えばXHTMLであれば、 <![CDATA[〜〜〜]]>で囲まれた区間は、
> 「&」や「<」を使っても文法違反ではありません。また、
> HTMLのSTYLE要素などの場合も同様です。
そうなんですか、知りませんでした。
あんまりふかーく勉強したわけではなかったので…。
申し訳ないです(>_<)
ツイート | ![]() |