2017-03-27 5 views
2

이 특정 웹 페이지의 데이터를 스크랩하는 끔찍한 시간이 있습니다 ... 기본적으로 URL을로드 할 때 'DOM Explorer'에서 필요한 정보를 볼 수 있습니다. 브라우저 및 수동 F12 충돌,하지만 난 프로그래밍 ... HTMLDOC 내가 'DOM 탐색기'에서 볼 수있는 것과 같은 정보를 포함하지 않습니다 (아래 참조) 같은VBA를 사용한 웹 스크래핑 (HTML <> DOM 인 경우)

Public Sub testCode() 
Dim IE As SHDocVw.InternetExplorer 
Dim HTMLDoc As MSHTML.HTMLDocument 
Set IE = New SHDocVw.InternetExplorer 
With IE 
    .navigate "https://www.wunderground.com/cgi-bin/findweather/getForecast?query=EIDW" 
    While .Busy = True Or .ReadyState <> READYSTATE_COMPLETE: Wend 
    Set HTMLDoc = .Document 
End With 
End Sub 

수있는 사람하시기 바랍니다 할 시도 할 때 'DOM Explorer'의 정보에 액세스하는 데 도움을 줍니까 ?? HTML은 항상 브라우저에서 보는 것이 아니라 브라우저에서 볼 수있는 것을 만드는 지침이지만 프로그래밍 방식으로 HTML에서 DOM을 만드는 방법이 있어야합니다. 또한 이후의 데이터가 스크립트 또는 iFrames에 의해 생성되고 있다고 생각하지만, 내가 찾고있는 데이터를 생성 할 수 없었습니다 ...

EDIT- 추가 정보 : DOM의 그림보기 Explorer below- enter image description here

도와주세요!

+0

