source

cricinfo 점수 카드의 html 구문 분석

factcode 2023. 5. 4. 20:37
반응형

cricinfo 점수 카드의 html 구문 분석

목적

Cricinfo 웹사이트에서 20/20 크리켓 스코어카드 데이터를 긁어모으고 싶습니다. 이상적으로는 Excel의 데이터 분석을 위해 CSV 형태로 만드는 것이 좋습니다.

예를 들어 현재 호주 빅배시 2011/12 스코어카드는 다음 사이트에서 사용할 수 있습니다.

배경

는 VBA 자동화)를 사용합니다.IE 는사용을 사용합니다.XMLHTTP그런 다음 정규식을 사용하여) 웹 사이트에서 데이터를 긁어냅니다. 즉, HTML TDTr에서 값을 추출합니다.

같은 질문에서 HTML 구문 분석을 제안하는 댓글이 게시되었습니다. - 전에 본 적이 없습니다. - 그래서 저는 XHTML 자체 포함 태그를 제외한 RegEx 일치 열린 태그와 같은 질문을 살펴보았습니다.

쿼리

아래 크리켓 데이터를 구문 분석하기 위해 정규식을 작성할 수 있지만 HTML 구문 분석을 통해 이러한 결과를 효율적으로 검색할 수 있는 방법에 대한 조언을 구하고 싶습니다.

다음을 포함하는 반복 가능한 CSV 형식을 선호합니다.

  • 경기 날짜/이름
  • 1팀 이름
  • 출력은 팀 1에 대해 최대 11개의 레코드를 덤프해야 합니다(선수들이 타구하지 않은 빈 레코드, 즉 "Did Not Bat").
  • 2팀 이름
  • 출력은 팀 2에 대해 최대 11개의 레코드를 덤프해야 합니다(선수들이 타구하지 않은 빈 레코드).

Nirvana는 분석을 완전히 자동화할 수 있도록 VBA 또는 VBscript를 사용하여 배포할 수 있는 솔루션이지만 HTML 구문 분석을 위해 별도의 도구를 사용해야 할 것 같습니다.

추출할 샘플 사이트 링크 및 데이터

critinfo 스코어카드 출처일자

제가 "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

반응형