카테고리 없음

22-08-12 chap07_3_news_crawling

서부남93 2022. 8. 12. 16:37

# chap07_3_news_crawling

# chap07_3_news_crawling

# - 네이버 뉴스 기사 수집 


# 1. 패키지 설치 
install.packages('rvest') # 웹문서 수집에 필요한 함수 제공 
library(rvest)  

#read_html(url) : html문서를 읽는 함수
#html_nodes() : 태그(tag)정보 수집
#html_attr(tag,속성) : 태그 속성 수집 
#html_text(tag): 태그 내용 수집

#<a href='http://www.naver.com' 시작태그> 네이버 </  종료태그>





# 2. url 만들기
# naver 뉴스 검색(검색어 : 코로나, 기간 :  2020.08.01 ~2022.08.01)
#https://search.naver.com/search.naver?where=news&sm=tab_pge&query=%EC%BD%94%EB%A1%9C%EB%82%98&sort=0&photo=0&field=0&pd=3&ds=2020.08.12&de=2022.08.12&cluster_rank=73&mynews=0&office_type=0&office_section_code=0&news_office_checked=&nso=so:r,p:from20200812to20220812,a:all&start=1 ->1page
#https://search.naver.com/search.naver?where=news&sm=tab_pge&query=%EC%BD%94%EB%A1%9C%EB%82%98&sort=0&photo=0&field=0&pd=3&ds=2020.08.12&de=2022.08.12&cluster_rank=30&mynews=0&office_type=0&office_section_code=0&news_office_checked=&nso=so:r,p:from20200812to20220812,a:all&start=11 ->2page
#https://search.naver.com/search.naver?where=news&sm=tab_pge&query=%EC%BD%94%EB%A1%9C%EB%82%98&sort=0&photo=0&field=0&pd=3&ds=2020.08.12&de=2022.08.12&cluster_rank=58&mynews=0&office_type=0&office_section_code=0&news_office_checked=&nso=so:r,p:from20200812to20220812,a:all&start=21 -> 3page
# 기본 url 만들기 : 네이버 뉴스 -> 뉴스 검색 : 키워드 입력(코로나) > 옵션 > 기간 : 직접입력 > 적용 > 1페이지 클릭 
base_url <- 'https://search.naver.com/search.naver?where=news&sm=tab_pge&query=%EC%BD%94%EB%A1%9C%EB%82%98&sort=0&photo=0&field=0&pd=3&ds=2020.08.01&de=2022.08.01&cluster_rank=33&mynews=0&office_type=0&office_section_code=0&news_office_checked=&nso=so:r,p:from20200801to20220801,a:all&start=' 

# url 만들기 
urls <- c() # url 저장 
urls

for (x in 0:10) {
urls <- c(urls, paste(base_url,x*10+1,sep='')) }

urls # base_url=1 ~ base_url=101

length(urls)

# 3. html 문서 & 태그 정보 수집

# 3-1. url에서 htrml 문서 읽기
html <- read_html(urls[1]) 
html
# 3-2. html 문서에서 태그 수집 
html_a <- html_nodes(html, 'ul.list_news > li > div > div > a') 
length(html_a)

links <- html_attr(html_a,'href') 
links # 1page에서 10개 url 추출 


# 4-1. a태그 href 속성 수집 
news_urls <- c()
for (url in urls){  # 코드 수정
  html <- read_html(url)
  html_a <- html_nodes(html,'ul.list_news > li > div > div > a')
  news_urls <- c(news_urls, html_attr(html_a, 'href'))
}  

length(news_urls)   # 110 = 11page *10 
news_urls <- unique(news_urls) # 중복제거 
length(news_urls)  # 103  
news_urls

# 4-2. a태그 내용 추출
news_texts <- c()
for (url in urls){  # 코드 수정
  html <- read_html(url)
  html_a <- html_nodes(html,'ul.list_news > li > div > div > a')
  news_texts <- c(news_texts, html_a %>% html_text())  
}


# 중복 news 제거 
news_texts <- unique(news_texts) 
length(news_texts)  #  103

news_texts

# 5. 불용어 전처리 
news_texts_pre <- gsub("[\r\n\t]", ' ', news_texts) # 이스케이프 제거
news_texts_pre <- gsub('[[:punct:]]',' ',news_texts_pre) # 문장부호 제거
news_texts_pre <- gsub('[[:cntrl:]]',' ',news_texts_pre) # 특수문자 제거
news_texts_pre <- gsub('\\s+',' ',news_texts_pre) # 공백 제거 
news_texts_pre
  
#6. 데이터 프레임 만들기

new_df <- data.frame(news= news_texts_pre)

str(new_df)

# 7. csv 파일로 저장하기
getwd()
setwd("C:/ITWILL/3_Rwork/output")
write.csv(new_df,'naver_news.csv',quote = F , row.names = T)

# csv.file 읽기

news_data<-read.csv('naver_news.csv',stringsAsFactors = F)

str(news_data)
news_data
names(news_data)<- c('no','news')
news_data

head(news_data)

news <- news_data$news
news
str(news)

