web-dev-qa-db-ja.com

cricinfoスコアカードのHTML解析

目的

私は Cricinfo Webサイト から20/20クリケットスコアカードデータを削り取り、理想的にはCSVフォームにExcelでデータ分析します

例として、現在のオーストラリアのビッグバッシュ2011/12スコアカードは、

背景

私はVBAを使用して(IEを自動化するか、XMLHTTPを使用してから正規表現を使用して)、Webサイトからデータをスクレイピングすることに熟練しています HTMLから値を抽出TDおよびTr

同じ質問で、html解析を提案するコメントが投稿されました-私はこれまでに遭遇したことがないので、 RegEx match open tags except XHTML self-contained tags などの質問を調べました。

クエリ

以下のクリケットデータを解析するための正規表現を書くことはできますが、HTML解析を使用してこれらの結果を効率的に取得する方法についてアドバイスをお願いします。

私の好みは以下を含む繰り返し可能なCSV形式であることを覚えておいてください。

  • 試合の日付/名前
  • チーム1の名前
  • 出力はチーム1の最大11のレコードをダンプする必要があります(プレーヤーが打ったことのない空白のレコード、つまり "Did Not Bat"
  • チーム2の名前
  • 出力は、チーム2の最大11のレコードをダンプする必要があります(プレーヤーが打たれていない空のレコード)

私にとってNirvanaは、VBAまたはVBscriptを使用して展開できるソリューションであり、分析を完全に自動化できますが、HTML解析には別のツールを使用する必要があると思います。

サンプルサイトリンクと抽出されるデータ

cricinfo scorecardsource date

35
brettdj

「VBA」には2つのテクニックがあります。 1つずつ説明していきます。

1)FireFox/Firebug Addon/Fiddlerを使用する

2)Excelの組み込み機能を使用してWebからデータを取得する

この投稿は多くの人に読まれるので、自明のことも取り上げます。知っている部分はスキップしてください。


1)FireFox/Firebug Addon/Fiddlerを使用する


FireFox: http://en.wikipedia.org/wiki/Firefox 無料ダウンロード( http://www.mozilla.org/en-US/firefox/new/

Firebugアドオン: http://en.wikipedia.org/wiki/Firebug_%28software%29 無料ダウンロード( https://addons.mozilla.org/en-US/firefox/ addon/firebug /

Fiddler: http://en.wikipedia.org/wiki/Fiddler_%28software%29 無料ダウンロード( http://www.fiddler2.com/fiddler2/

Firefoxをインストールしたら、Firebugアドオンをインストールします。 Firebugアドオンを使用すると、Webページのさまざまな要素を検査できます。たとえば、ボタンの名前を知りたい場合は、ボタンを右クリックして[Firebugで要素を検査]をクリックすると、そのボタンに必要なすべての詳細が表示されます。

enter image description here

別の例としては、スクラップする必要のあるデータがあるWebサイト上のテーブルの名前を見つける場合があります。

XMLHTTPを使用している場合にのみ、Fiddlerを使用します。ボタンをクリックしたときに渡される正確な情報を確認するのに役立ちます。サイトをスクレイピングするBOTSの数が増えたため、ほとんどのサイトでは、自動スクレイピングを防ぐために、マウスの座標をキャプチャしてその情報を渡します。フィドラーは、渡された情報のデバッグに実際に役立ちます。この情報は悪意を持って使用される可能性があるため、ここでは詳しく説明しません。

次に、質問に投稿されたURLをこする方法の簡単な例を見てみましょう

http://www.espncricinfo.com/big-bash-league-2011/engine/match/524915.html

まず、その情報を持つテーブルの名前を見つけましょう。テーブルを右クリックして、「Firebugで要素を検査」をクリックすると、以下のスナップショットが表示されます。

enter image description here

これで、データが「inningsBat1」というテーブルに格納されていることがわかりました。そのテーブルの内容をExcelファイルに抽出できれば、データを操作して分析を実行できます。 Sheet1にそのテーブルをダンプするサンプルコードは次のとおりです

先に進む前に、すべてのExcelを閉じて、新しいインスタンスを開始することをお勧めします。

VBAを起動し、ユーザーフォームを挿入します。コマンドボタンとWebcrowserコントロールを配置します。ユーザーフォームは次のようになります

enter image description here

