cricinfo记分卡的html解析
目标 我希望从中提取20/20板球记分卡数据,理想情况下将其转换为CSV格式,以便在Excel中进行数据分析 例如,当前的澳大利亚Big Bash 2011/12记分卡可从cricinfo记分卡的html解析,html,regex,excel,xml,vba,Html,Regex,Excel,Xml,Vba,目标 我希望从中提取20/20板球记分卡数据,理想情况下将其转换为CSV格式,以便在Excel中进行数据分析 例如,当前的澳大利亚Big Bash 2011/12记分卡可从 游戏1: 最后一场比赛: 背景 我精通使用VBA(自动化IE或使用XMLHTTP然后使用正则表达式)从网站上抓取数据,即 在同一个问题中,有人发表了一条评论,建议进行html解析——这是我以前从未遇到过的问题——因此我研究了以下问题: 查询 虽然我可以编写一个正则表达式来解析下面的cricket数据,但我想知道如何通过
- 游戏1:
- 最后一场比赛:
IE
或使用XMLHTTP
然后使用正则表达式)从网站上抓取数据,即
在同一个问题中,有人发表了一条评论,建议进行html解析——这是我以前从未遇到过的问题——因此我研究了以下问题:
查询
虽然我可以编写一个正则表达式来解析下面的cricket数据,但我想知道如何通过html解析有效地检索这些结果
请记住,我的首选是可重复的CSV格式,包含:
- 比赛的日期/名称
- 第一队的名字
- 输出应为第1队转储多达11条记录(球员未击球的空白记录,即“未击球”)
- 第2队姓名
- 输出最多应为第2队转储11条记录(球员未击球的空白记录)
正则表达式不是解析HTML的完整解决方案,因为它不能保证是常规的
您应该使用来查询HTML。这将允许您使用CSS选择器来查询HTML,类似于使用jQuery进行查询的方式。有两种技术可用于“VBA”。我将逐一描述它们 1) 使用FireFox/Firebug插件/Fiddler 2) 使用Excel的内置工具从web获取数据 因为这篇文章会被很多人阅读,所以我甚至会涵盖显而易见的内容。请随意跳过你知道的任何部分
1)使用FireFox/Firebug插件/Fiddler
火狐: 免费下载() Firebug插件: 免费下载() 小提琴手: 免费下载() 安装Firefox后,安装Firebug插件。Firebug插件允许您检查网页中的不同元素。例如,如果您想知道某个按钮的名称,只需右键单击该按钮,然后单击“使用Firebug检查元素”,它将为您提供该按钮所需的所有详细信息 另一个例子是在一个网站上查找一个表的名称,其中包含您需要废弃的数据 我只有在使用XMLHTTP时才使用Fiddler。当你点击一个按钮时,它可以帮助我看到传递的确切信息。由于抓取站点的机器人数量增加,现在大多数站点为了防止自动抓取,捕获鼠标坐标并传递该信息,而fiddler实际上帮助您调试正在传递的信息。我不会在这里谈论太多细节,因为这些信息可能被恶意使用
现在让我们举一个简单的例子来说明如何在你的问题
中搜索URL。 首先,让我们找到包含该信息的表的名称。只需在表上单击鼠标右键,然后单击“使用Firebug检查元素”,它将为您提供下面的快照 所以现在我们知道我们的数据存储在一个名为“inningsBat1”的表中,如果我们可以将该表的内容提取到Excel文件中,那么我们肯定可以使用数据进行分析。下面是将该表转储到Sheet1中的示例代码 在继续之前,我建议关闭所有Excel并启动一个新实例 启动VBA并插入用户表单。放置命令按钮和webcrowser控件。您的用户表单可能如下所示 将此代码粘贴到Userform代码区域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
希望这有帮助。如果您还有疑问,请告诉我
Sid对于其他对此感兴趣的人,我根据前面的答案使用了下面的代码
比自动化XMLHttp
IE
- 代码为要加载的每个系列生成一个CSV文件(保存在
变量中)X
- 该代码将每场比赛转储到常规的29排范围(不管有多少球员击球),以便以后更容易地进行分析
公共子填充数据表\u XML()
将URL设置为字符串
将ws设置为工作表
长得一样长
暗淡的阴影和长的一样
模糊的印像长的一样
暗淡的lngSpare尽可能长
朦胧的记忆如同漫长
暗淡的lngRow1一样长
尺寸X(1到15,1到4)作为字符串
作为对象的Dim objFSO
作为对象的Dim objTF
Dim xmlHttp作为对象
将htmldoc设置为HTMLDocument
将htmlbody变暗为htmlbody
将tbl设置为HTMLTable
Dim tr为HTMLTableRow
像细绳一样模糊的条纹
s=计时器()
设置xmlHttp=CreateObject(“MSXML2.ServerXMLHTTP”)
设置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)=“印度超级联赛-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)=“大巴什联盟-2011”
X(3,1)=“http://www.espncricinfo.com/ausdomestic-2010/engine/match/"
X(3,2)=461028
X(3,3)=461047
X(3,4)=“大巴什联盟-2010”
设置htmldoc=新的HTMLDocument
设置htmlbody=htmldoc.body
对于lngRow=1到UBound(X,1)
如果Len(X(lngRow,1))=0,则退出
设置objTF=objFSO.createtextfile(“c:\temp\”&X(lngRow,4)&
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
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
Option Explicit
Public Sub test()
WriteOutTable "https://www.espncricinfo.com/series/8044/scorecard/524935/hobart-hurricanes-vs-melbourne-stars-big-bash-league-2011-12"
End Sub
Public Sub WriteOutTable(ByVal url As String)
'required VBE (Alt+F11) > Tools > References > Microsoft HTML Object Library ; Microsoft XML, v6 (your version may vary)
Dim hTable As MSHTML.HTMLTable, clipboard As Object
Dim xhr As MSXML2.xmlhttp60, html As MSHTML.htmlDocument
Set xhr = New MSXML2.xmlhttp60
Set html = New MSHTML.htmlDocument
With xhr
.Open "GET", url, False
.Send
html.body.innerHTML = .responseText
End With
Set hTable = html.querySelector(".batsman")
rowCount = hTable.Rows.Length - 1
For i = rowCount To 0 Step -1
Select Case True
Case i = rowCount Or i = rowCount - 1 Or InStr(hTable.Rows(i).outerHTML, "wicket-details") > 0
hTable.deleteRow i
End Select
Next
Set clipboard = GetObject("New:{1C3B4210-F441-11CE-B9EA-00AA006B1A69}")
clipboard.SetText hTable.outerHTML
clipboard.PutInClipboard
ActiveSheet.Cells(1, 1).PasteSpecial
End Sub