2012-01-10 84 views
34

目的HTML解析記分卡

我期待從Cricinfo website刮20/20板球記分卡的數據,最好到CSV形式進行數據分析在Excel

作爲一個例子,當前澳大利亞大盛會2011/12記分卡可從

背景

我在使用VBA(無論是自動IE或使用XMLHTTP,然後使用正則表達式)刮從網站的數據精通,即 Extract values from HTML TD and Tr

在同一個問題中,發佈了一條意見,建議html解析 - 我之前沒有討論過這個問題 - 所以我看了一些問題,比如RegEx match open tags except XHTML self-contained tags

查詢

雖然我可以寫一個正則表達式解析板球數據下面我想建議,我怎麼能有效地獲取這些結果與HTML解析。

請記住,我的選擇是含有重複的CSV格式:比賽

  • 隊1名
  • 輸出應該轉儲多達11條記錄爲團隊的

    • 日期/名稱1(空白記錄,玩家都沒有擊出,即「沒有蝙蝠」
    • 隊2名
    • 輸出應該轉儲多達11個記錄隊2(空白記錄,讓玩家沒有擊)

    涅槃對我將是我可以部署使用VBA或VBScript,所以我可以完全自動化我的分析解決方案,但我相信我將不得不使用一個單獨的工具html解析。

    示例站點鏈接和數據提取

    cricinfo scorecard source date

  • +0

    只是一個簡單的查詢,我以爲爬行的Cricinfo是非法的! – 2016-11-01 15:42:10

    回答

    48

    我有2種技術用於「VBA」。我會一一介紹他們。

    1)使用Firefox/Firebug的附加組件/提琴手

    2)使用Excel的內置工具從網上

    獲取數據由於這篇文章會被很多人讀,所以我甚至將覆蓋明顯。請隨時跳過你知道什麼部分


    1)使用Firefox/Firebug的附加組件/提琴手


    火狐: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/

    提琴手:http://en.wikipedia.org/wiki/Fiddler_%28software%29 免費下載(http://www.fiddler2.com/fiddler2/

    一旦你已經安裝了Firefox,安裝Firebug的附加組件。 Firebug Addon讓你檢查網頁中的不同元素。例如,如果您想知道按鈕的名稱,只需右鍵單擊它並單擊「使用Firebug檢查元素」,它會爲您提供該按鈕所需的所有詳細信息。

    enter image description here

    另一個例子是一個網站,有你需要報廢的數據上找到一個表的名稱。

    我只在使用XMLHTTP時才使用Fiddler。它可以幫助我查看點擊按鈕時傳遞的確切信息。由於刮擦站點的BOTS數量增加,現在大多數站點爲了防止自動報廢,捕獲鼠標座標並傳遞該信息,小提琴手實際上可以幫助您調試正在傳遞的信息。我不會在這裏詳細介紹它,因爲這些信息可以被惡意使用。

    現在,讓我們對如何刮網址張貼在你的問題

    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的內置工具從網上


    我相信你正在使用Excel 2007中,所以我將它作爲例子來颳去上面提到的鏈接中獲取數據。

    導航到Sheet2。現在導航到「數據」選項卡,然後單擊最右側的「從網站」按鈕。見快照。

    enter image description here

    在「新建Web查詢窗口」輸入URL,然後單擊「轉到」

    一旦頁面上傳,選擇您想通過點擊小導入相關的表箭頭如快照中所示。完成後,點擊「導入」

    enter image description here

    Excel稍後會問你要導入的數據。選擇相關單元格,然後單擊確定。你完成了!數據將被導入到您指定的單元格中。

    如果你願意,你可以錄製宏並自動執行此,以及:)

    這裏是我記錄的宏。

    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 
    

    希望這有助於。如果您仍然有疑問,請告訴我。

    希德

    +5

    這個答案很清楚和詳盡。我希望這會幫助brettdj。 – JMax 2012-01-14 12:46:37

    +1

    謝謝西德。雖然這是一個與我預期不同的結果,但直接提到適當的html表格優於解析。 – brettdj 2012-01-15 03:28:18

    +0

    excel bwhaahahah的力量:) – 2012-10-15 13:40:07

    2

    正則表達式是不是因爲它不能保證是正規解析HTML的完整解決方案。

    您應該使用HtmlAgilityPack來查詢HTML。這將允許您使用CSS選擇器來查詢HTML,與您如何使用jQuery進行查詢相似。

    +0

    雖然鏈接是讚賞 - 我會進一步看看它 - 我期待有關方法的詳細反饋,工具的優缺點等給予有獎勵提供。 – brettdj 2012-01-12 08:28:28

    9

    對於任何人在這個最後我用下面根據Siddhart Rout's代碼的興致早些時候回答

    • XMLHttp是不是自動IE
    • 代碼生成CSV文件顯著更快每個系列都要下載(保存在X變量中)
    • 代碼將每個匹配轉儲到常規29行範圍(不管有多少玩家擊),以facillitate更容易分析以後

    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 
    
    +1

    + 1已經錯過了這個回覆... – 2012-12-18 13:29:50

    +0

    我給它一個upvote,但是它有一點點太硬編碼的信息在我看來,你可以拿出一個比X更好的變量名。:) – 2016-02-23 20:39:04

    +0

    @ rickhenderson Thx爲upvote;)不知道你的硬編碼評論是指什麼,除了最初的安裝程序指向代碼適當的一系列匹配? – brettdj 2016-02-24 00:50:05