HTML-разбор показателей Cricinfo - PullRequest
35 голосов
/ 10 января 2012

Цель

Я собираюсь собрать данные карты крикета 20/20 с веб-сайта Cricinfo , в идеале - Форма CSV для данныханализ в Excel

Например, текущие Australian Big Bash 2011/12 системы показателей доступны из

Фон

Я владею навыками использования VBA (либо автоматизации IE, либо использования XMLHTTP изатем с помощью регулярных выражений) для очистки данных с веб-сайтов, например Извлечение значений из HTML TD и Tr

В этом же вопросе был опубликован комментарий с предложением разбора html - который я не встречалраньше - поэтому я посмотрел на такие вопросы, как RegEx сопоставить открытые теги, кроме автономных тегов XHTML

Запрос

Хотя я могнапишите регулярное выражение для анализа данных по крикету ниже, я хотел бы получить совет относительно того, как я могу эффективно получитьРезультаты поиска с html-разбором.

Пожалуйста, имейте в виду, что я предпочитаю повторяющийся формат CSV, содержащий:

  • дата / название матча
  • Команда 1name
  • вывод должен содержать до 11 записей для команды 1 (пустые записи, в которых игроки не били, т. е. "Not Bat" )
  • название команды 2
  • выходные данные должны выводить до 11 записей для команды 2 (пустые записи, где игроки не сражались)

Для меня Nirvana - это решение, которое я мог бы развернуть, используя VBA илиVBscript, чтобы я мог полностью автоматизировать свой анализ, но я предполагаю, что мне придется использовать отдельный инструмент для анализа html.

Примеры ссылок на сайты и извлекаемые данные

cricinfo scorecard source date

Ответы [ 3 ]

50 голосов
/ 13 января 2012

Есть 2 техники, которые я использую для "VBA".Я опишу их по одному.

1) Использование FireFox / Firebug Addon / Fiddler

2) Использование встроенного средства Excel для получения данных из Интернета

С этого постабудет прочитано многими, поэтому я даже покрою очевидное.Пожалуйста, не стесняйтесь пропустить любую часть, которую вы знаете


1) Использование FireFox / Firebug Addon / Fiddler


FireFox: http://en.wikipedia.org/wiki/FirefoxБесплатно скачать (http://www.mozilla.org/en-US/firefox/new/)

Firebug Addon: 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 позволяет вам проверять различные элементы на веб-странице. Например, если вы хотите узнать имя кнопки, просто щелкните по ней правой кнопкой мыши и нажмите «Проверить»«Элемент с Firebug», и он предоставит вам все детали, которые вам понадобятся для этой кнопки.

enter image description here

Другим примером будет поиск имени таблицы на веб-сайте, который имеетданные, которые вам нужно удалить.

Я использую Fiddler только тогда, когда использую XMLHTTP. Это помогает мне видеть точную информацию, передаваемую при нажатии на кнопку. Из-за увеличения числа BOTS, которыецарапать сайты, большинство сайтов нетw, чтобы предотвратить автоматическую утилизацию, захватывайте координаты мыши и передавайте эту информацию, а Fiddler фактически помогает вам в отладке передаваемой информации.Я не буду здесь вдаваться в подробности, так как эту информацию можно использовать злонамеренно.

Теперь давайте рассмотрим простой пример того, как очистить URL, размещенный в вашем вопросе

http://www.espncricinfo.com/big-bash-league-2011/engine/match/524915.html

Сначала давайте найдем имя таблицы, в которой есть эта информация.Просто щелкните правой кнопкой мыши по таблице и нажмите «Проверить элемент с помощью Firebug», и он даст вам снимок ниже.

enter image description here

Итак, теперь мы знаем, что наши данные хранятся втаблица с именем "inningsBat1" Если мы можем извлечь содержимое этой таблицы в файл Excel, то мы определенно можем работать с данными для нашего анализа.Вот пример кода, который будет выгружать эту таблицу в Sheet1

. Прежде чем мы продолжим, я бы рекомендовал закрыть весь Excel и запустить новый экземпляр.

Запустить VBA и вставить пользовательскую форму.Поместите командную кнопку и веб-браузер управления.Ваша пользовательская форма может выглядеть следующим образом:

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

Теперь запустите пользовательскую форму и нажмите кнопку Command.Вы заметите, что данные сбрасываются в Sheet1.См. Снимок

enter image description here

Точно так же вы можете копировать и другую информацию.


2) Использование встроенного средства Excel для получения данных из Интернета


Я полагаю, что вы используете Excel 2007, поэтому я возьму это в качестве примера для очистки вышеупомянутой ссылки.

Перейдите к Sheet2.Теперь перейдите на вкладку «Данные» и нажмите на кнопку «Из Интернета» в крайнем правом углу.См. Снимок экрана.

enter image description here

Введите 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

Надеюсь, это поможет.Дайте мне знать, если у вас все еще есть какие-либо вопросы.

Сид

9 голосов
/ 16 июня 2012

Для всех, кто заинтересован в этом, я использовал приведенный ниже код, основанный на предыдущем ответе Сиддхарта Раута

  • XMLHttp был значительно быстрее, чем автоматизация IE
  • код генерирует CSV-файл для каждой серии, которую необходимо загрузить (содержится в переменной X)
  • код сбрасывает каждое совпадение в обычный диапазон из 29 строк (независимо от количества игроков)чтобы облегчить анализ позже

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
2 голосов
/ 12 января 2012

RegEx не является полным решением для анализа HTML, потому что он не гарантированно является регулярным.

Вы должны использовать HtmlAgilityPack для запроса HTML. Это позволит вам использовать селекторы CSS для запроса HTML, аналогично тому, как вы делаете это с jQuery.

...