tagCANDY CGI VBレスキュー(花ちゃん) の Visual Basic 2010 用 掲示板(VB.NET 掲示板) [ツリー表示へ]   [Home]
一括表示(VB.NET VB2005)
タイトルソースの一部取得は?
記事No3117
投稿日: 2006/02/15(Wed) 13:28
投稿者st
[OSのVer]:Windows XP    [VBのVer]:VB.NET  
はじめまして。stと申します。
最近花ちゃんさんのWebを見るようになったので投稿させて頂きました。
宜しくお願いします。

単刀直入に説明しますと、
HTMLソースを取得するのはできました。
希望はそのソースの一部分だけ取得したいというものです。
うまくいきません。と言いますか、全く分からないと言った感じです(>_<)
WebBrowserで表示させて表示されたWebのソース(ちなみに取得したソースはテキストボックスに表示
させています。)を、
一部分だけとりだして他のテキストボックスに表示させたいのです。

まだVB.NETを始めて半年です。
良い方法はありますでしょうか?
また参考になるものがありましたら教えていただければ幸いです。
宜しくお願いします。

[ツリー表示へ]
タイトルRe: ソースの一部取得は?
記事No3118
投稿日: 2006/02/15(Wed) 13:37
投稿者YAS
「一部分」というのはどんな部分ですか? なにか選ぶ基準がありますか?
それともWebBrowser上で選択された部分でしょうか?

[ツリー表示へ]
タイトルRe^2: ソースの一部取得は?
記事No3119
投稿日: 2006/02/15(Wed) 14:08
投稿者st
[OSのVer]:Windows    [VBのVer]:VB.NET  
YASさんご回答ありがとうございます。
一部分というのは、『Yahoo!JAPAN』のトップページを例にしますと、
・全てのソースを取得します。
・TextBox1にソースを表示します。
※下記が取得したソースだとします(全体の一部を表示しています)
-----------------------------------------------------------------------
(省略)
.
.
<TR>
<TD colSpan=2><SMALL>・<A href="hhttp://rd.yahoo.co.jp/toppage/topics/dome
stic/snowfall/?
hhttp://dailynews.yahoo.co.jp/fc/domestic/snowfall/?1139977514">落雪で数人生き埋めか
北海道
</A><IMG height=11 alt=[new] src="hhttp://img.yahoo.co.jp/images/new2.gif"
width=28
border=0></SMALL></TD></TR>
<TR>

<TD colSpan=2><SMALL>・<A
href="hhttp://rd.yahoo.co.jp/toppage/topics/entertainment/marriage_and_divorce/?
hhttp://dailynews.yahoo.co.jp/fc/entertainment/marriage_and_divorce/?1139976841">全国
各地で4月
並みの陽気</A></SMALL></TD></TR>
<TR>
<TD align=right colSpan=2><SMALL><A href="/r/fc2">一覧</A>&
lt;/SMALL></TD></TR></TBODY>
.
.
(続く)
※『Yahoo!JAPAN』抜粋
-----------------------------------------------------------------------

上記の『落雪で数人生き埋めか 北海道』や『全国各地で4月並みの陽気』の
この部分だけ取得してTextBox2に表示させたいのです。
なので確実にHTMLソースの大半はいらなくなります(^^;)

これが私が希望としている一部取得なのですが...
分かりにくかったらご指摘下さい。
よろしくお願いします。

[ツリー表示へ]
タイトルRe^3: ソースの一部取得は?
記事No3120
投稿日: 2006/02/15(Wed) 15:49
投稿者花ちゃん
.NET のバージョンは必ず記入して下さい。

タグの部分は要らないのであれば最初から Text だけTextBoxに表示するようにして下さい。
オブジェクト.Document.Body.InnerText

取得したい部分は、人間の判断によるものなら、その部分を選択して、
   TextBox1.Copy()
   TextBox2.Focus()
   TextBox2.Paste()
のようにすれば、コピーできます。

