#html #vba #web-scraping
#HTML #vba #очистка веб-страниц
Вопрос:
Приветствую всех.
ЦЕЛЬ
Я хочу открыть flashscore.com и получают данные, относящиеся к футбольным матчам. Мне нужны все матчи этого сезона, поэтому ссылку «Показать больше матчей» придется щелкнуть один или несколько раз.
ОГРАНИЧЕНИЯ
- Мне нужно сделать это с помощью VBA
- Этот сайт не поддерживает Internet Explorer
- Я не могу ничего установить на ПК, который будет использоваться, поэтому Selenium отключен в качестве опции
Принимая во внимание все вышесказанное, похоже, единственным оставшимся вариантом является Microsoft XML, v6.0
библиотека.
ЧТО я ПРОБОВАЛ
Я прочитал несколько возможных дубликатов этого поста и попробовал их решения, но, похоже, пока ничего не помогло.
Вот код с комментариями, объясняющими каждую ситуацию:
Option Explicit
Sub Get_Matches()
'REFERENCE TO Microsoft XML, v6.0
Dim httpReq As New MSXML2.XMLHTTP60
Dim doc As MSHTML.HTMLDocument
Dim eleCol As Object
Dim ele As MSHTML.HTMLHtmlElement
'Open site and get html. In comments:things proposed by others but seemed to make no change.
httpReq.Open "GET", "https://www.flashscore.com/football/england/premier-league-2019-2020/results/"
'httpReq.setRequestHeader "If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT"
httpReq.send
Set doc = New MSHTML.HTMLDocument
doc.body.innerHTML = httpReq.responseText
'doc.body.innerHTML = httpReq.responseBody
'Tried to get the div containing the first match:
Set ele = doc.getElementById("g_1_2JDks1o7") '--> returns nothing
'Tried to get the "Show more matches" link:
Set ele = doc.getElementsByClassName("event__more")(0) '--> returns nothing
'Tried to get the first ancestor that has an id:
Set ele = doc.getElementById("live-table") '--> returns nothing
'Tried to get all <a> elements and then narrow them down till I find the "Show more matches" link:
Set eleCol = doc.getElementsByTagName("a")
For Each ele In eleCol
If ele.href Like "*[#]*" And ele.innerText = "Show more matches" Then
Exit For
End If
Next ele
ele.Click '--> I get the "Show more matches" link, but nothing seems to change
'Someone suggested firing onclick event.
ele.FireEvent "onclick" '--> did nothing
'Some people suggested waiting.
'So I tried this:
Do
DoEvents
Loop While doc.readyState = "loading"
If doc.readyState <> "complete" Then GoTo ERROR_END
Set doc = New MSHTML.HTMLDocument
doc.body.innerHTML = httpReq.responseText
'and the Delay_Code_By function below,
Set ele = doc.getElementById("live-table") '--> but still returns nothing
'Some people suggested looping, so the document gets loaded first.
Do: Set ele = doc.getElementById("live-table"): DoEvents: Loop While ele Is Nothing '--> resulted to infinite loop.
Do: Set eleCol = doc.getElementsByClassName("event__more"): DoEvents: Loop Until eleCol.Length > 0 '--> resulted to infinite loop.
'This block extracts html in a txt file in desktop, to help me see it, as it is at runtime.
'------------------------------------------------------------------------------------------
' Dim fso As Scripting.FileSystemObject
' Dim txtFile As Scripting.TextStream
' Set fso = New Scripting.FileSystemObject
' Set txtFile = fso.OpenTextFile(CreateObject("WScript.Shell").SpecialFolders("Desktop") amp; "output.txt", 2, True, TristateTrue)
' txtFile.Write httpReq.responseText
' txtFile.Close
' Set txtFile = Nothing
' Set fso = Nothing
'------------------------------------------------------------------------------------------
'Inside the txt file I found html code that onclick calls some kind of function:
'Tried to call this function:
doc.parentWindow.execScript "document.body.classList.toggle('loading', true);", "JScript" '--> throws automation error (probably there's some error with my syntax).
'I also tried to call this function:
doc.parentWindow.execScript "function(){return cjs.Api.loader.get('cjs').call(function(_cjs){loadMoreGames(_cjs);});};" '--> which did not throw error but did nothing.
Exit Sub
ERROR_END:
MsgBox "error"
End Sub
Public Sub Delay_Code_By(seconds As Integer)
Dim endTime As Date
endTime = DateAdd("s", seconds, Now)
Do While Now < endTime
DoEvents
Loop
End Sub
ВОПРОСЫ
- Если есть какой-либо другой вариант, которого мне не хватает, кроме использования
Microsoft XML, v6.0
библиотеки, пожалуйста, скажите мне попробовать его. - Насколько я понимаю, проблема в том, что элементы, которые я пытаюсь получить, отсутствуют в тот момент, когда я пытаюсь их получить. Если я прав, может ли кто-нибудь, пожалуйста, объяснить мне, почему это происходит, и возможное решение этой проблемы? Если я ошибаюсь, пожалуйста, укажите мне правильное направление.Спасибо.
Обновить
Я публикую этот скриншот на основе комментария @QHarr о просмотре вкладки сеть / xhr.
Комментарии:
1. Если очистка разрешена, посмотрите, можете ли вы найти xhr на вкладке сеть, которая используется для обновления страницы с требуемым содержимым. Нажмите показать больше и посмотрите, что сгенерировано на вкладке сеть.
2. Я сделал то, что вы предложили, и что-то действительно генерируется. Не могли бы вы вкратце объяснить мне, что делается? Я обновлю вопрос скриншотом, чтобы увидеть точно.
3. Если страница динамически обновляется, вы можете увидеть эти обновления на вкладке сеть и, возможно, найти свои данные в одном из этих дополнительных запросов.