このコードをユーザーフォームのコード領域に貼り付けます

Option Explicit

'~~> Set Reference to Microsoft HTML Object Library

Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)

Private Sub CommandButton1_Click()
    Dim URL As String
    Dim oSheet As Worksheet

    Set oSheet = Sheets("Sheet1")

    URL = "http://www.espncricinfo.com/big-bash-league-2011/engine/match/524915.html"

    PopulateDataSheets oSheet, URL

    MsgBox "Data Scrapped. Please check " & oSheet.Name
End Sub

Public Sub PopulateDataSheets(wsk As Worksheet, URL As String)
    Dim tbl As HTMLTable
    Dim tr As HTMLTableRow
    Dim insertRow As Long, Row As Long, col As Long

    On Error GoTo whoa

    WebBrowser1.navigate URL

    WaitForWBReady

    Set tbl = WebBrowser1.Document.getElementById("inningsBat1")

    With wsk
        .Cells.Clear

        insertRow = 0
        For Row = 0 To tbl.Rows.Length - 1
            Set tr = tbl.Rows(Row)
            If Trim(tr.innerText) <> "" Then
                If tr.Cells.Length > 2 Then
                    If tr.Cells(1).innerText <> "Total" Then
                        insertRow = insertRow + 1
                        For col = 0 To tr.Cells.Length - 1
                            .Cells(insertRow, col + 1) = tr.Cells(col).innerText
                        Next
                    End If
                End If
            End If
        Next
    End With
whoa:
    Unload Me
End Sub

Private Sub Wait(ByVal nSec As Long)
    nSec = nSec + Timer
    While Timer < nSec
       DoEvents
        Sleep 100
    Wend
End Sub

Private Sub WaitForWBReady()
    Wait 1
    While WebBrowser1.ReadyState <> 4
        Wait 3
    Wend
End Sub

次にユーザーフォームを実行し、コマンドボタンをクリックします。データがSheet1にダンプされていることがわかります。スナップショットを見る

enter image description here

同様に、他の情報も削ることができます。


2)Excelの組み込み機能を使用してWebからデータを取得します


私はあなたがExcel 2007を使用していると思いますので、上記のリンクをこする例としてそれを取り上げます。

Sheet2に移動します。次に、[データ]タブに移動し、右端の[Webから]ボタンをクリックします。スナップショットを参照してください。

enter image description here

「新しいWebクエリウィンドウ」にURLを入力し、「移動」をクリックします。

ページがアップロードされたら、スナップショットに示されている小さな矢印をクリックして、インポートする関連テーブルを選択します。完了したら、「インポート」をクリックします

enter image description here

Excelは、データをインポートする場所を尋ねます。関連するセルを選択し、[OK]をクリックします。これで完了です。指定したセルにデータがインポートされます。

マクロを記録し、これを自動化することもできます。

これが私が記録したマクロです。

Sub Macro1()
    With ActiveSheet.QueryTables.Add(Connection:= _
    "URL;http://www.espncricinfo.com/big-bash-league-2011/engine/match/524915.html" _
    , Destination:=Range("$A$1"))
        .Name = "524915"
        .FieldNames = True
        .RowNumbers = False
        .FillAdjacentFormulas = False
        .PreserveFormatting = True
        .RefreshOnFileOpen = False
        .BackgroundQuery = True
        .RefreshStyle = xlInsertDeleteCells
        .SavePassword = False
        .SaveData = True
        .AdjustColumnWidth = True
        .RefreshPeriod = 0
        .WebSelectionType = xlSpecifiedTables
        .WebFormatting = xlWebFormattingNone
        .WebTables = """inningsBat1"""
        .WebPreFormattedTextToColumns = True
        .WebConsecutiveDelimitersAsOne = True
        .WebSingleBlockTextImport = False
        .WebDisableDateRecognition = False
        .WebDisableRedirections = False
        .Refresh BackgroundQuery:=False
    End With
End Sub

お役に立てれば。まだクエリがある場合はお知らせください。

シド

50
Siddharth Rout

これに興味のある他の人のために、私は Siddhart Rout's 以前の回答に基づいて以下のコードを使用することになりました

  • XMLHttpは自動化よりも大幅に高速でしたIE
  • コードは、ダウンロードするシリーズごとにCSVファイルを生成します(X変数に保持されます)
  • コードは、各試合を通常の29行の範囲にダンプし(打ったプレーヤーの数に関係なく)、後で簡単に分析できるようにします

enter image description here

    Public Sub PopulateDataSheets_XML()
    Dim URL As String
    Dim ws As Worksheet

    Dim lngRow As Long
    Dim lngRecords As Long
    Dim lngWrite As Long
    Dim lngSpare As Long
    Dim lngInnings As Long
    Dim lngRow1 As Long
    Dim X(1 To 15, 1 To 4) As String

    Dim objFSO As Object
    Dim objTF As Object

    Dim xmlHttp As Object
    Dim htmldoc As HTMLDocument
    Dim htmlbody As htmlbody
    Dim tbl As HTMLTable
    Dim tr As HTMLTableRow
    Dim strInnings As String

    s = Timer()

    Set xmlHttp = CreateObject("MSXML2.ServerXMLHTTP")
    Set objFSO = CreateObject("scripting.filesystemobject")

    X(1, 1) = "http://www.espncricinfo.com/indian-premier-league-2011/engine/match/"
    X(1, 2) = 501198
    X(1, 3) = 501271
    X(1, 4) = "indian-premier-league-2011"
    X(2, 1) = "http://www.espncricinfo.com/big-bash-league-2011/engine/match/"
    X(2, 2) = 524915
    X(2, 3) = 524945
    X(2, 4) = "big-bash-league-2011"
    X(3, 1) = "http://www.espncricinfo.com/ausdomestic-2010/engine/match/"
    X(3, 2) = 461028
    X(3, 3) = 461047
    X(3, 4) = "big-bash-league-2010"

    Set htmldoc = New HTMLDocument
    Set htmlbody = htmldoc.body


    For lngRow = 1 To UBound(X, 1)
        If Len(X(lngRow, 1)) = 0 Then Exit For
        Set objTF = objFSO.createtextfile("c:\temp\" & X(lngRow, 4) & ".csv")

        For lngRecords = X(lngRow, 2) To X(lngRow, 3)
            URL = X(lngRow, 1) & lngRecords & ".html"

            xmlHttp.Open "GET", URL
            xmlHttp.send
            Do While xmlHttp.Status <> 200
                DoEvents
            Loop
            htmlbody.innerHTML = xmlHttp.responseText

            objTF.writeline X(lngRow, 1) & lngRecords & ".html"
            For lngInnings = 1 To 2
            strInnings = "Innings " & lngInnings
                objTF.writeline strInnings

                Set tbl = Nothing
                On Error Resume Next
                Set tbl = htmlbody.Document.getElementById("inningsBat" & lngInnings)
                On Error GoTo 0
                If Not tbl Is Nothing Then
                    lngWrite = 0
                    For lngRow1 = 0 To tbl.Rows.Length - 1
                        Set tr = tbl.Rows(lngRow1)
                        If Trim(tr.innerText) <> vbNewLine Then
                            If tr.Cells.Length > 2 Then
                                If tr.Cells(1).innerText <> "Extras" Then
                                    If Len(tr.Cells(1).innerText) > 0 Then
                                        objTF.writeline strInnings & "-" & lngWrite & "," & Trim(tr.Cells(1).innerText) & "," & Trim(tr.Cells(3).innerText)
                                        lngWrite = lngWrite + 1
                                    End If
                                Else
                                    objTF.writeline strInnings & "-" & lngWrite & "," & Trim(tr.Cells(1).innerText) & "," & Trim(tr.Cells(3).innerText)
                                    lngWrite = lngWrite + 1
                                    Exit For
                                End If
                            End If
                        End If
                    Next
                    For lngSpare = 12 To lngWrite Step -1
                        objTF.writeline strInnings & "-" & lngWrite + (12 - lngSpare)
                    Next
                Else
                    For lngSpare = 1 To 13
                        objTF.writeline strInnings & "-" & lngWrite + (12 - lngSpare)
                    Next
                End If
            Next
        Next
    Next
    'Call ConsolidateSheets
End Sub
9
brettdj

RegExは、正規であることが保証されていないため、HTMLを解析するための完全なソリューションではありません。

HtmlAgilityPack を使用してHTMLをクエリする必要があります。これにより、CSSセレクターを使用して、jQueryで行う方法と同様にHTMLをクエリできます。

2
Babak Naffas