hpサイトの情報をtxtで保存するには

解決


tanaka  2003-06-13 06:58:30  No: 78235

HPのhtmlファイルを保存し、そのファイルの必要事項を検索して
抜粋し、表示させたいのですが、inetコントロールを使用して
ファイルを保存するとhtmlタグも一緒に保存される為、思い通りに
処理ができません。
何かよい方法がありましたらご教授お願いします。


たかみちえ  URL  2003-06-13 07:28:00  No: 78236

HTMLをダウンロードしているんですから、当然タグは消えません。
消してから処理をしたいのなら、自分で消すしかないでしょう。
(正規表現を使えば簡単に消せますけどね、DLLとか)


tanaka  2003-06-13 07:41:54  No: 78237

早速のご返答ありがとうございます。
具体的にどのように処理するのが最善でしょうか。

また、このような処理を行う場合、
・ファイルをダウンロードして処理
・直接データを取得(Inet.GetChunk)して処理
どちらが一般的なのでしょうか。

先日始めたばかりなのでご指摘お願いします。


VBレスキュー(花ちゃん)  URL  2003-06-13 09:41:54  No: 78238

こういう事でしょうか?

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


おーなー  2003-06-13 11:40:51  No: 78239

通りすがりに失礼
これは便利ですね。
勉強になりました


tanaka  2003-06-13 20:43:01  No: 78240

上記のコードを試した所希望通りの結果が得られましたが、
以下のようにしたところ問題が発生しました。

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コントロールを使用してから事象が発生しました)

お手数ですがよろしくお願いします。


たかみちえ  URL  2003-06-13 21:07:57  No: 78241

わたしの言った方法での返信だけ
>2003/06/12(木) 22:41:54
> 早速のご返答ありがとうございます。
> 具体的にどのように処理するのが最善でしょうか。
  この方法の場合、ごく普通にダウンロードしてください。
その時点では、タグ入りのテキストファイル(HTML)ですね。
  ですから、ダウンロードを済ませた後でそれから処理をしていくことになると思います。

  そのあと、タグを削除していくことになります。
VBだけでやるのならば、InStrで<を探しつつ、>がでたら<から>までを削除、というめんどくさい処理をしていくしかないでしょうね。
(たまたま表示できている<を見つけて消してしまったというのは、HTMLの作者が悪いのです、気にしないでいきましょう。
文中に表示する<や>は、ちゃんと特殊文字で書かないといけないんですjから)

  正規表現を使えば、こんなことをしなくてもすみます。
BRegExpというDLLを使えば、正規表現を使って置き換えられますから、
<から>までを消すような正規表現を使って消してしまいましょう。

  わたしの言った方法は、とりあえず環境に依存しません。
  WebBrowserを使った方法だと、WebBrowserコントロールが使えない環境、もしくは言語では、使えません。
(これが使えない環境は、いまさらないと思いますけど、コントロールの呼び出しができない、または面倒な言語なら、いくつか知ってます)

  まあ、わたしはWebBrowserを使ったことがないから、
その方法を思いつかなかっただけなんですけどね。


魔界の仮面弁士  2003-06-13 22:32:36  No: 78242

> 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部であれば、"<"が
実態参照なしで出現しても、文法的には問題無いような気がします。


たかみちえ  URL  2003-06-14 03:41:54  No: 78243

> テキストデータは、#PCDATAな領域だけではなく、CDATAな領域に
出現する可能性もありますから。。。
  CDATAというと、タグの中の値の文字列のことですよね?
あれもたしか、実体参照にしないとまずいとされています。
  よくHTMLからCGIを呼び出すとき、href="…何とか&何とか…"  とか書きますが、
これも本当は、…何とか&amp;何とか…  と書かなければいけません  
(&のままでもいいのは、ただの偶然)
と書いてありました。
  (Anothor HTML Lintの解説ページより)


魔界の仮面弁士  2003-06-14 05:27:55  No: 78244

# 話題が脱線しています。申し訳ありません>元質問者どの

>  CDATAというと、タグの中の値の文字列のことですよね?
「タグの中の値」の定義が曖昧ですが、もしかして、属性値の事でしょうか?

>  よくHTMLからCGIを呼び出すとき、href="…何とか&何とか…"  とか書きますが、
これは確かにその通りです。a要素のhref属性の値は、参照している
文字として扱われますので、文字実体参照の開始記号「&」を
普通の文字として使うには、文字を参照しなければならなりません。

しかし、要素の内容になっているCDATAの場合は、
すべて単なる文字データとして扱われる事になっています。

例えばXHTMLであれば、 <![CDATA[〜〜〜]]>で囲まれた区間は、
「&」や「<」を使っても文法違反ではありません。また、
HTMLのSTYLE要素などの場合も同様です。
# というか、この区間内で実態参照を使ってしまうと、
# 本当に&amp;という文字列として扱われてしまいます。(^_^;)


tanaka  2003-06-14 06:01:13  No: 78245

非同期の点ですが、ロジック処理上イベントを使わずに
ループさせる方法で試した所無事正常に処理できました。

DLLを使用した正規表現の方法は、現状の自分のスキルレベルでは
まだハードルが高い為、もう少し勉強してから試したいと思います。

皆様、いろいろご指導、ご意見ありがとうございました。


おーなー  2003-06-14 07:19:54  No: 78246

テキストで保存されたHTMLからタグを取り除くというのは、
正規表現を使うとか使わないとか以前の問題で
相当骨が折れるとおもいます、
どんな形式で書いているか
たとえば&の後はamp;やlt;なども可能ですが
16進でも可能で、それもいちいち変換しなければならないし、
HTMLのコメント内では-->以外は何かいても大丈夫ですし
(まぁ最初にコメントを全部とっちゃえば良いんですが)

HTMLの完全なリファレンスが横にないと厳しそうですね


おーなー  2003-06-14 07:55:55  No: 78247

暇人なので、こんなものを書いて見ました(笑)
&amp;とかの変換はしていません
関数二つは一つにすることができますが、
引数チェックがめんどうだったので(笑)
遊びで作ったので、否定的な意見は勘弁してください ( ;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


たかみちえ  URL  2003-06-16 08:11:18  No: 78248

脱線の返信になりますけど。

>魔界の仮面弁士  さん
> 例えばXHTMLであれば、 <![CDATA[〜〜〜]]>で囲まれた区間は、
> 「&」や「<」を使っても文法違反ではありません。また、
> HTMLのSTYLE要素などの場合も同様です。
  そうなんですか、知りませんでした。
  あんまりふかーく勉強したわけではなかったので…。
申し訳ないです(>_<)


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

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






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