/ R

R 기초강의(13) - R Crawling

R 강좌는 여러 절로 구성되어 있습니다.


R Crawling

Web Crawling의 일반적인 개념은 인터넷 상에서 필요한 정보를 읽어와서 수집하는 작업이라고 할 수 있습니다.

하지만 좀 더 구체적으로 다음과 같은 두 가지 작업으로 정의할 수 있습니다.

Web Scraping (웹 스크래핑)

  • 웹 스크래핑은 웹사이트상에서 원하는 부분에 위치한 정보를 컴퓨터로 하여금 자동으로 추출하여 수집하도록 하는 기술을 의미합니다.

Web Crawling (웹 크롤링)

  • 자동화 봇인 웹 크롤러가 정해진 규칙에 따라 복수개의 웹페이지를 browsing하는 행위를 의미하며 다른 말로 Web spidering 이라고도 합니다.

여기서는 Web Scraping을 위해 CSS(혹은 jQuery)의 selector와 XPATH를 이용하는 방법을 알아보겠습니다.

아래는 많이 사용되는 Selector에 대한 예시 입니다.

Selectors

실습

  • 네이버 영화 사이트 댓글 정보를 Scraping 및 Crawling 처리를 해 보겠습니다.
# 네이버 영화 사이트 댓글정보 스크래핑

# 필요한 package 설치 및 loading
install.packages("rvest"); 
library(rvest)

# 네이버 영화 검색 후 평점,리뷰 부분

url <- "http://movie.naver.com/movie/point/af/list.nhn"
page <- "page="

request_url <- str_c(url,"?",page,"1")

page_html <- read_html(request_url,  encoding="CP949")
page_html;

# 영화제목 추출
nodes <- html_nodes(page_html, "td.title > a.movie")
nodes

movie_title <- html_text(nodes)
movie_title

# 기존에는 영화 평점도 있었지만 지금은 공개하지 않음.

# 영화리뷰 추출
# CSS를 이용(완전하지 않음-영화제목이 포함됨)
# nodes <- html_nodes(page_html, "td.title")
# movie_review <- html_text(nodes, trim=TRUE);
# movie_review
# 문자열 처리필요(데이터 정제)
# movie_review <- str_remove_all(movie_review,"\t")
# movie_review <- str_remove_all(movie_review,"\n")
# movie_review <- str_remove_all(movie_review,"신고")
# movie_review


# XPATH를 이용
movie_review = vector(mode="character", length=10)
for(i in 1:10) {
  myPath = str_c('//*[@id="old_content"]/table/tbody/tr[',
                 i,
                 ']/td[2]/text()')
  nodes <- html_nodes(page_html, xpath=myPath)
  comment <- html_text(nodes, trim=TRUE);
  movie_review[i] = comment[3]
}
movie_review

result_page <- cbind(movie_title, movie_review)

write.csv(result_page, 
          file="C:/R_workspace/R_Lecture/data/movie_reviews.csv",
          row.names = FALSE,
          quote = FALSE,
          fileEncoding = "CP949")

실습

  • 위의 코드를 이용해서 Crawling 처리까지 진행해 보겠습니다.
extract_comment <- function(idx) {
  url <- "http://movie.naver.com/movie/point/af/list.nhn"
  page <- "page="
  
  request_url <- str_c(url,"?",page,idx)
  
  page_html <- read_html(request_url,  encoding="CP949")
  
  # 영화제목 추출
  nodes <- html_nodes(page_html, "td.title > a.movie")
  movie_title <- html_text(nodes)
  
  # 영화리뷰 추출
  movie_review = vector(mode="character", length=10)
  for(i in 1:10) {
    myPath = str_c('//*[@id="old_content"]/table/tbody/tr[',
                   i,
                   ']/td[2]/text()')
    nodes <- html_nodes(page_html, xpath=myPath)
    comment <- html_text(nodes, trim=TRUE);
    movie_review[i] = comment[3]
  }
  
  result_page <- cbind(movie_title, movie_review)
  return(result_page)
}

result_df = data.frame();

for(i in 1:10) {
  result_df = rbind(result_df,extract_comment(i))
}

View(result_df)

실습

  • 로튼토마토 사이트에서 2019년 가장 인기있는 영화 100개의 영화제목, User Rating, Genre를 추출해서 data frame으로 구축해보자
# 개인별 수행

R에서 Kakao Open API 활용

이번에는 Kakao 검색 API를 이용하여 이미지 검색을 하고 검색된 이미지를 파일로 저장하는 R 코드를 작성해 보도록 하겠습니다.

install.packages("httr")
library(httr)

url <- "https://dapi.kakao.com/v2/search/image"

keyword <- "query="

#request_url = str_c(url,"?",keyword,scan(what=character()))
request_url = str_c(url,"?",keyword,"아이유")
request_url = URLencode(request_url)   # 한글처리
request_url

apiKey <- "1bf8c91dbc8dd1814aa97f2614a1d730"
result <- GET(request_url,
              add_headers(Authorization = paste("KakaoAK", apiKey)))
http_status(result)   # 접속 상태
result_data <- content(result)  # 결과데이터
View(result_data)

for(i in 1:length(result_data$documents)) {
  res = GET(result_data$documents[[i]][["thumbnail_url"]])
  writeBin(content(res, 'raw'), 
           paste('C:/R_workspace/R_Lecture/img/image',
                 i,
                 ".png",
                 sep=""))
}

RSelenium을 이용한 동적 데이터 Crawling

AJAX를 이용해 화면을 Rendering하는 Front-End Web Application은 위의 방법으로는 Crawling이 불가능합니다.

이런 경우 RSelenium을 이용해 Crawling을 수행할 수 있습니다.

Selenium Standalone Server

Chrome Driver

R 코드를 실행하기 전에 다음의 코드를 실행 해 Selenium Server를 실행해야 합니다. (Java가 설치되어 있어야 합니다.)

java -jar selenium-server-standalone.jar -port 4445
# Selenium

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

# Selenium 서버에 접속하고 remoteDriver 객체 리턴
remDr <- remoteDriver(remoteServerAddr="localhost", 
                      port = 4445, 
                      browserName = "chrome")

# Chrome browser Open
remDr$open()

# 특정 page 랜더링
remDr$navigate("http://localhost:8080/bookSearch/index.html")

# 입력 상자를 CSS를 이용해서 찾기
webElem <- remDr$findElement(using="css", "[type=text]")

# 검색어를 입력하고 enter key 입력
#webElem$sendKeysToElement(list("여행", key="enter"))
webElem$sendKeysToElement(list("여행"))

# click을 할element를 xpath를 이용해서 찾기
# CSS로 찾으면 잘 수행되지 않음.
btn <- remDr$findElement(using="xpath", 
                         value='//*[@id="inputText"]')

# 찾은 element click event 처리
btn$clickElement()

# AJAX 호출로 나온 결과 데이터 추출
liElem <- remDr$findElements(using="xpath", 
                             value='//*[@id="myList"]/li')

myList = sapply(liElem,function(x){x$getElementText()})

class(myList)

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

공공데이터 포탈의 Open API를 활용한 데이터 구축

공공데이터 포털의 데이터를 이용하여 데이터를 구축할 수 있다. 서울특별시 버스노선경로 목록정보를 제공하는 Open API를 이용하여 데이터를 구축해보자.

REST API를 이용해야 하며 결과가 XML로 리턴된다.

# 개인별 수행

End.


이 포스트의 내용은 아래의 책과 사이트를 참조했습니다. 조금 더 자세한 사항을 알고 싶으시면 책을 참조하거나 해당 사이트를 방문하세요!!