VBA에서 IE(InternetExplorer), WinHttp, XmlHttp(ServerXmlHttp) 등을 이용해서 웹사이트 정보를 가져올 수 있는데

특히 접속 후 웹페이지와 상호작용 즉, input상자에 텍스트를 넣거나 선택하거나 값을 보내려면 반응이 느리고 불안정한 IE를 이용하는 수밖에 없습니다.  샘플로 IE개체를 이용해서 Yahoo에 접속한 다음 Parasite라는 검색어로 접속해서 나온 페이지에서 IMDB점수를 가져오는 VBA예시입니다.

IERedirect1.xlsm
0.02MB

IE개체가 상대적으로 느린 편이고 변수가 많아 VBA로 IE개체를 제어하는 것이 녹록치 않습니다.

(WinHttp나 XmlHttp를 이용할 경우 계속 상호작용이 불가능해서 한번에 Form 내부의 값들을 Post로 웹서버에 전달해줘야 합니다. 이 방법이 가능한 경우 빠른 속도 때문에 추천할 만합니다.)

 

그런데 세상에는 브라우저가 IE만 있는 것이 아닙니다. 다른 브라우저를 제어할 수 있는 방법이 있습니다.

 

IE말고 다른 웹개체를 이용하는 방법이 바로 Selenium입니다.

Selenium은 IE뿐만아니라 chrome, firefox, Opera, PhontomJS 등 다양한 브라우저 개체를 지원합니다.

IE를 원격제어하는 것처럼  VBA/VB로 chrome이나 firefox 브라우져를 제어할 수 있는 것입니다.

여기서는 chrome에 집중하겠습니다.

- 또한 비슷한 개념의 SeleniumWrapper 도 있는데 이건 실행시에 검은 도스창 같은게 항상 떠서 보기 않좋음.

- 파이어폭스에서는 Selenium IDE로 웹사이트 접속을 매크로처럼 녹화하는 것도 가능함.

 

준비:

1. SeleniumBasic 다운로드 및 설치파일 실행:

https://github.com/florentbr/SeleniumBasic/releases

Selenium v2.0.9.0.exe 를 다운받아 실행.

(.NET 3.5 가 설치되어 있지 않다면 반드시 설치해야함)

 

2. 자신의 크롬 브라우저 버전에 맞는 chromedriver.exe 다운로드및 기존 파일과 교체:

https://chromedriver.chromium.org/downloads

다운 받아서 대개 C:\Users\사용자명\AppData\Local\SeleniumBasic 폴더(윈7에서는 C:\Program Files\SeleniumBasic 폴더)에 기존의 chromedriver.exe와 교체(덮어쓰기)

구 버전을 쓰면 오류가 발생하므로 자신의 크롬브라우저 버전과 맞는 chromedriver.exe 를 설치할 것!

 

 

엑셀이나 파워포인트 VBA에서 활용방법입니다.

 

먼저 Early Binding 일 경우,

Alt-F11 도구 - 참조에서 아래처럼 Selenium Type Library에 체크해줍니다.

1. 접속

Dim Sel As New Selenium.WebDriver

    Sel.Start "chrome", "http://www.yahoo.com"
    Sel.Get "/"
    Sel.Wait 1000

 

2. 텍스트 입력 및 폼값 전송( form submit )

Dim Sel As New Selenium.WebDriver

    Sel.Start "chrome", "http://www.yahoo.com"
    Sel.get "/"
    Sel.Wait 1000
    
    Sel.FindElementById("header-search-input").SendKeys "Parasite"
    Sel.FindElementById("header-desktop-search-button").Click
    Sel.Wait 1000

 

3. 접속 후 대기(생략)

    '안해줘도 되지만 참고로 남김
    'While Sel.executeScript("return document.readyState") <> "complete"
    '    Sel.Wait (1000)
    'Wend

3-1. 특정 클래스가 나타날 때까지 대기

        Sel.Get URL
        'Sel.Wait (2000)
        Do While Sel.FindElementsByClass("찾고자하는Class이름").Count = 0
            DoEvents
            Sel.Wait (1000)
            If k > 5 Then Exit Do '최대 5초 대기
            k = k + 1
        Loop

3-2. 여러가지 대기 방법들

'There are multiple ways  to set  a timeout:
Sel.Timeouts.ImplicitWait = 5000 ' 5 seconds

'As well as individually :
Sel.FindElementById("id", timeout:=10000).Click  ' implicitly wait of 10sec
Sel.FindElementById("id", timeout:=0).Click  ' no implicit waiting

'To set the timeout for the server that runs the browser:
Sel.Timeouts.Server = 120000 ' 2 mins

'source: https://stackoverflow.com/questions/32348486/how-to-make-selenium-wait-for-the-page-to-fully-load-in-selenium-wrapper-for-e

 

