2017-12-13 23 views
0

나는 this post을 발견했습니다. 나는 받아 들인 대답에 의해 제안 된 해결책을 시도하고 다음 코드를 생각해 내었다.VBA 웹 스크래핑과 런타임 오류 91 시간에서

Sub WebScraping() 

Dim appIE As Object 
Dim myValue As String 
Dim iLastRow As Integer 
Dim allRowOfData 

Application.DisplayAlerts = False 

Set appIE = CreateObject("internetexplorer.application") 

With appIE 
    .Navigate "http://uk.investing.com/rates-bonds/financial-futures" 
    .Visible = False 
End With 

Do While appIE.Busy 
    DoEvents 
Loop 

'Set allRowOfData = appIE.document.getElementById("pair_8907") 

Worksheets("Web Scraping").Activate 

'myValue = allRowOfData.Cells(7).innerHTML 
myValue = appIE.document.getElementById("pair_8907").Cells(7).innerHTML 

iLastRow = ActiveSheet.Range("B100000").End(xlUp).Row 
ActiveSheet.Cells(iLastRow, 1).Select 

If iLastRow = 1 Then 
    ActiveCell.Offset(1, 0).Value = "US 30Y T-Bond" 
    ActiveCell.Offset(1, 1).Value = myValue 
    ActiveCell.Offset(1, 2).Value = Now() 
    ActiveCell.Offset(1, 2).Select 
ElseIf iLastRow > 1 Then 
    ActiveCell.Copy Destination:=Cells(ActiveCell.Row + 1, 1) 
    ActiveCell.Offset(1, 1).Value = myValue 
    ActiveCell.Offset(1, 2).Value = Now() 
    ActiveCell.Offset(1, 2).Select 
End If 

appIE.Quit 
Set appIE = Nothing 
Set allRowOfData = Nothing 

End Sub 

내 스크립트는 10 배에서 원활 9를 실행하지만 때때로 오류가 발생합니다 : 즉 VBE 디버거 명령은 내가 생각

myValue = appIE.document.getElementById("pair_8907").Cells(7).innerHTML 
+1

오류 처리를하는 것이 유용 할 수 있습니다. 웹 사이트로드가 준비되었다고 가정하면 appIE가 더 이상 사용되지 않지만 웹 사이트가 완전히로드되지 않았습니다 (예 : 인터넷 연결 오류로 인해). 이 경우 유효한 appI.document가있을 수 있지만 아마도 그 순간에 ID "pair_8907"을 가진 요소가 없으므로 .Cells (7) .innerHTML은 오류를 발생시킬 수 있습니다. 언제나 안전을 위해 모든 스크 레이 핑을 확인해야합니다. - 잠시 후 유효한 문서가 있습니까? - 문서에 주어진 ID가있는 요소가 있습니까? -이 요소가 8 개입니까? – DaDirnbocher

답변

0

에서 정지 보여줍니다 발생하면 error message

을 당신은로드 할 수있는 충분한 시간을주지 못하고 있습니다 ... 페이지가로드 될 때까지 기다리는이 함수 WaitIE가 있습니다. 오류가 계속 발생하면 5000ms로 설정되고 더 많은 시간을줍니다.

#If VBA7 Then 
    Public Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As LongPtr) 'For 64 Bit Systems 
#Else 
    Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds as Long) 'For 32 Bit Systems 
#End If 

Sub WebScraping() 

Dim appIE As Object 
Dim myValue As String 
Dim iLastRow As Integer 
Dim allRowOfData 

Application.DisplayAlerts = False 

Set appIE = CreateObject("internetexplorer.application") 

With appIE 
    .Navigate "http://uk.investing.com/rates-bonds/financial-futures" 
    .Visible = False 
End With 

    WaitIE appIE, 5000 

'Set allRowOfData = appIE.document.getElementById("pair_8907") 

Worksheets("Web Scraping").Activate 

'myValue = allRowOfData.Cells(7).innerHTML 
myValue = appIE.document.getElementById("pair_8907").Cells(7).innerHTML 

iLastRow = ActiveSheet.Range("B100000").End(xlUp).Row 
ActiveSheet.Cells(iLastRow, 1).Select 

If iLastRow = 1 Then 
    ActiveCell.Offset(1, 0).Value = "US 30Y T-Bond" 
    ActiveCell.Offset(1, 1).Value = myValue 
    ActiveCell.Offset(1, 2).Value = Now() 
    ActiveCell.Offset(1, 2).Select 
ElseIf iLastRow > 1 Then 
    ActiveCell.Copy Destination:=Cells(ActiveCell.Row + 1, 1) 
    ActiveCell.Offset(1, 1).Value = myValue 
    ActiveCell.Offset(1, 2).Value = Now() 
    ActiveCell.Offset(1, 2).Select 
End If 

appIE.Quit 
Set appIE = Nothing 
Set allRowOfData = Nothing 

End Sub 

Sub WaitIE(IE As Object, Optional time As Long = 250) 
'Code from: https://stackoverflow.com/questions/33808000/run-time-error-91-object-variable-or-with-block-variable-not-set 
Dim i As Long 
Do 
    Sleep time 
    Debug.Print CStr(i) & vbTab & "Ready: " & CStr(IE.READYSTATE = 4) & _ 
       vbCrLf & vbTab & "Busy: " & CStr(IE.Busy) 
    i = i + 1 
Loop Until IE.READYSTATE = 4 Or Not IE.Busy 
End Sub 
+0

힌트를 보내 주셔서 감사합니다. 나는 잠자기와 비슷한 기능인 Application.Wait을 시험해 보았고 문제를 해결 한 것으로 보인다. – RookieNoMore