[ツリー表示へ]
タイトルRe^4: ソースの一部取得は?
記事No3122
投稿日: 2006/02/15(Wed) 16:52
投稿者st
[OSのVer]:Windows XP    [VBのVer]:VB.NET 2003   

> .NET のバージョンは必ず記入して下さい。
すみません。記入漏れでした。

> タグの部分は要らないのであれば最初から Text だけTextBoxに表示するようにして下さい。
>  オブジェクト.Document.Body.InnerText

TextBox1.Text = AxWebBrowser1.Document.Body.innerHTML()
で表示していました。
なるほど、Textにすれば良かったんですね。
ありがとうございます。

> 取得したい部分は、人間の判断によるものなら、その部分を選択して、
>    TextBox1.Copy()
>    TextBox2.Focus()
>    TextBox2.Paste()
> のようにすれば、コピーできます。

先程の例えに説明不足でした。
実は取得する部分は定期的に更新されるものです。
なので自動で1分間隔で更新をかけて読む仕様としているのですが、
そこができなかったです。

つまり、その部分を手動ではなく自動で読むようにしたいのですが、
どのようにすればイイのかよく分かりません(>_<;)
説明不足でお手数かけましたが、
以上が私のやりたいことです。

質問が多少異なっているような気がしてきました。
…レス立て直した方がイイですか?
ご質問、ご意見、上記についてのアドバイス等あればよろしくお願いします。

[ツリー表示へ]
タイトルRe^3: ソースの一部取得は?
記事No3121
投稿日: 2006/02/15(Wed) 16:11
投稿者YAS
VB2005であったらこんな感じでしょうか。

Public Class Form1
    WithEvents WebBrowser1 As New WebBrowser
    Dim TextBox1 As New TextBox
    Private Sub Form1_Load(ByVal sender As System.Object, _
    ByVal e As System.EventArgs) Handles MyBase.Load
        Me.TextBox1.Multiline = True
        Me.TextBox1.Dock = DockStyle.Fill
        Me.Controls.Add(Me.TextBox1)
        Me.WebBrowser1.Navigate("hhttp://www.yahoo.co.jp")
    End Sub

    Private Sub WebBrowser1_DocumentCompleted(ByVal sender As Object, _
    ByVal e As System.Windows.Forms.WebBrowserDocumentCompletedEventArgs) _
    Handles WebBrowser1.DocumentCompleted
        Dim Document As HtmlDocument = Me.WebBrowser1.Document
        Dim HtmlElements As HtmlElementCollection = Document.GetElementsByTagName("a")
        For Each HtmlElement As HtmlElement In HtmlElements
            If HtmlElement.GetAttribute("href") _
            .StartsWith("hhttp://rd.yahoo.co.jp/toppage/topics/") Then
                Me.TextBox1.Text += HtmlElement.InnerText & ControlChars.CrLf
            End If
        Next
    End Sub
End Class

[ツリー表示へ]
タイトルRe^4: ソースの一部取得は?
記事No3123
投稿日: 2006/02/15(Wed) 17:10
投稿者st
[OSのVer]:Windows XP    [VBのVer]:VB.NET 2003  

YASさんご回答ありがとうございます。

> VB2005であったらこんな感じでしょうか。

…VB.NET 2003なのです。
説明不足ですみませんでした。
ためしてみたんですが、これは2003じゃ使えないですか?
『〜の定義がされていない』とか『〜の変数が必要』とか
表示されてダメみたいです。

すみません。でもヒントになりそうですね。
アドバイスありがとうございます。

[ツリー表示へ]
タイトルRe^5: ソースの一部取得は?
記事No3124
投稿日: 2006/02/15(Wed) 19:24
投稿者魔界の仮面弁士
2003 だとすれば、こんな感じかな。