더 구체적으로 예상되는 출력을 게시하십시오. 아마도 데이터가있는 강조 표시된 영역과 스크래핑하는 URL이있는 웹 페이지의 스크린 샷을 게시하십시오. [이 질문] (http://stackoverflow.com/q/40225095/2165759) 도움이 될 수 있습니다. – omegastripes

+0

안녕하세요 @omegastripes - 스크린 샷을 넣으려고했지만 편집 창에 붙여 넣을 수 없습니다 .... 필요한 정보가 있으면 알려 주시기 바랍니다. 보내 주시면 알려 드리겠습니다. . 또한 지금 다른 예제를 통해보고 있는데, 지금까지 행운이 없습니다. – TheSilkCode

+0

[편집 도움] (http://stackoverflow.com/editing-help) - [images] (http://stackoverflow.com/editing -help # images) * CTRL + I를 눌러 이미지를 삽입 할 수도 있습니다 *. –

답변

1

개요 : https://www.wunderground.com/cgi-bin/findweather/getForecast?query=EIDW

사실 웹 브라우저는 웹 페이지를 열 때마다 거의 동일한 작업을 수행합니다.

아래의 VBA 코드를 사용하여 응답 및 출력 결과를 구문 분석 할 수 있습니다. JSON.bas 모듈을 JSON 처리 용 VBA 프로젝트로 가져옵니다.

Sub TestScrapeWunderground() 

    Dim sContent As String 
    Dim sKey As String 
    Dim sLocation As String 
    Dim vJSON As Variant 
    Dim sState As String 
    Dim oDays As Object 
    Dim oHours As Object 
    Dim vDay As Variant 
    Dim vHour As Variant 
    Dim aRows() As Variant 
    Dim aHeader() As Variant 

    ' GET XHR to retrieve location and key 
    With CreateObject("MSXML2.ServerXMLHTTP") 
     .Open "GET", "https://www.wunderground.com/cgi-bin/findweather/getForecast?query=EIDW", False 
     .Send 
     sContent = .responseText 
    End With 
    ' Extract location and key from HTML content 
    sLocation = Split(Split(sContent, "var query = 'zmw:' + '", 2)(1), "'", 2)(0) 
    sKey = Split(Split(sContent, vbTab & "k: '", 2)(1), "'", 2)(0) 
    ' GET XHR to retrieve JSON data 
    With CreateObject("MSXML2.ServerXMLHTTP") 
     .Open "GET", "https://api-ak-aws.wunderground.com/api/" & sKey & "/forecast10day/hourly10day/labels/conditions/astronomy10day/lang:en/units:metric/v:2.0/bestfct:1/q/zmw:" & sLocation & ".json", False 
     .Send 
     sContent = .responseText 
    End With 
    ' Parse JSON response to data structure 
    JSON.Parse sContent, vJSON, sState 
    ' Populate dictionaries with daily and hourly forecast data 
    Set oDays = CreateObject("Scripting.Dictionary") 
    Set oHours = CreateObject("Scripting.Dictionary") 
    For Each vDay In vJSON("forecast")("days") 
     oDays(vDay("summary")) = "" 
     For Each vHour In vDay("hours") 
      oHours(vHour) = "" 
     Next 
    Next 
    ' Convert daily forecast data to arrays 
    JSON.ToArray oDays.Keys(), aRows, aHeader 
    ' Output daily forecast data to table 
    With Sheets(1) 
     .Cells.Delete 
     OutputArray .Cells(1, 1), aHeader 
     Output2DArray .Cells(2, 1), aRows 
     .Columns.AutoFit 
    End With 
    ' Convert hourly forecast data to arrays 
    JSON.ToArray oHours.Keys(), aRows, aHeader 
    ' Output hourly forecast data to table 
    With Sheets(2) 
     .Cells.Delete 
     OutputArray .Cells(1, 1), aHeader 
     Output2DArray .Cells(2, 1), aRows 
     .Columns.AutoFit 
    End With 
    ' Convert response data to arrays 
    JSON.ToArray Array(vJSON("response")), aRows, aHeader 
    ' Output response transposed data to table 
    With Sheets(3) 
     .Cells.Delete 
     Output2DArray .Cells(1, 1), WorksheetFunction.Transpose(aHeader) 
     Output2DArray .Cells(1, 2), WorksheetFunction.Transpose(aRows) 
     .Columns.AutoFit 
    End With 
    ' Convert current data to arrays 
    JSON.ToArray Array(vJSON("current_observation")), aRows, aHeader 
    ' Output current transposed data to table 
    With Sheets(4) 
     .Cells.Delete 
     Output2DArray .Cells(1, 1), WorksheetFunction.Transpose(aHeader) 
     Output2DArray .Cells(1, 2), WorksheetFunction.Transpose(aRows) 
     .Columns.AutoFit 
    End With 
    ' Populate dictionary with daily astronomy data 
    Set oDays = CreateObject("Scripting.Dictionary") 
    For Each vDay In vJSON("astronomy")("days") 
     oDays(vDay) = "" 
    Next 
    ' Convert daily astronomy data to arrays 
    JSON.ToArray oDays.Keys(), aRows, aHeader 
    ' Output daily astronomy transposed data to table 
    With Sheets(5) 
     .Cells.Delete 
     Output2DArray .Cells(1, 1), WorksheetFunction.Transpose(aHeader) 
     Output2DArray .Cells(1, 2), WorksheetFunction.Transpose(aRows) 
     .Columns.AutoFit 
    End With 
    ' Convert hourly history data to arrays 
    JSON.ToArray vJSON("history")("days")(0)("hours"), aRows, aHeader 
    ' Output hourly history data to table 
    With Sheets(6) 
     .Cells.Delete 
     OutputArray .Cells(1, 1), aHeader 
     Output2DArray .Cells(2, 1), aRows 
     .Columns.AutoFit 
    End With 
    MsgBox "Completed" 

End Sub 

Sub OutputArray(oDstRng As Range, aCells As Variant) 

    With oDstRng 
     .Parent.Select 
     With .Resize(_ 
       1, _ 
       UBound(aCells) - LBound(aCells) + 1) 
      .NumberFormat = "@" 
      .Value = aCells 
     End With 
    End With 

End Sub 

Sub Output2DArray(oDstRng As Range, aCells As Variant) 

    With oDstRng 
     .Parent.Select 
     With .Resize(_ 
       UBound(aCells, 1) - LBound(aCells, 1) + 1, _ 
       UBound(aCells, 2) - LBound(aCells, 2) + 1) 
      .NumberFormat = "@" 
      .Value = aCells 
     End With 
    End With 

End Sub 

두 번째 XHR

는, 파일로 JSON을 저장 내용을 복사 및 추가 연구에 대한 JSON 뷰어에 붙여 넣을 수 있습니다, 필요한 데이터가 추출되는 방식이 명확하게하기 위해, JSON 데이터를 반환합니다. 6 개 가지 주요 섹션, 실행하기 전에 수동으로 작성해야 6 개 워크 시트 (에 관련 추출 된 데이터의 일부 출력이 있습니다

JSON structure

: 나는 온라인 도구 http://jsonviewer.stack.hu를 사용하여 루트 요소의 구조는 다음과 같습니다) :

Sheet1 - Daily forecast 
Sheet2 - Horly forecast 
Sheet3 - Response data (transposed) 
Sheet4 - Current data (transposed) 
Sheet5 - Astronomy (transposed) 
Sheet6 - Hourly history data 

해당 예제를 사용하여 해당 JSON 응답에서 필요한 데이터를 추출 할 수 있습니다.

+0

이것은 환상적입니다. 거기에 많은 부분이 있으므로 모든 테스트를 끝내지는 못했지만 올바른 트랙에서 나를 얻을 수 있다고 확신합니다. 너무 많이! – TheSilkCode

+0

마침내이 모든 것을 테스트 해 보았습니다. 도움을 주셔서 감사합니다.하지만 몇 가지 사항을 변경했습니다. 1) 관심있는 데이터를 요청하기 위해 API URL을 자르고 영어로 단위를 변경하고 2) JSON 파서 솔루션을 사용하는 대신 실제로 데이터를 파싱하기 위해 일련의 분할 및 루프를 사용했습니다. 그 이유 중 하나는 JSON 구문 분석 코드를 따르는 데 어려움이 있었기 때문에 복사 및 붙여 넣은 코드를 사용하고 싶지 않았기 때문입니다 이해할 수는 없지만 Rage 및 Scripting Dictionaries를 사용하여 파싱하는 것보다 ~ 60 % 빠름을 발견했습니다. 어쨌든 다시 고마워! – TheSilkCode