안녕하세요 교수님
교수님께서 올려주신 코드로 열심히 공부해보려고하는 학생입니다.
네이버 뉴스 기사 크롤링을 하려고 교수님의 패키지로 구동해보았는데 잘 안돼서 질문을 남겨봅니다.
뉴스 리스트 페이지 내의 개별 네이버 뉴스 url들을 가져오는데까지는 되는데
가져온 url들의 정보를 가져오는데에서 newsData가 빈 리스트들로만 이루어집니다.
교수님께서 올리신 함수들은 고치지 않았는데 무엇이 문제일까요??
제가 보고 있는 코드는 다음과 같습니다.
`library(N2H4)
library(httr)
메인 카테고리 id 가져옵니다.
cate<-getMainCategory()
예시를 위해 하나만 선택합니다.
여기는 101(경제)를 선택했습니다.
tcate<-cate$sid1[2]
경제의 세부 카테고리를 가져옵니다.
subCate<-cbind(sid1=tcate,getSubCategory(sid1=tcate))
그중에 1번째, 2번째 세부 카테고리를 정했습니다.
tscate<-subCate$sid2[1:2]
목표 날짜를 지정합니다.
strDate<-"20180705"
endDate<-"20180705"
strTime<-Sys.time()
midTime<-Sys.time()
##파일 이름을 지정하면 한 파일에 이어 붙이고 ""로 놔두면 각 뉴스마다 파일을 따로 저장ㅎ
save_path <- ""
Main카테고리벡터, 세부카테고리벡터, 시작날짜, 종료날짜, 페이지벡터로 URL 생성하는 함수입니다.
setUrls <- function(sid1_vec, sid2_vec, strDate, endDate, page_vec=NA){
url_list <- expand.grid(sid1_vec, sid2_vec, strDate:endDate, page_vec, stringsAsFactors=FALSE)
colnames(url_list) <- c("sid1", "sid2", "date", "pageNum")
url_list <- apply(url_list, 1, as.list)
url_list <- lapply(url_list, function(x){
pageUrl <- parse_url("http://news.naver.com/main/list.nhn")
if(is.na(x$page)){
pageUrl$query <- list(sid1=x$sid1, sid2=x$sid2, mid="shm", mode="LS2D", date=x$date)
} else {
pageUrl$query <- list(sid1=x$sid1, sid2=x$sid2, mid="shm", mode="LS2D", date=x$date, page=x$pageNum)
}
x$pageUrl <- build_url(pageUrl)
return(x)
})
return(url_list)
}
주어진 조건 값들의 모든 조합을 고려한 pageUrl을 생성합니다. (sid1 x sid2 x date)
urls <- setUrls(tcate, tscate, strDate, endDate)
라스트 페이지 탐색 및 페이지 수에 맞춰 pageUrl을 재생성하는 코드입니다.
sub_urls <- list()
for (url in urls){
print(paste0(url$date," / ", url$sid1," / ", url$sid2 ," / start Time: ", strTime," / spent Time: ", Sys.time()-midTime," / spent Time at first: ", Sys.time()-strTime))
midTime<-Sys.time()
리스트 페이지의 마지막 페이지수를 가져옵니다.
max<-getMaxPageNum(url$pageUrl)
기존에 주어진 조건 값 + page번호의 모든 조합을 고려한 pageUrl을 생성합니다. (sid1 x sid2 x date x page)
sub_urls <- c(sub_urls, setUrls(url$sid1, url$sid2, url$date, url$date, 1:max))
}
페이지 번호가 포함된 Url List에서 news data를 가져옵니다.
for (url in sub_urls){
print(paste0(url$date," / ",url$sid1," / ",url$sid2," / ",url$pageNum, " / start Time: ", strTime," / spent Time: ", Sys.time()-midTime," / spent Time at first: ", Sys.time()-strTime))
midTime<-Sys.time()
뉴스 리스트 페이지 내의 개별 네이버 뉴스 url들을 가져옵니다.
newsList<-getUrlListByCategory(url$pageUrl)
newsData<-c()
///////////////////////////////////////문제라고 생각되는 부분입니다.///////////////////////////////////////
가져온 url들의 정보를 가져옵니다.
newsData <- lapply(newsList$links, function(x){
# 불러오기에 성공할 때 까지 반복합니다.
tem<-try(getContent(x), silent = TRUE)
while(class(tem)=="try-error"){
tem<-try(getContent(x), silent = TRUE)
print(paste0("try again: ",x))
}
if(class(tem$datetime)[1]=="POSIXct"){
# newsData<-rbind(newsData,tem)
return(tem)
}
})
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
dplyr 패키지의 bind_rows 함수로 리스트로 저장된 데이터 프레임을 rbind 합니다.
newsData <- dplyr::bind_rows(newsData)
dir.create("./data",showWarnings=F)
가져온 뉴스들(보통 한 페이지에 20개의 뉴스가 있습니다.)을 csv 형태로 저장합니다.
#write.csv(newsData, file=paste0("./data/news",url$sid1,"",url$sid2,"",url$date,"_",url$pageNum,".csv"),row.names = F)
##파일 이름을 지정하면 한 파일에 이어 붙이고 ""로 놔두면 각 뉴스마다 파일을 따로 저장
if(save_path==""){
# 가져온 뉴스들(보통 한 페이지에 20개의 뉴스가 있습니다.)을 csv 형태로 저장합니다.
write.csv(newsData, file=paste0("./data/news",url$sid1,"",url$sid2,"",url$date,"_",url$pageNum,".csv"),row.names = F)
} else {
if (!file.exists(save_path)){
write.csv(newsData, file=save_path, row.names = F)
}
write.table(newsData, file=save_path, append=T, row.names = F, col.names = F, sep=",")
}
}`