([プロジェクト]-[参照の追加]の画面にて、COM の "Microsoft HTML Object Library" を追加)
=====================================================================================
Private Sub AxWebBrowser1_DocumentComplete( _
  ByVal sender As Object, _
  ByVal e As AxSHDocVw.DWebBrowserEvents2_DocumentCompleteEvent _
) Handles AxWebBrowser1.DocumentComplete

  ListBox1.Items.Clear()

  Dim Document As mshtml.HTMLDocument = DirectCast(AxWebBrowser1.Document, mshtml.HTMLDocument)
  Dim HtmlElements As mshtml.IHTMLElementCollection = Document.getElementsByTagName("A")
  For Each HtmlElement As mshtml.IHTMLElement In HtmlElements
    Dim Anchor As mshtml.IHTMLAnchorElement = DirectCast(HtmlElement, mshtml.IHTMLAnchorElement)
    If Anchor.href.StartsWith("hhttp://rd.yahoo.co.jp/toppage/topics/") Then
      ListBox1.Items.Add(HtmlElement.innerText)
    End If
    ReleaseComObject(Anchor)
  Next
  ReleaseComObject(HtmlElements)
  ReleaseComObject(Document)
End Sub

Private Sub ReleaseComObject(ByVal O As Object)
  If Not O Is Nothing AndAlso System.Runtime.InteropServices.Marshal.IsComObject(O) Then
    Dim I As Integer = System.Runtime.InteropServices.Marshal.ReleaseComObject(O)
    While I > 0
      I = System.Runtime.InteropServices.Marshal.ReleaseComObject(O)
    End While
  End If
End Sub

[ツリー表示へ]
タイトルRe^6: ソースの一部取得は?
記事No3125
投稿日: 2006/02/15(Wed) 22:34
投稿者YAS
> Private Sub ReleaseComObject(ByVal O As Object)
>   If Not O Is Nothing AndAlso System.Runtime.InteropServices.Marshal.IsComObject(O) Then
>     Dim I As Integer = System.Runtime.InteropServices.Marshal.ReleaseComObject(O)
>     While I > 0
>       I = System.Runtime.InteropServices.Marshal.ReleaseComObject(O)
>     End While
>   End If
> End Sub

本題からはずれて申し訳ありませんが,2つ質問させてください。

・COMオブジェクトの解放を上記のように記述するのは安全のためですか,それともこう記述しないと
解放されないのですか?
・HtmlElementをキャストしてAnchorに代入するとHtmlElementとAnchorは同じオブジェクトを参照
する。だからAnchorを解放すればHtmlElementを解放する必要はない。と,いうことであっていますか?

COMオブジェクトの解放でいつも悩むので,教えて頂けたらうれしいです。

[ツリー表示へ]
タイトルRe^7: ソースの一部取得は?
記事No3127
投稿日: 2006/02/16(Thu) 10:08
投稿者st
[OSのVer]:Windows    [VBのVer]:VB.NET 

> Private Sub ReleaseComObject(ByVal O As Object)
> If Not O Is Nothing AndAlso System.Runtime.InteropServices.Marshal.IsComObject(O) Then
> Dim I As Integer = System.Runtime.InteropServices.Marshal.ReleaseComObject(O)
> While I > 0
> I = System.Runtime.InteropServices.Marshal.ReleaseComObject(O)
> End While
> End If
> End Sub

少ししか分かりませんが、分かっている範囲でお答えしようかと...
> ・COMオブジェクトの解放を上記のように記述するのは安全のためですか,それともこう記述しな
いと
> 解放されないのですか?
ReleaseComObjectでしか確かCOMオブジェクトは解放されないはずでは。
なので上記でしか解放されないです。(たぶん)
怪しいので
hhttp://jeanne.wankuma.com/tips/programing/releasecom.html
で参考になるのではないでしょうか。

[ツリー表示へ]
タイトルCOMの解放に関して
記事No3129
投稿日: 2006/02/16(Thu) 10:44
投稿者魔界の仮面弁士
# COM Interop に関する .NET 1.0/1.1/2.0 の動作に関しては、
# 私もまだ調査中の段階だったりします…。(^^;

> ・COMオブジェクトの解放を上記のように記述するのは安全のためですか,それともこう記述しないと
> 解放されないのですか?

その両方です。
解放処理の記述についてですが、それぞれの判定に対しては、
 Not O Is Nothing
  → null参照を解放できるわけがないので、記述しておく
 Marshal.IsComObject(O)
  → Marshal.ReleaseComObject(O) の対象となるのは、COMコンポーネントだけなので
 Whileループ
  → 特定の状況下で、参照カウントが 2以上になる可能性があるから(この投稿の最後を参照)
といった意味があります。(実際には、Tryステートメントブロックを併用すべきですけれどね)


もちろん、使用中のオブジェクトを破棄してしまうと、その後のアクセスで例外が出ますから、
誰がいつそのオブジェクトを破棄するべきかは、よく考えねばなりませんね。


> ・HtmlElementをキャストしてAnchorに代入するとHtmlElementとAnchorは同じオブジェクトを参照
> する。だからAnchorを解放すればHtmlElementを解放する必要はない。と,いうことであっていますか?

あっていると思います。

ためしに、HtmlElement と Anchor の両方を Marshal.ReleaseComObject して、
その戻り値をチェックしてみてください。参照カウントが共有されている事がわかりますよ。


これは、RCW (ランタイム呼び出し可能ラッパー)では、その COM オブジェクトへの参照が、
複数の マネージ クライアントから参照されていたとしても、そのプロセス内での
参照カウントは一つしか保持されず、増加する事は無いからです。

[RCW (ランタイム呼び出し可能ラッパー)]
hhttp://www.microsoft.com/japan/msdn/library/ja/cpguide/html/cpconruntimecallablewrapper.asp

[CCW (COM 呼び出し可能ラッパー)]
hhttp://www.microsoft.com/japan/msdn/library/ja/cpguide/html/cpconcomcallablewrapper.asp


ただし、アウトプロセスな ActiveX EXE のクラスの場合は、話が変わってきます。
プロセス境界を越えて RCW を渡した場合には、COM オブジェクトの参照カウンタを
上げることができるので、参照カウンタが常に 1 に留まるとは限らないからです。
このような場合には、Marshal.ReleaseComObject を複数回呼ぶ必要があります。

具体例を挙げると……たとえば Excel の場合には、
 Dim Hs As Excel.HPageBreaks = oWorksheet.HPageBreaks
 Dim H As Excel.HPageBreak = Hs.Add(oRange) '改ページ挿入
というコードを、レイトバインドにして
 Dim Hs As Object = oWorksheet.HPageBreaks
 Dim H As Object = Hs.Add(oRange) '改ページ挿入
のようにすると、.Add 時に oRange の参照カウントが増加してしまうらしく、
Marshal.ReleaseComObject(oRange) を、一回多く呼び出さねばならないようです。

hhttp://hpcgi1.nifty.com/MADIA/VBBBS2/wwwlng.cgi?print+200512/05120042.txt

[ツリー表示へ]
タイトルRe^7: ソースの一部取得は?
記事No3130
投稿日: 2006/02/16(Thu) 15:24
投稿者YAS
st様
参考ページを紹介して頂きありがとうございました。
また,便乗して質問し,申し訳ありませんでした。

魔界の仮面弁士様
詳しく解説して頂きありがとうございました。
.NETからCOMオブジェクトを参照するときに,参照カウントが増える条件が
今まであやふやだったのがだいぶクリアになりました。
ReleaseComObject()の戻り値を調べてさらに勉強してみます。

[ツリー表示へ]
タイトルRe^6: ソースの一部取得は?
記事No3126
投稿日: 2006/02/16(Thu) 09:49
投稿者st
[OSのVer]:Windows XP    [VBのVer]:VB.NET 2003  

魔界の仮面弁士さん回答ありがとうございます。

さっそくやってみたところ...
できましたー!!ありがとうございます。バッチリでした。
魔界の仮面弁士さんには色々とごめんどうかけています(^-^;)
YASさん、花ちゃんありがとうございました。
とても助かりました〜。

みなさんありがとうございました。
この質問については解決しましたが、
YASさんの質問もありますし、何か意見等あったらレスください。
よろしくお願いします。

[ツリー表示へ]