いまや企業のみならず
『個人においてもビックデータな時代』
ではないでしょうか?
その気さえあれば個人でもネットにあふれる情報を収集,分析することで実りあるアウトプットを期待出来ると思います。
例えば,「Yahoo!検索(リアルタイム)」ではTwitterなどの投稿をワード検索出来,時間ごとの件数を表示してくれますが特定ワードの検索結果を一定間隔で収集しデータベースに溜め込み時間帯などの独自の切り口で分析するなどアイディアは沢山あると思います。
その意味で「WebページからHTMLデータを取得する」ことが入り口の作業として重要になってきます。
HTMLのデータ収集はプログラミングで実現出来ますが,例えばVisualBasic(VB)の場合だと,いくつかの方法(プログラムコード)があります。
主に
1)WebClientクラス を使用
2)WebBrowserクラス を使用
3)InternetExplorer(IE)オブジェクト を使用
それぞれ長所短所があります。
WebClient → 簡単で高速,但しページ上のボタンが押せないなど
WebBrowser → ブラウザーの機能を有しほとんどのことが出来る
IEオブジェクト → 面倒で低速,但しVBAなどでポピュラー
VBの場合,WebClientかWebBrowserかどちらかの選択で,ボタンを押す必要がある,セッションを維持する必要などの場合はWebBrowserになります。
その前提で使い分けてプログラミングしている訳ですが,ふと「WebClientが高速」って思ってたけど本当に高速なの?高速だとしてどのくらい高速なの? と疑問が湧いてきます。そう思い始めると気になってしょうがありません。
と言うことで実験してみました。
実験前にWebBrowserで注意点があります。
WebBrowserも内部的にIEが動作しているそうですが,標準で「IE7」のバージョンに設定されます。IE7はWindowsXP以前のバージョンですのでWebサイトによっては対応していません。また,バージョンが上がるほど高速になるなどの利点もありますので予め適切なバージョンを強制設定しておく必要があります。今回は下記のサイトを参考に最新の「IE11」に設定してあります。
※多分,IE11そのものがインストールされている必要があります。
WebBrowser コントロールで使われている Internet Explorerを最新のバージョンに変更する
C# WebBrowserのレンダリングモード
WebBrowserコントロールのIEバージョン
実験方法
1)中身が単なる文字羅列の100KByteと10MByteの
HTMLファイルをローカルフォルダー(例えばDドライブ)
に用意します。
2)WebClient,WebBrowser,IEオブジェクトのそれぞれで
HTMLを読み込みその時間を計測します。
プログラムコードは下記参照。
3)計測値の10回の平均を算出します。
当初,連続してページを読み込みましたが100KByteファイルで確認中に段々時間が早くなっていく現象がありました。計測前にIEの一時ファイルは削除していますがどこかの経路でキャッシュが働いているかも知れません。そのため面倒でしたが1回1回プログラムを終了,起動させながらデータを取得しました。
なお,VisualStudioのデバックモードでプログラムを実行しました。
パソコンはCeleron B840+256GB SSDのノートパソコンです。
計測結果
クラス/obj サイズ 結果 WC比 WB比
WebClient(WC) 100KB 25ms
WebClient(WC) 10MB 67ms
WebBrowser(WB) 100KB 156ms 6.4倍
WebBrowser(WB) 10MB 1169ms 17.4倍
IE 100KB 423ms 16.9倍 2.7倍
IE 100KB 6895ms 102倍 5.8倍
結果として,WebClientがダントツに高速でした。
ただ,ローカルドライブのファイルをアクセスしており,Webからの場合,TCP/IP通信時間などのゲタが足されて幾分相殺されると思います。
(実際の時間差は少ないかも知れない)
逆にローカルファイルだったことでそれぞれの方法の時間差を正確に把握出来たとも言えますのでWebClientとWebBrowserをきっちり使い分けてプログラミングしていく必要性を改めて認識出来ました。
検証に使用したVisualBasicのソースコード
-----------------------------------------------------------
Imports System.IO
Imports System.Timers
'参照
'Microsoft.msHtml
'Microsoft Internet Controls
Public Class Form1
Private myUrl As String
'ストップウオッチ
Private sw As New System.Diagnostics.Stopwatch()
'IE
Private WithEvents IE As SHDocVw.InternetExplorer
Private Sub Form1_Load(sender As Object, e As EventArgs) _
Handles Me.Load
myUrl = "D:\Work\check_100KB.html"
'myUrl = "D:\Work\check_10MB.html"
End Sub
'IEオブジェクトでページを開く
Private Sub Button1_Click(sender As Object, e As EventArgs) _
Handles Button1.Click
delIeCache()
If Not (IE Is Nothing) Then
IE.Quit()
IE = Nothing
End If
sw.Start()
IE = New SHDocVw.InternetExplorer
IE.Visible = False
sw.Start()
IE.Navigate2(myUrl)
End Sub
'IEオブジェクトのドキュメントコンパレート
Private Sub IE_DocComplete(pDisp As Object, ByRef URL As Object) _
Handles IE.DocumentComplete
If Not TypeName(pDisp) = "IWebBrowser2" Or _
URL.ToString myUrl Then Return
Invoke(New SHDocVw.DWebBrowserEvents2_DocumentCompleteEventHandler(AddressOf myDocComplete), pDisp, URL)
End Sub
'IEオブジェクトのドキュメントコンパレート
Private Sub myDocComplete(ByVal pDisp As Object, ByRef URL As Object)
Dim ieDoc As mshtml.HTMLDocument = _
CType(IE.Document, mshtml.HTMLDocument)
Dim html As String = ieDoc.body.innerHTML
MRComObject(ieDoc)
sw.Stop()
System.Diagnostics.Debug.WriteLine("IE " & sw.ElapsedMilliseconds)
sw.Reset()
End Sub
'COMオブジェクトの開放
Public Shared Sub MRComObject(Of T As Class) _
(ByRef objCom As T, Optional ByVal force As Boolean = False)
If objCom Is Nothing Then
Return
End If
Try
If System.Runtime.InteropServices.Marshal.IsComObject(objCom) Then
If force Then
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(objCom)
Else
Dim count As Integer = _
System.Runtime.InteropServices.Marshal.ReleaseComObject(objCom)
If count 0 Then
Debug.Print(count.ToString())
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(objCom)
End If
End If
End If
Finally
objCom = Nothing
End Try
End Sub
'WebBrowserでページを開く
Private Sub Button2_Click(sender As Object, e As EventArgs) _
Handles Button2.Click
delIeCache()
sw.Start()
WebBrowser1.ScriptErrorsSuppressed = True
WebBrowser1.Visible = False
WebBrowser1.Navigate(myUrl)
End Sub
'WebBrowserのドキュメントコンパレート
Private Sub WebBrowser1_DocumentCompleted(ByVal sender As System.Object,
ByVal e As System.Windows.Forms.WebBrowserDocumentCompletedEventArgs) _
Handles WebBrowser1.DocumentCompleted
If Not TypeName(sender) = "WebBrowser" Then Exit Sub
If e.Url DirectCast(sender, WebBrowser).Url Then Exit Sub
Dim html As String = WebBrowser1.Document.Body.InnerHtml
sw.Stop()
System.Diagnostics.Debug.WriteLine("WB " & sw.ElapsedMilliseconds)
sw.Reset()
End Sub
'WebClient.DownloadStringでHTML取得
Private Sub Button3_Click(sender As Object, e As EventArgs) _
Handles Button3.Click
delIeCache()
sw.Start()
Dim wc As New System.Net.WebClient()
wc.Encoding = System.Text.Encoding.UTF8
Dim HTML As String = wc.DownloadString(myUrl)
wc.Dispose()
sw.Stop()
System.Diagnostics.Debug.WriteLine("WC " & sw.ElapsedMilliseconds)
sw.Reset()
End Sub
'IEの一時ファイル削除 本当に削除されているかは未確認…
Sub delIeCache()
Dim D As String
D = System.Environment.GetFolderPath(Environment.SpecialFolder.InternetCache)
Dim F() As String
Try
F = Directory.GetFiles(D, "*", SearchOption.AllDirectories)
For I As Integer = 0 To (F.Length - 1)
File.Delete(F(I))
Next
Catch ex As Exception
End Try
End Sub
'フォームを閉じる時の処理
Private Sub Form1_FormClosed(sender As Object, _
e As FormClosedEventArgs) _
Handles Me.FormClosed
If Not (IE Is Nothing) Then
IE.Quit()
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(IE)
IE = Nothing
End If
End Sub
Private Sub Button4_Click(sender As Object, e As EventArgs) _
Handles Button4.Click
Application.Exit()
End Sub
End Class
最近のコメント