study blog

selenium을 이용한 동적 page 데이터 추출 본문

R/2. 데이터 구축

selenium을 이용한 동적 page 데이터 추출

ivo_lee 2020. 1. 14. 00:54

1. KAKAO-API (이미지검색) 

- KAKAO API (이미지검색)을 이용해서 이미지를 찾고 파일로 저장

- 사용하는 package network 연결을 통해서 서버에 접속해서 결과를 받아올 때 일반적으로 많이 사용하는 package를 이용

- jsonlite(), httr() 패키지

# .libPaths()        # .libPaths("C:/R_lecture/lib")
install.packages("jsonlite");   library(jsonlite)
install.packages("httr");     library(httr)
library(stringr)

 

1) 카카오 사이트에 접속 - Open API의 주소 복사해오기

url <- "https://dapi.kakao.com/v2/search/image"
keyword <- "query=아이유"

 

2) API호출 주소 만들기

request_url <- str_c(url, "?", keyword)
request_url <- URLencode(request_url) #한글 처리
request_url      #API호출 주소

 

3) open API 키 발급 -  Open API를 사용할 때 거의 대부분 인증절차를 거쳐야 사용 가능

apikey <- "로그인해서 발급받은 키"

 

4) 호출하기 GET 함수 이용 (httr 패키지의)

- web에서 클라이언트가 서버쪽 프로그램을 호출할 때 호출방식이라는 것이 있음

- 호출방식 4가지 : GET, POST, PUT, DELETE (기본적으로 4가지 방식)

  - 일반적으로 GET, POST를 이용

  - GET 방식: 서버프로그램을 호출할 때 전달하는 데이터를 URL 뒤에 붙여서 전달하는 방식 (문자열형식

                  -> 이 방식을 사용할 것 !

  - POST 방식: 서버프로그램을 호출할 때 전달 데이터가 request header에 붙어서 전달됨

 

result <- GET(request_url,
              add_headers(Authorization=paste("KakaoAK", apikey)))

 


(+) fromJSON 대신 GET 사용해서 서버 접속해서 json데이터 가져온 이유?

- 인증코드나 특별한 내용 있으면 GET이나 POST 이용하는 것이 좋다. fromJSON은 가져오면 바로 json 형태로 가져오지만, GET은 절차가 좀 있기 때문이다.

- 호출해서 가져오면 data frame으로 오는게 아니라 응답 객체로 있어서 content() 해줘야 실제 내가 서버로부터 받은 json 데이터를 데이터프레임형태로 가져올 수 있다. 

- 편한 것은 jsonlite fromJSON이 편하다. httr 패키지의 이거 이용해서 fromJSON을 만든 것이라서.

- fromJSON 으로도 사실 가능하기는 하나 전형적인 형태의 패키지와 전형적인 함수 사용법을 알아본 것

- json만 가져온 것 뿐 아니라 이미지 경롤 다시 뽑아서 밑에서 다시 반복적으로 호출. 그러나 json이 아니라 raw data 가져온다.

- binary하려면 raw 붙이면 raw 데이터 가져올 수 있음


 

5) 결과 확인하기

http_status(result)   #접속 상태 결과

result_data <- content(result)    #content: httr안의 함수. 결과 내용을 가져오는 함수

myL = length(result_data$documents); #myResult=c();

for(i in 1:myL){
  req <- result_data$documents[[i]]$thumbnail_url
  res <- GET(req)         #이미지에 대한 응답
  
  # 결과로 받은 이미지를 raw 형태로 추출 (binary 파일이므로 문자열과 다르게 처리)
  imgData = content(res,"raw") 
  writeBin(imgData,
           paste("C:/R_lecture/image/img", i, “.png”)
  )  
}

2. selenium 설치하기

크롬 -> 설정 -> 크롬정보 -> 버전 78.0.3904.70(공식 빌드) (64비트)

크롬 업데이트 -> 버전에 맞는 드라이버 다운 -> chrome driver wih32.zip 받기-> 환경변수 추가하기

- selenium server program 다운로드

- selenium chrome browser를 자동으로 제어하게 됨!

- chrome을 자동으로 제어하려면 chrome driver 필요

- chrome driver 프로그램을 selenium이 사용할 수 있도록 path환경변수에 경로를 설정

 

- selenium server 기동

cmd에서 확인

cd C:\Users\student\Desktop\selenium                           # cd: change directory
dir
java -jar파일명 -port 4445
java -jar selenium-server-standalone-3.141.59.jar -port 4445

 

- mysql 기동

cd C:\Users\student\Desktop\mysql-5.6.46-winx64\bin
mysqld

 

-이클립스 기동되는지 확인 booksearch프로그램

http://localhost:8080/bookSearch/index.html

 


3. selenium(자동화 도구)을 이용한 동적 page scraping

 

1) selenium 패키지 설치

install.packages("RSelenium")
library(RSelenium)

 

2) R 프로그램에서 selenium 서버에 접속한 후, remote driver객체 return 받기

- remoteDriver() : Rselenium이 가지고 있는 함수.  서버에 접속하게 해주는 함수

remDr <- remoteDriver(remoteServerAddr="localhost",
                      port=4445,                    #cmd에서 selenium서버 켜놓은거에 접속
                      browserName="chrome")

 

3) 접속이 성공하면 remote driver를 이용해서 chrome browser R code로 제어할 수 있음

remDr$open()      # open: 브라우저 열어라 (크롬브라우저 열릴 것)

 

4) open된 브라우저의 주소를 변경하자

remDr$navigate("http://localhost:8080/bookSearch/index.html")

 

5) 입력상자에 글 입력해서 검색하기

 

(1) 입력상자 찾기

- using: css(selector)로 찾을건지 xpath로 찾을건지 명시해줌 -> css로 먼저 하고 안되면 xpath로 해보기

inputBox <- remDr$findElement(using="css",
                              "[type=text]")

 

(2) 찾은 입력상자에 검색어 넣기

inputBox$sendKeysToElement(list("여행"))

 

(3) AJAX호출을 하기 위해 버튼을 먼저 찾아야 함

btn <- remDr$findElement(using="css",
                         "[type=button]")

 

(4) 찾은 버튼에 click event를 발생

btn$clickElement()                       #clickElement: element를 클릭해라

 

(5) AJAX 호출이 발생해서 출력된 화면에서 필요한 내용을 추출

- findElements: 여러개 찾을 것. s없으면 맨위값 하나만 출력됨

li_element <- remDr$findElements(using="css", "li")

 

(6) 이렇게 얻어온 element 각각에 대해서 함수를 호출

- sapply: element 각각에 대해 함수 적용

myList <- sapply(li_element, function(x){   #여기서 x는 li들
  x$getElementText()
}) 

class(myList)  #list형태로 데이터들을 추출해 가져옴

for(i in 1:length(myList)){
  print(myList[[i]])
}

 

Comments