cricinfo 점수 카드의 html 구문 분석
목적
Cricinfo 웹사이트에서 20/20 크리켓 스코어카드 데이터를 긁어모으고 싶습니다. 이상적으로는 Excel의 데이터 분석을 위해 CSV 형태로 만드는 것이 좋습니다.
예를 들어 현재 호주 빅배시 2011/12 스코어카드는 다음 사이트에서 사용할 수 있습니다.
- 게임 1: http://www.espncricinfo.com/big-bash-league-2011/engine/match/524915.html
- 마지막 게임: http://www.espncricinfo.com/big-bash-league-2011/engine/match/524935.html
배경
는 VBA 자동화)를 사용합니다.IE
는사용을 사용합니다.XMLHTTP
그런 다음 정규식을 사용하여) 웹 사이트에서 데이터를 긁어냅니다. 즉, HTML TD 및 Tr에서 값을 추출합니다.
같은 질문에서 HTML 구문 분석을 제안하는 댓글이 게시되었습니다. - 전에 본 적이 없습니다. - 그래서 저는 XHTML 자체 포함 태그를 제외한 RegEx 일치 열린 태그와 같은 질문을 살펴보았습니다.
쿼리
아래 크리켓 데이터를 구문 분석하기 위해 정규식을 작성할 수 있지만 HTML 구문 분석을 통해 이러한 결과를 효율적으로 검색할 수 있는 방법에 대한 조언을 구하고 싶습니다.
다음을 포함하는 반복 가능한 CSV 형식을 선호합니다.
- 경기 날짜/이름
- 1팀 이름
- 출력은 팀 1에 대해 최대 11개의 레코드를 덤프해야 합니다(선수들이 타구하지 않은 빈 레코드, 즉 "Did Not Bat").
- 2팀 이름
- 출력은 팀 2에 대해 최대 11개의 레코드를 덤프해야 합니다(선수들이 타구하지 않은 빈 레코드).
Nirvana는 분석을 완전히 자동화할 수 있도록 VBA 또는 VBscript를 사용하여 배포할 수 있는 솔루션이지만 HTML 구문 분석을 위해 별도의 도구를 사용해야 할 것 같습니다.
추출할 샘플 사이트 링크 및 데이터
제가 "VBA"에 사용하는 두 가지 기술이 있습니다.저는 그것들을 하나씩 설명하겠습니다.
FireFox / Firebug Addon / Fiddler 사용
Excel의 내장 기능을 사용하여 웹에서 데이터 가져오기
이 게시물은 많은 사람들이 읽을 것이기 때문에 저는 당연한 것까지 다룰 것입니다.알고 있는 부분은 자유롭게 건너뜁니다.
FireFox / Firebug Addon / Fiddler 사용
FireFox : http://en.wikipedia.org/wiki/Firefox 무료 다운로드 (http://www.mozilla.org/en-US/firefox/new/)
파이어버그 애드온: 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 Addon을 설치합니다.Firebug Addon을 사용하여 웹 페이지의 다양한 요소를 검사할 수 있습니다.예를 들어, 단추 이름을 알고 싶다면 해당 단추를 마우스 오른쪽 단추로 클릭하고 "Inspect Element with Firebug"를 클릭하면 해당 단추에 필요한 모든 세부 정보가 제공됩니다.
또 다른 예는 폐기해야 할 데이터가 있는 웹 사이트에서 테이블 이름을 찾는 것입니다.
저는 XMLHTTP를 사용할 때만 Fiddler를 사용합니다.단추를 클릭하면 전달되는 정확한 정보를 볼 수 있습니다.사이트를 스크랩하는 BOT의 수가 증가했기 때문에 현재 대부분의 사이트는 자동 폐기를 방지하기 위해 마우스 좌표를 캡처하고 정보를 전달하고 피들러는 전달되는 정보를 디버깅하는 데 실제로 도움이 됩니다.이 정보는 악의적으로 사용될 수 있기 때문에 여기서 자세히 설명하지 않겠습니다.
이제 질문에 게시된 URL을 지우는 방법에 대해 간단한 예를 들어 보겠습니다.
http://www.espncricinfo.com/big-bash-league-2011/engine/match/524915.html
먼저 해당 정보가 있는 테이블의 이름을 찾아보겠습니다.표를 마우스 오른쪽 버튼으로 클릭하고 "Inspect Element with Firebug"를 클릭하면 아래의 스냅샷이 제공됩니다.
이제 데이터가 "inningsBat1"이라는 테이블에 저장된다는 것을 알게 되었습니다. 이 테이블의 내용을 Excel 파일로 추출할 수 있다면 데이터를 사용하여 분석을 수행할 수 있습니다.다음은 시트 1의 테이블을 덤프할 샘플 코드입니다.
진행하기 전에 모든 Excel을 닫고 새로운 인스턴스를 시작하는 것이 좋습니다.
VBA를 시작하고 사용자 양식을 삽입합니다.명령 단추와 웹 브라우저 컨트롤을 배치합니다.사용자 양식은 다음과 같을 수 있습니다.
사용자 양식 코드 영역에 이 코드를 붙여넣습니다.
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
이제 사용자 양식을 실행하고 명령 단추를 클릭합니다.데이터가 시트 1에 덤프된다는 것을 알 수 있습니다.스냅샷 참조
마찬가지로 다른 정보도 긁어낼 수 있습니다.
Excel의 내장 기능을 사용하여 웹에서 데이터 가져오기
당신이 엑셀 2007을 사용하고 있다고 생각하기 때문에 위 링크를 예로 들겠습니다.
시트 2로 이동합니다.이제 데이터 탭으로 이동하여 오른쪽 끝에 있는 "웹에서" 버튼을 클릭합니다.스냅샷을 참조하십시오.
새 웹 쿼리 창에 URL을 입력하고 "이동"을 클릭합니다.
페이지가 업로드되면 스냅샷에 표시된 대로 작은 화살표를 클릭하여 가져올 관련 테이블을 선택합니다.완료되면 "가져오기"를 클릭합니다.
그런 다음 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
이게 도움이 되길 바랍니다.아직 문의 사항이 있으면 알려주세요.
시드
이에 관심이 있는 다른 사람들을 위해 저는 Siddhart Rout의 이전 답변을 기반으로 아래 코드를 사용하게 되었습니다.
XMLHttp
자동화보다 훨씬 빠름IE
- 코드는 다운로드할 각 영상 시리즈에 대해 CSV 파일을 생성합니다(에서 보관).
X
가변) - 코드는 각 경기를 정규 29열 범위(타격한 선수 수에 관계없이)로 덤프하여 나중에 더 쉽게 분석할 수 있도록 합니다.
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
RegEx는 HTML을 구문 분석하기 위한 완전한 솔루션이 아닙니다. 이는 정규화가 보장되지 않기 때문입니다.
HTML을 쿼리하려면 HtmlAgilityPack을 사용해야 합니다. 이렇게 하면 CSS 선택기를 사용하여 jQuery로 수행하는 방법과 유사한 HTML을 쿼리할 수 있습니다.
많은 사람들이 이것을 볼 수 있기 때문에 VBA 웹스크래핑에서 사용하는 사람들을 거의 볼 수 없는 몇 가지 기능을 보여주는 기회로 사용할 것이라고 생각했습니다.deleteRow, querySelector
및 사용clipboard
표(포맷과 하이퍼링크가 포함된)를 다음을 기반으로 시트에 작성합니다.table.outerHTML
.
deleteRow는 원하지 않는 행을 제거하는 데 사용됩니다.querySelector는 노드에서 일치하도록 더 빠른 CSS Selector를 적용하는 데 사용됩니다.최신 브라우저/html 파서는 CSS에 최적화되어 있으며 클래스 선택기(제가 사용하는)는 ID 다음으로 빠른 선택기 유형입니다.
CSS 선택기 사용 및 이해htmlTable
방법/속성을 통해 웹 캐핑 작업을 훨씬 더 유연하게 수행할 수 있습니다.클립보드 사용을 이해한다는 것은 테이블을 Excel로 전송하기 위한 간단한 복사 붙여넣기 방법을 의미합니다.
실행은 버튼 누르기와 셀에서 읽은 URL에 쉽게 연결될 수 있습니다.
VBA:
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
언급URL : https://stackoverflow.com/questions/8798260/html-parsing-of-cricinfo-scorecards
'source' 카테고리의 다른 글
Android용 스프레드시트 위젯이 있습니까? (0) | 2023.05.04 |
---|---|
Eclipse용 경량 SQL 편집기 (0) | 2023.05.04 |
의 버전을 반환하는 PowerShell 스크립트.기계의 NET Framework? (0) | 2023.05.04 |
그래프에서 xxick을 제거하는 방법 (0) | 2023.05.04 |
PostgreSQL에서 다대다 관계를 구현하는 방법은 무엇입니까? (0) | 2023.05.04 |