でも、ページの作りで、カラム(縦罫)のソートが出来なかったり、余計な情報も多い為、
自分用に、表の内容を加工したいと思う事もありますね。
今回は、VB で、自分のデータベースとして保存するものを書いてみました。
HTML にお詳しければ、 カラム(縦罫)のソートは、それ用のスクリプトをソースコードに書き加えれば済みます。
データの保存も、ブラウザの ページを保存 で 完全版を残せば、取り敢えずは何とかなります。
でも、検索やソートや閲覧の自由度の観点からは、VB の様な言語での方が、柔軟性が高い気がします。
いやぁ、ここの処、あまり書いていなかったので、ウラシマ太郎状態 でした ... 。 ふぅ。.
但し、ここでの作業は、 始めに 表 ありき! です。
汎用性が高い書き方にはなっていません。
最初に、IDE 等で、元になる 表 を作らなければなりません。
謂わば、データベースの設計をしておいて、データの入力部分は、
インターネット上から、ダウンロードした、HTML ファイルを使って、自動入力する方法です。
また、ページの中に複数の表がある事は想定していません。
データ量が少なければ、コピーペーストや手入力で十分な場合だってありますし ... 。
元になる表が全てを左右する為、ここに全貌を示す事はしません。
HTML から、テーブル部分を抽出して、TD タグの内容を変数に取る 部分だけを示します。
この内容を元に、データベースへのレコード追加 部分を書き込む必要があります。
先ずは、元の HTML コードを。
説明用に、自分の Blog の過去記事から流用しました。 例としては、行数は かなり 少なめ。.
<!DOCTYPE html>
<html lang="jp" xmlns=http://www.w3.org/1999/xhtml>
<head>
<meta charset="utf-8" />
<title>MyLinkList Local</title>
<!--sorter js Load -->
<body>
My Link List<br />
<br />
<table id="sample" >
<thead>
<th width= "60">分類</th>
<th width="120">区分</th>
<th width="220">内容</th>
<th width="150">LINK</th>
<th width="250">Memo</th>
</thead>
<tbody>
<tr>
<td>検索</td>
<td>検索 Google</td>
<td>Google ホーム</td>
<td><a href="http://www.google.co.jp/">Google Home</a></td>
<td></td>
</tr>
<tr>
<td>気象</td>
<td>気象 台風</td>
<td>台風情報</td>
<td><a href="http://www.jma.go.jp/jp/typh/">台風情報 気象庁</a></td>
<td>台風中心クリックで詳細</td>
</tr>
<!--*** 注: 説明の為、データ部分を省略しています。***-->
</tbody>
</table>
<style>
<!--*** 注: 説明の為、スクリプト部分を省略しています。***-->
</style>
</body>
</html>
さて、以下のコードで、HTML からテーブルデータを抽出します。
実際には、データベース用に構成したデータセットをデータグリッドビューに表示し、追加していくのがいいと思います。
ここでは、便宜的に、テキストボックス(マルチライン)に吐き出しています。
Form1 に用意したのは、 Label1 / Button1 / WebBrowser1 / TextBox1 の4つです。
Public Class Form1
'Test Program
'Label1:FilePath / Button1:ReadHTML / WebBrowser1:HTML for DOM / TextBox1:MultiLines ShowReadingResult
'TR TD Tags tr td OK UpperLower:NoError
'HTML Table InnerText Catching a Tag = Ref URL NoExecuting
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Me.Width = 680
Me.Height = 360
Me.Label1.Location = New Point(12, 25)
Me.Button1.Location = New Point(345, 20)
Me.WebBrowser1.Size = New Point(408, 240)
Me.WebBrowser1.Location = New Point(12, 70)
Me.TextBox1.Multiline = True
Me.TextBox1.Size = New Point(205, 240)
Me.TextBox1.Location = New Point(440, 70)
Me.TextBox1.ScrollBars = ScrollBars.Vertical
Me.Button1.Text = "GetItem"
Me.Label1.Text = "c:\users\UserName\Documents\TMP\test.htm"
Dim winPath As String = Me.Label1.Text
Dim u As New Uri(winPath)
Me.WebBrowser1.Navigate(u)
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim doc As HtmlDocument = Me.WebBrowser1.Document
Dim elements As HtmlElementCollection
Dim element As HtmlElement
Dim thTags As HtmlElementCollection
Dim tdTags As HtmlElementCollection
Dim tdTag As HtmlElement
Dim tdTagStr As String
Dim tdTagStrs As String = ""
Dim result As Boolean
Dim resultPre As Boolean
Dim counterRows As Integer = 0
Const LineEnd As String = "---------------------"
elements = doc.GetElementsByTagName("TR")
For Each element In elements
resultPre = element.InnerHtml.Contains("<TH")
If resultPre Then
thTags = element.GetElementsByTagName("TH")
tdTagStrs = "TableColumns : " + Str(thTags.Count) + vbCrLf + LineEnd
End If
result = element.InnerHtml.Contains("<TD")
If result Then
counterRows = counterRows + 1
tdTags = element.GetElementsByTagName("TD")
Dim counterColumn As Integer = -1
For Each tdTag In tdTags
counterColumn = counterColumn + 1
tdTagStr = tdTag.InnerText
tdTagStrs = tdTagStrs + vbCrLf + tdTagStr
Next
tdTagStrs = tdTagStrs + vbCrLf + LineEnd
End If
Next
tdTagStrs = tdTagStrs + vbCrLf + LineEnd + " End" + vbCrLf + Str(counterRows) + " Lines"
Me.TextBox1.Text = tdTagStrs
End Sub
End Class
このコードを実行すると、
ロード時には HTML が左の WebBrowser1 に表示され、 Button1 でフラットテキストで TextBox1 に表示されます。
本来、表示に係る部分(デザイナのプロパティで設定)は 灰色 で表示しています。 (画面表示調整のみ)
また、抽出結果の表示部分は、 紫色 に.しました。
尚、同じ変数に値を加えて行く場合の常套手段は StringBuilder なのですが、
ここでは例なので分り易さ重視 ?。 そのまま使う場合には、ちゃんと、直して下さいね。.
この部分を 変数 counterColumn の値に応じて、 データセットの各カラムに追加して行く様に変えて下さい。
また、ここでは、 ファイル指定はコード内でハードコーディングしていますが、
実際には、拡張子を指定した ファイル選択ダイアログ が便利でしょうね。 事実、自分用のコードではそうしています。.
HTML コード自体も、実際のものは、 Script や Table (レイアウト用途で) が多用されていて、
お目当ての表からデータ抽出するには、 条件文を考えたり、 Script の実行を阻止したり、 そんな対策が必要です。
Table 自体も色々な記述方法があり、
TH タグではなく、TD タグの属性変更で見出しを表示していたり と様々なケースがあります。
TD タグも、ページ構成用にハイパーリンク目的のデータ行(本来不要)が付加されていたりします。
条件文 : TD の項目数や内容で条件分岐 ・ Table に id や class が振ってあれば それで区別出来て楽
Script の実行を阻止 : .Navigate(u) 前に、 Me.WebBrowser1.ScriptErrorsSuppressed = True
その他(読込待機) : WebBrowser1.DocumentCompleted イベントハンドラ利用
これらを加味すると、上記コードは、ブロック構成(Sub の中身も含)が変わると思います。.
ここで示した以外のアプローチ方法 としては、
HTML ソースから、データ部分を CSV (Comma-Separated Values) ファイルとして抽出して、一気に操作する方法もあります。
要は、HTML ソースのフラットテキストからの 抽出を どう考えるか ですね。
まぁ、一例として、ご覧下さい。
0 件のコメント:
コメントを投稿