개발일지/빅데이터 댓글 시각화 프로젝트

[Python] 네이버 뉴스 기사 댓글 크롤링하기(Feat. Selenium, Webdriver)

Emil :) 2020. 6. 6. 19:29
728x90
반응형

오늘의 목표


  1. 네이버 뉴스 기사의 정보 크롤링하기
  2. 해당 기사에 달린 댓글들의 남녀 성비, 연령대별 비율, 댓글 및 등록시간 크롤링

 

참고


1. 기사 크롤링하기
https://hogni.tistory.com/69

 

파이썬 네이버 뉴스 기사 크롤링하기: 초보자도 실행할 수 있는 코드

이전에 뉴스 알림 봇을 만드는 내용을 작성했던 적이 있습니다. 당시에는 네이버 모바일 버전에서 뉴스 기사를 가져오는 방법을 사용했었는데, PC 버전에서는 어떻게 할 수 있는지 여쭤보시는 ��

hogni.tistory.com

2. 댓글 크롤링 예제 - https://blog.pignu.kr/2018/03/26/naver_crawling.html

 

네이버뉴스 댓글 크롤링 with python

간단히 해보는 네이버 댓글 크롤링

blog.pignu.kr

 

 

진행 과정


1. 네이버 뉴스 기사의 정보 크롤링하기


먼저 코딩에 쓰일 URL이다.
https://news.naver.com/main/read.nhn?m_view=1&includeAllCount=true&mode=LSD&mid=shm&sid1=100&oid=422&aid=0000430957

 

윤미향 공방…"수사 지켜봐야" vs "국민이 퇴출운동"

[뉴스리뷰] [앵커] 윤미향 의원의 해명 기자회견에도 불구하고 정치권의 공방은 계속됐습니다. 민주당은 수사를 지켜보자며 신중 모드를 유지했지만, 통합당은 퇴출운동까지 거론하며 공세의 ��

news.naver.com

 

from selenium import webdriver
import time

url = 'https://news.naver.com/main/read.nhn?m_view=1&includeAllCount=true&mode=LSD&mid=shm&sid1=100&oid=422&aid=0000430957'

#웹 드라이버
driver = webdriver.Chrome('./chromedriver.exe')
driver.implicitly_wait(30)
driver.get(url)

#더보기 계속 클릭하기
while True:
    try:
        btn_more = driver.find_element_by_css_selector('a.u_cbox_btn_more')
        btn_more.click()
        # time.sleep(1)
    except:
        break


#기사제목 추출
article_head = driver.find_elements_by_css_selector('div.article_info > h3 > a')
print("기사 제목 : " + article_head[0].text)

#기사시간 추출
article_time = driver.find_elements_by_css_selector('div.sponsor > span.t11')
print("기사 등록 시간 : " + article_time[0].text)

생각보다 되게 간단하게 구현할 수 있어서 놀랐다.
크롤링을 하기 위해선 먼저 selenium 설치가 필요하다.
설치방법은 아래 방법을 확인하자

https://kkkapuq.tistory.com/62

 

[Pycharm] 파이참에서 패키지 설치하기

개요 파이썬에서 패키지를 설치할 땐 두가지 방법이 있다. 명령 프롬프트와 python -install 명령어를 통해 설치하는것과 파이참과 같은 IDE에서 제공하는 패키지를 다운받는 방식이다. 둘 다 어느것

kkkapuq.tistory.com

BeautifulSoup는 이 예제에서는 사용하지 않으므로 별도로 설치는 필요없지만, 나중에 필요한 경우가 많으니 하는김에 해주는게 좋다.

그리고 webdriver를 설치해야 한다. 나는 크롬으로 했당

https://chromedriver.chromium.org/downloads

 

Downloads - ChromeDriver - WebDriver for Chrome

WebDriver for Chrome

chromedriver.chromium.org

해당 링크에서 원하는 버전을 다운로드 받고, (글 쓴 시점 기준으로 안정적인 버전은 83이라고한다)
압축을 푼 뒤, 파이썬 프로젝트가 있는 디렉토리에 같이 냅두면 된다.
이렇게 되면 웹드라이버를 활용한 크롤링 준비는 완료됐고, 어떻게 사용하는지 살펴보자

from selenium import webdriver
import time

url = 'https://news.naver.com/main/read.nhn?m_view=1&includeAllCount=true&mode=LSD&mid=shm&sid1=100&oid=422&aid=0000430957'

#웹 드라이버
driver = webdriver.Chrome('./chromedriver.exe')
driver.implicitly_wait(30)
driver.get(url)

6열과 같이 웹드라이버의 위치를 명시해주고, driver라는 변수로 할당해준다.
7열은 지정한 시간동안 파싱되는 시간을 기다려주는 메소드다. 30초안에 파싱이 안되면 종료한다는 뜻
8열은 웹드라이버를 해당 url로 실행시키는 함수다. 실행시키면 이런 화면이 나올거다

