Ответ 1
Честно говоря, мне очень нравится решать/адаптировать ваши вопросы, они действительно сложны. Вот вы:
Sub Get_links()
Dim driver As New WebDriver
Dim CurrentPageHeight As Long, PrevPageHeight As Long
Dim EndofPage As Boolean
'EndofPage = False
With driver
.Start "chrome", "http://fortune.com/fortune500"
.get "/list/"
End With
Do While EndofPage = False
PrevPageHeight = CurrentPageHeight
CurrentPageHeight = driver.ExecuteScript("window.scrollTo(0, document.body.scrollHeight);var CurrentPageHeight=document.body.scrollHeight;return CurrentPageHeight;")
driver.Wait 3000 'depending on your internet connection, increase or decrease time
If PrevPageHeight = CurrentPageHeight Then
EndofPage = True
End If
Loop
End Sub
EDIT:
Я предполагаю, что не существует явного или явного ожидания Selenium в VBA, и нет необходимости.
При очистке веб-страницы, независимо от того, является она Selenium или нет, я всегда предпочитаю полагаться, существует ли элемент на странице. Из моего личного опыта "неявное и явное ожидание" подвело меня как на python, так и на vba, в то время как соскабливание.
Снова, лично, я обнаружил, что VBA более надежен и проще, чем python, не только для очистки, но и для извлечения данных для Excel, поскольку они находятся на одной платформе. Причина этого в том, что я нашел решение, чтобы убедиться, что я очищаю страницу, которую хочу (а не ранее загруженную страницу в цикле). Пожалуйста, проверьте этот пост для вышеупомянутого решения, которое я не смог найти в сети.
Я мог бы реализовать одно и то же с python, но я бы это сделал, только если бы я использовал свои проанализированные данные в api, например. Поскольку он превосходит, VBA - лучший выбор.
В любом случае, я подражаю молчаливому ожиданию вас ниже. Надеюсь, это даст вам представление о вашем комментарии/вопросе.
Sub Get_links()
Dim driver As New WebDriver
Dim CurrentPageHeight As Long, NextPageHeight As Long
Dim EndofPage As Boolean
'EndofPage = False
With driver
.Start "chrome", "http://fortune.com/fortune500"
.get "/list/"
End With
Do
driver.ExecuteScript "window.scrollTo(0, document.body.scrollHeight);"
On Error Resume Next
Debug.Print Split(driver.FindElementsByClass("company-list")(1).Text, vbLf)(3001)
Loop Until Err.Number <> 9
End Sub
Edit2: Причина использования Debug.Print Split(driver.FindElementsByClass("company-list")(1).Text, vbLf)(3001)
заключается в проверке элемента, который принадлежит нижней части страницы, если он существует или нет. В этой фразе нет ничего особенного, вы можете использовать что-то подобное, пока вы можете вернуть элемент снизу. Позвольте мне объяснить мою логику:
Если вы debug.print driver.FindElementsByClass("company-list")(1).Text
, вы увидите, что это полный список, разделенный линейными фидерами.
Итак, я разделил их на vbLf
и получил ранг 1000
в списке, который является 3001-м элементом. Откуда я знаю это? С быстрой простой логикой:
...(1).Text, vbLf)(0) -> RANK
...(1).Text, vbLf)(1) -> COMPANY
...(1).Text, vbLf)(2) -> REVENUES ($M)
...(1).Text, vbLf)(3) -> 1
...(1).Text, vbLf)(4) -> Walmart
...(1).Text, vbLf)(5) -> $485,873
...(1).Text, vbLf)(6) -> 2
.
.
(Rank 1) * 3 = (3)
(Rank 2) * 3 = (6)
.
.
.
(Rank 1000) * 3 = (3000)
Вы должны получить ранг 1000
из (3000), но вы этого не делаете, потому что есть еще один div
сразу после 20-й строки в списке. Так оно и есть (3001). Вы можете использовать 3000, 2950, 2912, что угодно, если они находятся в последних 50 группах.