4. 연결된 사이트에서 특정 class의 값 추출

    'Xpath 를 이용하는 것이 제일 믿을 만 함.
    '크롬 개발자 도구에서 html개체를 우클릭하고 Copy-전체 XPath 하면 복사 가능
    Debug.Print Sel.findElementByXPath("/html/body/div[1]/div[3]/div/div/div[2]/ol/li/div/div[3]/ul/li[1]/span[2]").Text
    
    'PageSource는 document.body.innerHtml 과 같은  HTML소스 전체
    Debug.Print Mid(Sel.PageSource, InStr(Sel.PageSource, Chr(34) & " imdb") - 1000, 2000)
    
    'FindElementsByClass 는 모든 개체컬렉션, FindElementByClass는 개체 하나만
    Debug.Print Sel.FindElementByClass(" imdb", timeout:=10000).Text

 

5. 야후에 접속해서 parasite 로 검색후 IMDB 평점값을 추출하는 전체예제:

Sub TestSelenium()

    Dim Sel As New Selenium.WebDriver

    Sel.Timeouts.ImplicitWait = 5000
    Sel.Timeouts.Server = 60000
    Sel.Start "chrome", "http://www.yahoo.com"
    Sel.get "/"
    Sel.Wait 1000
    
    Debug.Print Sel.FindElementById("header-search-form").Text
    Sel.FindElementById("header-search-input").SendKeys "Parasite"
    Sel.FindElementById("header-desktop-search-button").Click
    'sel.Wait 1000
    
    'Debug.Print sel.PageSource
    'For Each ele In sel.FindElementsByClass(" imdb")
    '    Debug.Print ele.Text
    'Next ele
    'While Sel.executeScript("return document.readyState") <> "complete"
    '    Sel.Wait (1000)
    'Wend
    Debug.Print Sel.findElementByXPath("/html/body/div[1]/div[3]/div/div/div[2]/ol/li/div/div[3]/ul/li[1]/span[2]").Text
    Debug.Print Mid(Sel.PageSource, InStr(Sel.PageSource, Chr(34) & " imdb") - 1000, 2000)
    Debug.Print Sel.FindElementByClass(" imdb", timeout:=10000).Text
    
    Sel.Close
    Set Sel = Nothing
    
End Sub

 

실행화면 캡쳐영상입니다.

 

 


 

다른 여러가지 잔기술을 추가합니다.

 

6. 특정 요소(버튼) 클릭

'playbtn 버튼 포커스(클릭은 아님)
Sel.ExecuteScript ("javascript:document.getElementById('playbtn').focus();")

'playbtn 버튼 클릭
 Sel.ExecuteScript ("javascript:document.getElementById('playbtn').Click();")

 

7. 여러가지 키 전송

Dim keys As New Selenium.keys

Sel.SendKeys keys.Tab
Sel.SendKeys keys.Down
Sel.SendKeys keys.Enter

 

8. 특정 요소 감추기

'Hide Ads
Sel.ExecuteScript ("javascript:document.getElementById('Ads').style.display='none';")

Sel.ExecuteScript ("javascript:document.getElementsByClassName('Ads').item(0).style.display='none';")

Sel.ExecuteScript ("javascript:document.querySelector('Ads').style.display='none';")

 

9. 윈도우 스크롤

'Scroll down
Sel.ExecuteScript ("javascript:window.scrollTo( 0, 800 );")

 

10. Select Value 선택상자 값 선택

'Select value
Sel.FindElementById("languageselect").AsSelect.SelectByValue ("en-US")
Sel.FindElementById("speed").AsSelect.SelectByIndex (1) 
Sel.FindElementById("speed").AsSelect.SelectByLabel ("United States")

'Range type input
Sel.ExecuteScript ("javascript:document.getElementById('speed').value='99'")

 

11. 자바스크립트 들

Sel.ExecuteScript("return document.querySelector('downloads-percent').Text")

 

12. 기존에 열려져 있는 크롬 창에서 접속하기

'// 먼저 크롬창을 모두 닫고 시작 > 실행에서 아래를 실행
'// chrome.exe --remote-debugging-port=9222

Dim Sel As New Selenium.ChromeDriver
Dim keys As New Selenium.keys

'/// RUN chrome.exe --remote-debugging-port=9222
Private Sub existingChromeSession()

    Sel.SetCapability "debuggerAddress", "localhost:9222"
    Sel.Get ("https://www.google.com")
    
End Sub

 

13. 아이프레임 접근

Sel.Start "chrome"
Sel.Get "https://world.taobao.com/markets/all/login"
Sel.Wait 2000            
Sel.SwitchToFrame "login-iframe"
Sel.Wait 2000
Sel.FindElementById("fm-login-id").SendKeys "test my id"

 

 

Edge 브라우저를 이용하는 방법

 

1. Chrome과 마찬가지로 Edge Driver 설치(자신의 엣지브라우저 버전과 일치해야 함)

https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/

 

2. C:\Users\사용자명\AppData\Local\SeleniumBasic 폴더에 msedgedriver.exe압축을 풀고

msedgedriver.exe 를 edgedriver.exe 로 이름 변경 (기존 것과 교체)

 

Dim driver As New Selenium.WebDriver 'to keep the browser open

Sub TestSelenium()

    Dim keys As New Selenium.keys
     
    With driver
        .Start "edge"
        
        .Get "https://www.google.com"
        .Wait 1000

        .FindElementsByTag("input")(1).SendKeys "방탄"
        .Wait 1000
        
        .FindElementsByTag("input")(1).SendKeys keys.Enter
 
    End With
        
End Sub

 

실행 화면: