셀레니움으로 항공권을 조회하는 것을 해보려한다.
더 섬세하게 만들수도 있겠지만, 만들면서 생각해봐도 조회하는 정도 밖에는 쓸모가 없을 것 같아서 딱 그정도로 구현을 가능하게 하였다.
위와 같이 크롤링 되는 모습이 화면에 보이도록 창의 위치과 엑셀 창의 크기를 조절하는 코드이다.
Application.WindowState = xlNormal '= 창의 위치와 크기 조정
Application.Top = 0
Application.Left = 0
Application.Width = 730
Application.Height = 1080
strUrl = "https://flight.naver.com/" '= 항공권 예매
Sel.Start "chrome"
Sel.Window.SetPosition 960, 0
Sel.Get strUrl
출발지를 입력하게 되면 아래와 같이 연관된 공항들이 나오게 되는데 출발지가 입력된 첫 위치값을 클릭하는 코드는 다음과 같다.
Sel.FindElementsByCss(".select_code__d6PLz")(1).Click '= 출발지 선택
Sel.FindElementByCss(".autocomplete_input__1vVkF").SendKeys Fromstr '= 출발지 입력
If InStr(Sel.FindElementByCss(".autocomplete_search_item__2WRSw").Text, Fromstr) > 0 Then
Sel.FindElementByCss(".autocomplete_search_item__2WRSw").Click '= 항공사에 출발지가 포함되어 있으면 선택
End If
다음은 출발날짜를 선택하는 코드인데 이게 좀 난이도가 있었는데, CssSelector가 아닌 Xpath로 포함된 텍스트 값으로 해결하는 코드는 다음 번에 올려보도록 하겠다.
Sel.FindElementByCss(".tabContent_option__2y4c6").Click '= 출발날짜 클릭
Sel.Wait 500
Haja_go FromMonthstr, FromDaystr '= 출발 월 / 출발 일을 Haja_go 매개변수로 전달
----------------------------------------------------------------------------------------
Function Haja_go(Monthstr$, Daystr$)
Dim Cal As Object, Ca As Object, Tr As Object, Td As Object
Set Cal = Sel.FindElementsByCss(".awesome-calendar > div.month") '= 달력을 Cal변수에 담고
For Each Ca In Cal '= 각 월을 순환
If Ca.FindElementByCss(".dCaTmH").Text = Monthstr Then '= 출발월과 같으면
For Each Tr In Ca.FindElementsByCss("table > tbody > tr") '= 여행일자를 주 단위로 순환
For Each Td In Tr.FindElementsByCss("td.day") '= 여행의 주단위순환에서 일단위 순환
If Td.Text <> "" Then '= 달력에서 일자가 표현이 되었다면
If Td.FindElementByCss("button > b").Text = Daystr Then '= 해당일자와 출발일자가 같은지 판별
Td.FindElementByCss("button > b").Click '= 해당일자 클릭
Exit Function
End If
End If
Next Td
Next Tr
End If
Next Ca
End Function
이렇게 항공표를 검색하면 웹방식 특성상 끝까지가 아닌 중간에 끊겨서 데이터를 가져오게 되는데, 다음 코드로 해결이 가능하다. 현재 스크롤의 위치값을 prev_height에 담고, 스크롤을 화면 크기만큼 이동시켜서 [ 실행할 코드를 실행] 하고 이동한 스크롤의 위치를 current_height에 담는다..그리고 이전위치와 현재위치를 비교하여 다르면 Do문을 실행하고 같다면 더이상 이동할 스크롤값이 없으므로 Do문을 탈출하게 된다.
prev_height = Sel.ExecuteScript("return document. body.scrollHeight")
Do
Sel.ExecuteScript ("window.scrollTo(0, document.body.scrollHeight);")
* 실행할 코드
current_height = Sel.ExecuteScript("return document. body.scrollHeight")
If prev_height = current_height Then
Exit Do
Else
prev_height = current_height
End If
Loop
더보기
Sub Flight_naver()
Dim strUrl$
Dim Fromstr$: Fromstr = [b6] '= 출발
Dim Tostr$: Tostr = [b7] '= 도착
Dim FromMonthstr$: FromMonthstr = Format(Left([b5], 7), "yyyy.mm.") '= 출발년월(yyyy.mm.)
Dim FromDaystr$: FromDaystr = Format([b5], "d") '= 출발일
Dim node As Object
Dim prev_height&, current_height& '= 스크롤 위치
Dim rngX As Range: Set rngX = [d9] '= 출력위치
Columns("d:g").Clear '= 초기화
Application.Wait Now + TimeValue("0:00:02") '= 2초지연
Application.ScreenUpdating = False
Application.WindowState = xlNormal '= 창의 위치와 크기 조정
Application.Top = 0
Application.Left = 0
Application.Width = 730
Application.Height = 1080
strUrl = "https://flight.naver.com/" '= 항공권 예매
' Sel.AddArgument "--headless" '= 헤드리스모드
Sel.Start "chrome" '= 크롬으로 진행
Sel.Window.SetPosition 960, 0 '= 크롬창 이동
Sel.Get strUrl '= Url
Sel.FindElementByCss("button[title='닫기']").Click '= 팝업 닫기
Sel.FindElementsByCss("div.searchBox_tablist__1uWMk > button")(2).Click '= 편도 예약
Sel.FindElementsByCss(".select_code__d6PLz")(1).Click '= 출발지 선택
Sel.FindElementByCss(".autocomplete_input__1vVkF").SendKeys Fromstr '= 출발지 입력
If InStr(Sel.FindElementByCss(".autocomplete_search_item__2WRSw").Text, Fromstr) > 0 Then
Sel.FindElementByCss(".autocomplete_search_item__2WRSw").Click '= 항공사에 출발지가 포함되어 있으면 선택
End If
Sel.FindElementsByCss(".select_code__d6PLz")(2).Click '= 도착지 선택
Sel.FindElementByCss(".autocomplete_input__1vVkF").SendKeys Tostr '= 도착지 입력
If InStr(Sel.FindElementByCss(".autocomplete_search_item__2WRSw").Text, Tostr) > 0 Then
Sel.FindElementByCss(".autocomplete_search_item__2WRSw").Click '= 항공사에 도착지가 포함되어 있으면 선택
End If
Sel.FindElementByCss(".tabContent_option__2y4c6").Click '= 출발날짜 클릭
Sel.Wait 500
Haja_go FromMonthstr, FromDaystr '= 출발 월 / 출발 일을 Haja_go 매개변수로 전달
'Sel.Wait 500
' Haja_go ToMonthstr, ToDaystr
Sel.FindElementByCss(".searchBox_txt__3RoCw").Click '= 항공권 검색
Sel.Wait 5000 '= 5초 대기
prev_height = Sel.ExecuteScript("return document. body.scrollHeight") '= 현재 스크롤 위치
Do
Sel.ExecuteScript ("window.scrollTo(0, document.body.scrollHeight);") '= 현재 화면의 크기 만큼 스크롤 이동
For Each node In Sel.FindElementsByCss(".domestic_Flight__sK0eA")
rngX(1, 1) = node.FindElementByCss(".airline").Text '= 항공사
rngX(1, 2) = node.FindElementByCss(".info").Text '= 이벤트
rngX(1, 3) = Replace(node.FindElementByCss(".route_Route__2UInh").Text, Chr(10), " / ") '= 비행시간
rngX(1, 4) = node.FindElementByCss(".domestic_prices__3N88F").Text '= 항공권 가격
Set rngX = rngX.Offset(1)
Next node
current_height = Sel.ExecuteScript("return document. body.scrollHeight") '= 이동된 스크롤의 위치를 저장
If prev_height = current_height Then '= 처음 위치와 변동 위치가 같으면 / 변화가 없으면
Exit Do '= Do 탈출
Else
prev_height = current_height '= 현재위치를 prev_height 변수에 담아라
End If
Loop
Application.ScreenUpdating = False
Haja_Format
Sel.FindElementByCss(".jsx-1527821584.as_top").Click '= 맨위로 버튼 클릭
End Sub
Function Haja_go(Monthstr$, Daystr$)
Dim Cal As Object, Ca As Object, Tr As Object, Td As Object
Set Cal = Sel.FindElementsByCss(".awesome-calendar > div.month") '= 달력을 Cal변수에 담고
For Each Ca In Cal '= 각 월을 순환
If Ca.FindElementByCss(".dCaTmH").Text = Monthstr Then '= 출발월과 같으면
For Each Tr In Ca.FindElementsByCss("table > tbody > tr") '= 여행일자를 주 단위로 순환
For Each Td In Tr.FindElementsByCss("td.day") '= 여행의 주단위순환에서 일단위 순환
If Td.Text <> "" Then '= 달력에서 일자가 표현이 되었다면
If Td.FindElementByCss("button > b").Text = Daystr Then '= 해당일자와 출발일자가 같은지 판별
Td.FindElementByCss("button > b").Click '= 해당일자 클릭
Exit Function
End If
End If
Next Td
Next Tr
End If
Next Ca
End Function
Function Haja_Format()
With [d9].CurrentRegion
.HorizontalAlignment = xlLeft
.IndentLevel = 1
.Borders.LineStyle = 1
End With
End Function
'VBA > 엑사남_심화방' 카테고리의 다른 글
[심화방] VBA_심화_100제 #14-1 [ 셀레니움 네이버항공 조회] (0) | 2023.04.02 |
---|---|
[심화방] VBA_심화_100제 #15 [ 4대보험계산기] (0) | 2023.04.01 |
[심화방] VBA_심화_100제 #13 [ 셀레니움 네이버 로그인] (0) | 2023.03.20 |
[심화방] VBA_심화_100제 #12 [ 셀레니움 자동화테스트] (0) | 2023.03.16 |
[심화방] VBA_심화_100제 #11 [ 셀레니움 Astable] (0) | 2023.03.13 |
댓글