2012-01-10 52 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