#8. 토픽분석
Sys.setenv(JAVA_HOME='C:\\Program Files\\Java\\jdk-18.0.2') # jdk 경로
library(rJava)   
library(KoNLP) # 로딩 성공  
library(tm) # 전처리 용도 
library(wordcloud) # 단어 구름 시각화 

# term='추가단어', tag=ncn(명사지시코드)
user_dic <- data.frame(term=c("펜데믹","코로나","코로나19","더블링","원숭이두창"), tag='ncn')
user_dic
buildDictionary(ext_dic='sejong', user_dic = user_dic)

# 단계3 : 단어추출 사용자 함수 정의
# (1) Sejong 사전에 등록된 신규 단어 테스트    
extractNoun('김진성은 많은 사람과 소통을 위해서 소셜네트워크에 가입하였습니다.') #KoNL
paste(extractNoun('코로나19로 인해서 전세계 팬더믹에 빠졌다'), collapse=" ")
#paste(문장)
#extractNoun(명사 추출)
#collapse (단어 추출후 문장으로 묶어줌)
# (2) 사용자 정의 함수 실행 순서 : 문자변환 -> 명사 단어추출 -> 공백으로 합침
exNouns <- function(x) { 
  paste(extractNoun(as.character(x)), collapse=" ")
}

# (3) exNouns 함수 이용 단어 추출 
# 형식) sapply(vector, 함수) -> 76개 vector 문장(원소)에서 단어 추출 
news_nouns <- sapply(news, exNouns) 
news_nouns[1]
news_nouns[76]

# 단계4 : 자료 전처리   
# (1) 말뭉치(코퍼스:Corpus) 생성 : 문장을 처리할 수 있는 자료의 집합 
myCorpus <- Corpus(VectorSource(news_nouns)) 
myCorpus
# <<SimpleCorpus>>
# Metadata:  corpus specific: 1, document level (indexed): 0
# Content:  documents: 76

# corpus 내용 보기



# (2) 자료 전처리 : 말뭉치 대상 전처리 
myCorpusPrepro <- tm_map(myCorpus, removePunctuation) # 문장부호 제거
myCorpusPrepro <- tm_map(myCorpusPrepro, tolower) # 소문자 변경

# 영문 대상 불용어 제외 : stopwords()
stopwords('english')
myCorpusPrepro <-tm_map(myCorpusPrepro, removeWords, stopwords('english')) # 불용어제거


# (3) 전처리 결과 확인 
myCorpusPrepro # Content:  documents: 76
inspect(myCorpusPrepro[1:3]) # 데이터 전처리 결과 확인(숫자, 문장부호, 영문 상태 확인)

myCorpusPrepro_term <- TermDocumentMatrix(myCorpusPrepro, 
                                          control=list(wordLengths=c(4,16))) 

myTerm_df <- as.data.frame(as.matrix(myCorpusPrepro_term)) 
dim(myTerm_df) 
myTerm_df

table(myTerm_df[1,])

wordResult <- sort(rowSums(myTerm_df), decreasing=TRUE) 
wordResult[1:10] # top10 단어  

myStopwords = c(stopwords('english'), ""); # 제거할 문자 추가
myCorpusPrepro <-tm_map(myCorpusPrepro, removeWords, myStopwords) # 불용어제거

myCorpusPrepro_term <- TermDocumentMatrix(myCorpusPrepro, 
                                          control=list(wordLengths=c(4,16))) # 2음절 
myTerm_df <- as.data.frame(as.matrix(myCorpusPrepro_term)) 

wordResult <- sort(rowSums(myTerm_df), decreasing=TRUE) 
wordResult[1:10]

myName <- names(wordResult)
word.df <- data.frame(word=myName, freq=wordResult) 
str(word.df) # word, freq 변수
head(word.df)

pal <- brewer.pal(12,"Paired") # 12가지 색상 pal <- brewer.pal(9,"Set1") # Set1~ Set3
# 폰트 설정세팅 : "맑은 고딕", "서울남산체 B"
windowsFonts(malgun=windowsFont("맑은 고딕"))  #windows

# (4) 단어 구름 시각화: 크기,최소빈도수,순서,회전,색상,글꼴 지정  
wordcloud(word.df$word, word.df$freq, 
          scale=c(3,1), min.freq=2, random.order=F, 
          rot.per=.1, colors=pal, family="malgun")
# 단계8 : 차트 시각화  
#(1) 상위 10개 토픽추출
topWord <- head(sort(wordResult, decreasing=T), 10) # 상위 10개 토픽추출 
# (2) 파일 차트 생성 
pie(topWord, col=rainbow(10), radius=1) 
# radius=1 : 반지름 지정 - 확대 기능  

# (3) 빈도수 백분율 적용 
pct <- round(topWord/sum(topWord)*100, 1) # 백분율

# (4) 단어와 백분율 하나로 합친다.
label <- paste(names(topWord), "\n", pct, "%")

# (5) 파이차트에 단어와 백분율을 레이블로 적용 
pie(topWord, main="SNS 빅데이터 관련 토픽분석", 
    col=rainbow(10), cex=0.8, labels=label)