12-22 18:59
Notice
Recent Posts
Recent Comments
관리 메뉴

Scientific Computing & Data Science

[Data Science / Baseball] rvest 패키지를 이용하여 KBO 야구 데이터 가져오기 본문

Data Science/ Baseball Data Analysis

[Data Science / Baseball] rvest 패키지를 이용하여 KBO 야구 데이터 가져오기

cinema4dr12 2017. 5. 14. 21:10

by Geol Choi | 


지난 번 포스팅에서 유명 야구 데이터 사이트인 baseball-reference.com으로부터 데이터를 가져오는 방법에 대해 알아보았다. 해당 포스팅을 보시고, 동일한 방법으로 KBO 리그 데이터에 대한 웹스크랩핑을 시도해 보았는데 실패했다는 문의를 이메일을 통해 전달받았다. 그래서 직접 시도해 보기로 했다.


대상 웹페이지는 네이버 야구 기록실 페이지이며, 이 중 팀순위 기록 가져오기를 시도해 보았다.




지난 포스팅과 동일한 코드로 시도를 해 보았다 (단, 지난 포스팅의 코드와는 달리 네이버 야구기록 페이지에서는 HTML 주석문 처리를 할 필요가 없어서 주석문 제거를 위한 코드는 생략하였다):


R CODE:

############################################################################################## ## load libraries & source if (! ("rvest" %in% rownames(installed.packages()))) { install.packages("rvest") } if (! ("stringr" %in% rownames(installed.packages()))) { install.packages("stringr") } if (! ("tidyr" %in% rownames(installed.packages()))) { install.packages("tidyr") } base::require("rvest") base::require("stringr") base::require("tidyr") ############################################################################################## url <- "http://sports.news.naver.com/kbaseball/record/index.nhn?category=kbo&year=2017&type=batter&playerOrder=hra" webpage <- xml2::read_html(url) ## import KBO League Team Ranking ranking_table <- rvest::html_nodes(x=webpage, xpath='//*[@id="content"]/div/div/div[2]/table') ranking <- rvest::html_table(ranking_table)[[1]]


그리고 결과를 확인했더니 다음과 같이 에러 메시지를 내뱉었다:


> ranking <- rvest::html_table(ranking_table)[[1]]
Error in utils::type.convert(out[, i], as.is = TRUE, dec = dec) : 
  invalid multibyte string at '<ed><8c><a8>'


"invalid multibyte string"은 UTF-8에서 인코딩된 것이 문제였다. Sys.getlocale() 함수를 입력하여 Locale 정보를 확인해 보자:


> Sys.getlocale()
[1] "LC_COLLATE=Korean_Korea.949;LC_CTYPE=Korean_Korea.949;LC_MONETARY=Korean_Korea.949;LC_NUMERIC=C;LC_TIME=Korean_Korea.949"


한국어 OS를 사용하는 경우 대부분이 위와 같은 결과가 출력될 것이다. 이를 해결하는 방법은 Locale을 다음과 같이 설정하는 것이다:


> Sys.setlocale("LC_ALL", "English")
[1] "LC_COLLATE=English_United States.1252;LC_CTYPE=English_United States.1252;LC_MONETARY=English_United States.1252;LC_NUMERIC=C;LC_TIME=English_United States.1252"


위와 같이 Locale을 설정하고, 다시 네이버 KBO 리그 기록 페이지로부터 팀 순위 데이터를 가져오기 위해 맨 위의 R Code를 실행하였더니, 다음과 같은 결과를 얻었다:


> head(ranking)
  <U+C21C><U+C704>         <U+D300> <U+ACBD><U+AE30><U+C218> <U+C2B9> <U+D328> <U+BB34> <U+C2B9><U+B960> <U+AC8C><U+C784><U+CC28> <U+C5F0><U+C18D> <U+CD9C><U+B8E8><U+C728> <U+C7A5><U+D0C0><U+C728> <U+CD5C><U+ADFC> 10<U+ACBD><U+AE30>
1                1              KIA                       38       25       13        0            0.658                      0.0        1<U+D328>                    0.334                    0.395       5<U+C2B9>-5<U+D328>-0<U+BB34>
2                2               LG                       37       23       14        0            0.622                      1.5        1<U+C2B9>                    0.348                    0.389       8<U+C2B9>-2<U+D328>-0<U+BB34>
3                3               NC                       37       22       14        1            0.611                      2.0        2<U+D328>                    0.331                    0.413       4<U+C2B9>-6<U+D328>-0<U+BB34>
4                4 <U+B450><U+C0B0>                       36       18       17        1            0.514                      5.5        4<U+C2B9>                    0.369                    0.416       6<U+C2B9>-4<U+D328>-0<U+BB34>
5                5 <U+B125><U+C13C>                       37       18       18        1            0.500                      6.0        2<U+C2B9>                    0.352                    0.411       5<U+C2B9>-4<U+D328>-1<U+BB34>
6                5               SK                       37       18       18        1            0.500                      6.0        1<U+C2B9>                    0.333                    0.451       4<U+C2B9>-5<U+D328>-1<U+BB34>

값이 나오기는 나오기는 하는데 뭔가 이상한 코드가 섞여있다. 예를 들어, <U+C21C><U+C704>는 UTF-16 Unicode로서, <U+C21C>는 "순", <U+C704> "위"를 의미하여 합치면 "순위"가 된다.


한편 names() 함수를 이용하여 ranking 변수(Data Frame)의 Column 이름을 출력하면,


> names(ranking)
 [1] "순위"        "팀"          "경기수"      "승"          "패"          "무"          "승률"        "게임차"     
 [9] "연속"        "출루율"      "장타율"      "최근 10경기"


위와 같이 제대로 한글로 잘 나오는 것을 확인할 수 있었으며, 이 중 "팀" 데이터를 출력해 보았더니,


> ranking$"팀"
 [1] "KIA"  "LG"   "NC"   "두산" "넥센" "SK"   "kt"   "한화" "롯데" "삼성"


역시 한글로 잘 나옴을 확인할 수 있었다. 그래서 이 결과를 MongoDB에 넣어 보았다:


R CODE:

############################################################################################## ## load library & source for connecting mongodb if (! ("mongolite" %in% rownames(installed.packages()))) { install.packages("mongolite") } base::require("mongolite") source('./Connect.R') ## insert data into mongodb InsertDataFrameToDB(colName="kbo_ranking", df=ranking)


그리고, 위의 코드를 실행하고 Robomongo로부터 데이터를 확인해 보았더니,





한글이 깨지지않고 잘 출력됨을 확인할 수 있었다.


그러나, 아직까지 한글 출력이 완벽하지 않아 뭔가 꺼림직한데 이를 해결할 수 있는 방법을 찾아 다음 포스팅에 게재하도록 하겠다.

Comments