실제 크롬과 흡사하지만, 테스트용이라고 보면 쉽다.

이제 이 화면에서 원하는 정보를 출력할 땐, 여러가지 방법이 있다.

#더보기 계속 클릭하기
while True:
    try:
        btn_more = driver.find_element_by_css_selector('a.u_cbox_btn_more')
        btn_more.click()
        # time.sleep(1)
    except:
        break


#기사제목 추출
article_head = driver.find_elements_by_css_selector('div.article_info > h3 > a')
print("기사 제목 : " + article_head[0].text)

#기사시간 추출
article_time = driver.find_elements_by_css_selector('div.sponsor > span.t11')
print("기사 등록 시간 : " + article_time[0].text)

코드를 설명하기 앞서, while문은 기사 댓글의 '더 보기' 버튼을 자동으로 클릭해주는 구간이다.
네이버 기사는 댓글 더 보기를 끝까지 눌러야 전체 댓글이 보여지기 때문에.. 시간이 좀 걸리지만 꼭 필요하다.
중간의 time.sleep(1)은 주석처리해도 상관없다. 네트워크 환경에 따라 잘 안된다면 딜레이를 넣어주도록 하자.
눈여겨 볼 것은 find_elements_by_css_selector이다.

find_element_by_css_selector는 하나의 오브젝트로 저장되지만,
find_elements_by_css_selector는 배열 형태로 저장된다.

따라서 찾고자하는 css가 1개면 element를, 여러개면 elements를 사용해주자.

그러면, '더 보기' 버튼을 어떻게 찾아가는지 알아보자.

댓글의 '더 보기' 버튼을 우클릭하고 '검사' 버튼을 누르면 이처럼 콘솔창에 html 코드가 나타난다.
이를 활용해서..

btn_more = driver.find_element_by_css_selector('a.u_cbox_btn_more')

element 함수를 써주면 '더 보기' 버튼으로 포인터가 가있는 상태라고 생각하면 쉽다.
a.u_cbox~ 이부분은 하위 태그를 찾아가는 표기법이라고 생각하면 된다.
a 태그에 속해있는 u_cbox_btn_more 라는 클래스를 찾아간다. 라는 뜻이다.

#더보기 계속 클릭하기
while True:
    try:
        btn_more = driver.find_element_by_css_selector('a.u_cbox_btn_more')
        btn_more.click()
        # time.sleep(1)
    except:
        break

그렇다면 이 코드가 해설이 된다.
click 함수는 말그대로 클릭하는것.
그리고 btn_more가 더이상없다면 break 하면된다.

이렇게 전체 댓글을 화면에 다 띄운 뒤에

#기사제목 추출
article_head = driver.find_elements_by_css_selector('div.article_info > h3 > a')
print("기사 제목 : " + article_head[0].text)

#기사시간 추출
article_time = driver.find_elements_by_css_selector('div.sponsor > span.t11')
print("기사 등록 시간 : " + article_time[0].text)

기사 제목과 기사 등록시간도 마찬가지로 우클릭 - 검사를 통해 html 태그를 알아내고, css 선택자 함수로 경로만 지정해주면 다음과 같이 나타난다.

이 때, elements는 앞서 말했던것처럼 배열형식으로 저장되기 때문에 [0]을 써줬다.
.text는 텍스트만 출력한다는 뜻임

 

2. 댓글 및 댓글 상세정보 크롤링


댓글의 남녀 성비, 연령대 등도 가져오고자 한다. 간단하게 표기하면 다음과 같다.

# 성비와 연령대 추출
per = driver.find_elements_by_css_selector('span.u_cbox_chart_per')

print("남자 성비 : " + per[0].text)
print("여자 성비 : " + per[1].text)
print("10대 : " + per[2].text)
print("20대 : " + per[3].text)
print("30대 : " + per[4].text)
print("40대 : " + per[5].text)
print("50대 : " + per[6].text)
print("60대 이상 : " + per[7].text)

물론 이는 단순히 정적인 배열로 표기한 방법이기에, 썩 좋은 방법은 아니지만 큰 변화가 없다면 이렇게 하는 것이 간편하다.

변동사항이 큰 태그의 경우에만 할당해주도록 하자.
아무튼 이렇게하면 다음과 같이 표기된다.

원본
결과

 

이렇게 해서 기사 제목, 댓글 작성자들의 비율을 가져올 수 있다.
이제 메인 컨텐츠인 댓글을 가져와야 한다. 그런데 문제가있다.
먼저 댓글을 긁어오는 코드를 보자.

#댓글추출
contents = driver.find_elements_by_css_selector('span.u_cbox_contents')
cnt = 1;
for content in contents:
    print(cnt, " : ", content.text)
    cnt+=1

