programing

vba를 사용하여 웹 사이트에서 데이터 스크랩

padding 2023. 7. 12. 22:19
반응형

vba를 사용하여 웹 사이트에서 데이터 스크랩

저는 vba를 통해 웹사이트 http://uk.investing.com/rates-bonds/financial-futures 에서 데이터를 긁어내려고 합니다. 예를 들어, 독일의 5 YR Bobl, 미국의 30 YT-Bond, 저는 엑셀 웹 쿼리를 시도했지만 그것은 전체 웹사이트를 긁어내고 싶을 뿐입니다. 이것을 할 수 있는 방법이 있나요?

이 작업에는 여러 가지 방법이 있습니다.이것은 "웹 사이트에서 데이터 스크랩" 키워드를 검색할 때 Internet Explorer 자동화의 모든 기본 사항을 찾을 수 있기를 바라며 작성하는 답변입니다. 그러나 사용자 지정할 수 없는 사전 작성된 코드를 고수하고 싶지 않은 경우에는 사용자가 직접 조사할 만한 가치가 없습니다.

방법은 성능 면에서는 선호하지 않지만(브라우저 속도에 따라 다르기 때문에) 인터넷 자동화의 근거를 이해하는 것이 좋습니다.

웹을 검색해야 한다면 브라우저가 필요합니다!Internet Explorer 브라우저를 만듭니다.

Dim appIE As Object
Set appIE = CreateObject("internetexplorer.application")

브라우저에서 대상 웹 페이지를 탐색하도록 요청합니다.속성 "의 사용을 통해.Visible"에서 브라우저가 제 기능을 수행하는 것을 볼 것인지 여부를 결정합니다.코드를 구축하는 것이 좋을 때Visible = True하지만 코드가 데이터 스크랩을 위해 작동할 때는 매번 그것을 보지 않는 것이 좋습니다.Visible = False.

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

웹 페이지를 로드하는 데 약간의 시간이 필요합니다.그래서, 바쁜 동안 기다리겠습니다...

Do While appIE.Busy
    DoEvents
Loop

자, 이제 페이지가 로드되었습니다.제가 US30Y T-Bond의 잔돈을 긁어내고 싶다고 가정해 보겠습니다.Internet Explorer(인터넷 익스플로러)에서 F12를 클릭하면 웹 페이지의 코드가 표시되므로 포인터(빨간색 원)를 사용하여 원하는 요소를 클릭하여 목적에 도달하는 방법을 확인합니다.

enter image description here

제가 해야 할 일은 간단합니다. 저는 을 통해 선는, 나로 ID 을 얻을 입니다.tr값을 포함하는 요소:

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

서 저는 여서나수것입다니집할기는의 을 얻을 입니다.td 요특소히특,,tr이며, 는데터행며이이,td그것의 세포들입니다.우리는 8일을 찾고 있습니다. 그래서 저는 다음과 같이 쓸 것입니다.

Dim myValue As String: myValue = allRowOfData.Cells(7).innerHTML

왜 8개가 아니라 7개를 썼을까요?셀 집합이 0부터 시작하기 때문에 8번째 원소의 지수는 7(8-1)입니다.이 코드 라인을 분석하면 다음과 같습니다.

  • .Cells()▁the에 접속하게 .td요소;
  • innerHTML우리가 찾는 값을 포함하는 셀의 속성입니다.

가치를 , 일우리우가갖되게면치, 은이저다니됩에 됩니다.myValue변수, IE 브라우저를 닫고 없음으로 설정하여 메모리를 해제하면 됩니다.

appIE.Quit
Set appIE = Nothing

자, 이제 여러분은 여러분의 가치를 가지고 있고 여러분이 원하는 것을 무엇이든 할 수 있습니다: 그것을 세포에 넣습니다.Range("A1").Value = myValue()에 .Me.label1.Text = myValue).

StackOverflow는 이렇게 작동하지 않습니다. 여기서 특정 코딩 문제에 대한 질문을 올리지만 먼저 검색을 수행해야 합니다.제가 너무 많은 연구 노력을 보여주지 않는 질문에 대답하는 이유는 단지 여러 번 질문을 받은 것을 보고, 제가 이 방법을 배울 때, 저는 시작하기 위해 더 나은 지원을 받았으면 좋았을 것을 기억하기 때문입니다.따라서 "연구 입력"일 뿐 최상의/가장 완벽한 솔루션이 아닌 이 답변이 다음 사용자가 동일한 문제를 겪고 있을 때 도움이 될 수 있기를 바랍니다.왜냐하면 저는 이 커뮤니티 덕분에 프로그래밍하는 법을 배웠고, 여러분과 다른 초보자들이 제 의견을 사용하여 아름다운 프로그래밍 세계를 발견할 수 있다고 생각하기 때문입니다.

즐겁게 연습하세요 ;)

다른 방법들이 언급되었으니, 글을 쓰는 시점에서 우리는 21세기에 있다는 것을 인정해 주시기 바랍니다.로컬 버스 브라우저를 열고 XMLHTTP GET 요청(XHR GET)을 사용하여 이동합니다.

Wiki 모멘트:

XHR은 메서드가 웹 브라우저와 웹 서버 간에 데이터를 전송하는 객체 형태의 API입니다.오브젝트는 브라우저의 JavaScript 환경에서 제공됩니다.

브라우저를 열지 않아도 데이터를 빠르게 검색할 수 있는 방법입니다.서버 응답은 HTML 문서로 읽을 수 있으며 테이블을 잡는 과정은 여기서 계속되었습니다.

브라우저에 있는 Javascript 엔진이 실행되고 있지 않기 때문에 Javascript 렌더링/동적으로 추가된 콘텐츠는 검색되지 않습니다.

은 id id id로 잡힙니다.cr1.

table

Sub에서는 서서에브미도우,.WriteTable합니다.tdtags를 선택한 테이블행(으)로 합니다.tr태그), 마지막으로 각 테이블 행, 테이블 셀의 길이를 테이블 셀별로 이동합니다.우리는 1열과 8열의 데이터만 원하기 때문에,Select Case문을 사용하여 시트에 기록할 내용을 지정합니다.


샘플 웹 페이지 보기:

Sample page view


샘플 코드 출력:

Code output


VBA:

Option Explicit
Public Sub GetRates()
    Dim html As HTMLDocument, hTable As HTMLTable '<== Tools > References > Microsoft HTML Object Library
    
    Set html = New HTMLDocument
      
    With CreateObject("MSXML2.XMLHTTP")
        .Open "GET", "https://uk.investing.com/rates-bonds/financial-futures", False
        .setRequestHeader "If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT" 'to deal with potential caching
        .send
        html.body.innerHTML = .responseText
    End With
    
    Application.ScreenUpdating = False
    
    Set hTable = html.getElementById("cr1")
    WriteTable hTable, 1, ThisWorkbook.Worksheets("Sheet1")
    
    Application.ScreenUpdating = True
End Sub

Public Sub WriteTable(ByVal hTable As HTMLTable, Optional ByVal startRow As Long = 1, Optional ByVal ws As Worksheet)
    Dim tSection As Object, tRow As Object, tCell As Object, tr As Object, td As Object, r As Long, C As Long, tBody As Object
    r = startRow: If ws Is Nothing Then Set ws = ActiveSheet
    With ws
        Dim headers As Object, header As Object, columnCounter As Long
        Set headers = hTable.getElementsByTagName("th")
        For Each header In headers
            columnCounter = columnCounter + 1
            Select Case columnCounter
            Case 2
                .Cells(startRow, 1) = header.innerText
            Case 8
                .Cells(startRow, 2) = header.innerText
            End Select
        Next header
        startRow = startRow + 1
        Set tBody = hTable.getElementsByTagName("tbody")
        For Each tSection In tBody
            Set tRow = tSection.getElementsByTagName("tr")
            For Each tr In tRow
                r = r + 1
                Set tCell = tr.getElementsByTagName("td")
                C = 1
                For Each td In tCell
                    Select Case C
                    Case 2
                        .Cells(r, 1).Value = td.innerText
                    Case 8
                        .Cells(r, 2).Value = td.innerText
                    End Select
                    C = C + 1
                Next td
            Next tr
        Next tSection
    End With
End Sub

winhttpRequest 객체에 비해 인터넷 익스플로러 객체를 무겁게 만드는 광고 n개의 사진을 포함한 전체 웹페이지를 다운로드하는 대신에, 인터넷 익스플로러 대신 winhttprequest 객체를 사용할 수 있습니다.

이 질문은 오래 전에 물었습니다.하지만 저는 다음과 같은 정보가 신인들에게 유용할 것이라고 생각했습니다.실제로 이렇게 클래스 이름에서 값을 쉽게 얻을 수 있습니다.

Sub ExtractLastValue()

Set objIE = CreateObject("InternetExplorer.Application")

objIE.Top = 0
objIE.Left = 0
objIE.Width = 800
objIE.Height = 600

objIE.Visible = True

objIE.Navigate ("https://uk.investing.com/rates-bonds/financial-futures/")

Do
DoEvents
Loop Until objIE.readystate = 4

MsgBox objIE.document.getElementsByClassName("pid-8907-last")(0).innerText

End Sub

그리고 웹 스크래핑을 처음 하시는 분들은 이 블로그 게시물을 읽어보시기 바랍니다.

웹 스크래핑 - 기본사항

또한 웹 페이지에서 데이터를 추출하는 다양한 기술이 있습니다.이 기사는 그 중 몇 가지를 예로 들어 설명합니다.

웹 스크래핑 - 웹 페이지에서 데이터 수집

오류가 표시되는 부분을 수정하여 필요에 따라 데이터를 추출하는 데 큰 도움이 되었습니다.

Sub get_data_web()

Dim appIE As Object
Set appIE = CreateObject("internetexplorer.application")

With appIE
    .navigate "https://finance.yahoo.com/quote/NQ%3DF/futures?p=NQ%3DF"
    .Visible = True
End With

Do While appIE.Busy
    DoEvents
Loop

Set allRowofData = appIE.document.getElementsByClassName("Ta(end) BdT Bdc($c-fuji-grey-c) H(36px)")

Dim i As Long
Dim myValue As String

Count = 1

    For Each itm In allRowofData

        For i = 0 To 4

        myValue = itm.Cells(i).innerText
        ActiveSheet.Cells(Count, i + 1).Value = myValue

        Next

        Count = Count + 1

    Next

appIE.Quit
Set appIE = Nothing


End Sub

언급URL : https://stackoverflow.com/questions/27066963/scraping-data-from-website-using-vba

반응형