22-08-12 chap07_3_news_crawling
# 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)