결과는 다음과 같이 잘 뽑힌다. 하지만 이상한 점이 있지 않은가?

작성된 댓글은 581개지만, 추출된 댓글은 527개다

그렇다, 네이버의 경우 클린봇이 비속어를 포함한 댓글은 가려버려서 추출이 안되는 것이다.
이를 해결하기 위해서 클린봇을 직접 꺼줄 필요가 있다.

해당 코드를 더 보기 버튼을 누르기 전에 삽입해주자, 나중에 넣으니까 시간이 오래걸리더라.

#네이버의 경우, 클린봇으로 추출이 안되는게 있다, 클린봇 옵션 해제 후 추출해주도록 한다.
cleanbot = driver.find_element_by_css_selector('a.u_cbox_cleanbot_setbutton')
cleanbot.click()
time.sleep(1)
cleanbot_disable = driver.find_element_by_xpath("//input[@id='cleanbot_dialog_checkbox_cbox_module']")
cleanbot_disable.click()
time.sleep(1)
cleanbot_confirm = driver.find_element_by_css_selector('a.u_cbox_layer_cleanbot_extrabutton')
cleanbot_confirm.click()
time.sleep(1)

이걸 하면서 느꼈는데, css_selector 함수는 생각보다 복잡한 경우가 좀 많았다. 잘 안되기도하고..
개인적으로 xpath를 쓰는걸 추천한다.
xpath의 자세한 사용법은 아래 링크 참조
https://www.fun-coding.org/crawl_advance5.html

 

웹크롤링 심화: XPATH 이용하기 - 잔재미코딩

연습문제 http://v.media.daum.net/v/20170202180355822 페이지에서 [김익현의 미디어 읽기] '마이너리티 리포트'와 AI 를 XPATH로 크롤링해서 출력하세요

www.fun-coding.org

css_selector를 이용해서 클린봇을 누르면, 클릭할 수 없는 요소라고 에러가 뜬다.
이 때 xpath로 설정해봤더니 잘 된다.

581개의 댓글 모두 크롤링된다.

 

이렇게 해서, 최종 완성된 코드는 다음과 같다.

from selenium import webdriver
import time

url = 'https://news.naver.com/main/read.nhn?m_view=1&includeAllCount=true&mode=LSD&mid=shm&sid1=100&oid=422&aid=0000430957'

#웹 드라이버
driver = webdriver.Chrome('./chromedriver.exe')
driver.implicitly_wait(30)
driver.get(url)

#네이버의 경우, 클린봇으로 추출이 안되는게 있다, 클린봇 옵션 해제 후 추출해주도록 한다.
cleanbot = driver.find_element_by_css_selector('a.u_cbox_cleanbot_setbutton')
cleanbot.click()
time.sleep(1)
cleanbot_disable = driver.find_element_by_xpath("//input[@id='cleanbot_dialog_checkbox_cbox_module']")
cleanbot_disable.click()
time.sleep(1)
cleanbot_confirm = driver.find_element_by_css_selector('a.u_cbox_layer_cleanbot_extrabutton')
cleanbot_confirm.click()
time.sleep(1)

#더보기 계속 클릭하기
while True:
    try:
        btn_more = driver.find_element_by_css_selector('a.u_cbox_btn_more')
        btn_more.click()
        # time.sleep(1)
    except:
        break


#기사제목 추출
article_head = driver.find_elements_by_css_selector('div.article_info > h3 > a')
print("기사 제목 : " + article_head[0].text)

#기사시간 추출
article_time = driver.find_elements_by_css_selector('div.sponsor > span.t11')
print("기사 등록 시간 : " + article_time[0].text)

# 성비와 연령대 추출
per = driver.find_elements_by_css_selector('span.u_cbox_chart_per')

print("남자 성비 : " + per[0].text)
print("여자 성비 : " + per[1].text)
print("10대 : " + per[2].text)
print("20대 : " + per[3].text)
print("30대 : " + per[4].text)
print("40대 : " + per[5].text)
print("50대 : " + per[6].text)
print("60대 이상 : " + per[7].text)

#댓글추출
contents = driver.find_elements_by_css_selector('span.u_cbox_contents')
cnt = 1;
for content in contents:
    print(cnt, " : ", content.text)
    cnt+=1

 

 

 

오늘의 결과


실행시키면 webdriver에서 이렇게 실행된다. 마치 매크로같음

 

위에 기사 정보와 비율이 뜨고
댓글들을 다 긁어온다.

 

더 보기 버튼을 눌러서인지 실행속도가 매우 느리다.. 다 하고나면 약 30초가량 걸리는데, 속도를 어떻게 개선하는지에 대해서 고민을 해봐야 할 것 같다

728x90
반응형