네이버 카페 게시물 댓글수, 조회수 크롤링 하기

2019. 9. 5. 16:06프로그래밍 언어/Python

지인 요청으로 네이버 카페 게시물의 댓글수와 조회수를 가져오는 간단한 크롤러를 만들었습니다.

 

요구사항

input : 네이버 카페 게시물 url 리스트가 있는 엑셀 파일 (.xlsx)
process : 게시물 url에서 댓글 수와 조회수를 가져온다. 엑셀 파일 해당 라인의 댓글 수, 조회수 열에 덮어쓰기한다.
output : 댓글 수, 조회수가 덮어쓰기 된 엑셀 파일 (.xlsx)

 

* 기재된 카페와는 아무 관련이 없습니다.

 

 

개발 환경

[OS]
- MacOS Mojave 10.14.6

[Language]
- Python 3.7

[Library]
- Selenium 3.141.0
- Beautiful Soup4 4.8.0
- OpenPyXL 2.6.3

[Driver]
- ChromeDriver 76.0.3809

[IDE]
- Eclipse 2019-06 (4.12.0)
- pyDev 7.3.0

 

아래는 크롤러를 구현하면서 발생한 문제점과 해결방법들을 적어보겠습니다.

정답은 아니고 제가 해결해본 방법일 뿐이기 때문에

다른 좋은 방법이 있거나 제 방식이 틀렸을 경우 댓글 부탁드리겠습니다 !!

 


1. ChromeDriver 버전 오류

https://sites.google.com/a/chromium.org/chromedriver/downloads

위의 링크에서 크롬 드라이버를 설치했습니다.

자신의 PC에  설치된 크롬 버전과 드라이버의 버전이 맞아야 합니다.

버전확인을 잘 하시고 OS에 맞는 파일을 다운받아서 압축해제하시면 됩니다.

크롬 버전 확인은 아래의 두 경로에서 확인이 가능합니다.

chrome://version/

chrome://settings/help

(직접 주소창에 입력해주셔야합니다.)

 

만약 버전에 맞지 않는 드라이버를 설치했을 경우 아래와 같은 exception이 발생합니다.

selenium.common.exceptions.SessionNotCreatedException: Message: session not created: This version of ChromeDriver only supports Chrome version 77

 

 

 

2. ChromeDriver 경로 오류

크롬 드라이버를 아래처럼 일반 사용자 폴더인 Documents, Downloads에 압축해제후 연결할 경우 

# 크롬 드라이버 연결
driver = webdriver.Chrome('/User/사용자이름/Documents/chromedriver')

크롬 드라이버 실행파일이 경로에 있어야 한다는  exception이 발생합니다.

selenium.common.exceptions.WebDriverException: Message: 'chromedriver' executable needs to be in PATH. Please see https://sites.google.com/a/chromium.org/chromedriver/home

이 문제는 드라이버 경로를 /usr/local/bin 하위에 위치시켜서 해결하였습니다.

# 크롬 드라이버 연결
driver = webdriver.Chrome('/usr/local/bin/chromedriver')

 

 

 

4. 네이버 로그인

네이버 카페 게시물을 보려면 아래의 조건을 충족해야 합니다.

1) 게시물이 전체공개일 때
   ① 로그인하지 않아도 조회 가능
2) 게시물이 멤버공개일 때
  ① 네이버에 로그인 되어있는 상태
  ② 해당 카페에 가입되어있는 상태
  ③ 해당 게시물을 볼 수 있는 권한 (회원등급)이 있는 상태

 

2-2, 2-3번 문제의 경우 요청하신 분 께서 권한은 전부 있다고 하셔서 넘겼습니다.

2-1번 문제는 맨 처음 실행시 네이버 로그인 후 카페 게시물로 페이지 이동하도록 수정했습니다.

 

네이버 정책상 셀레늄 같은 자동화 도구를 통한 접근을 부정적 이용으로 판단하고 있어

가장 간단하게 send_keys 메소드를 이용해 로그인 구현시 캡챠(자동입력방지)가 실행되어 한 번에 로그인이 되지 않습니다.

# 네이버 로그인
id = 'user_id' # 사용자 아이디
pw = 'user_password' # 비밀번호
driver.find_element_by_name('id').send_keys(id)
driver.find_element_by_name('pw').send_keys(pw)
driver.find_element_by_class_name('btn_global').click()

 

그래서 아래와 같이 스크립트 구문을 만들어서 아이디와 비밀번호를 입력했습니다.

중간중간 타임슬립도 랜덤하게 지정해주면 캡챠에 잘 걸리지 않는다고 하여 추가했습니다.

그러나 추후에는 이 방법도 막힐 수 있습니다.

# 네이버 로그인
id = 'user_id' # 사용자 아이디
pw = 'user_password' # 비밀번호
driver.execute_script("document.getElementsByName('id')[0].value=\'" + id + "\'")
driver.execute_script("document.getElementsByName('pw')[0].value=\'" + pw + "\'")
time.sleep(randrange(1,3))
driver.find_element_by_class_name('btn_global').click()

 

 

 

4. iframe

우선 네이버 카페 게시물은 이렇게 생겼습니다.

오른쪽 부분이 게시물 컨텐츠가 담긴 부분인데요, 여기가 iframe으로 구성되어있습니다.

 

코드로 보시면 "cafe_main"이란 name의 iframe이 있고

#document가 중첩되어 새로 시작되는 것을 볼 수 있습니다.

 

iframe 태그에서 src를  "about:blank"로 받아오기 때문에, Beautiful Soup4만 써서는 크롤링이 어려웠습니다.

결국 Selenium과 Beautiful Soup4를 같이 사용해 iframe의 src를 받아오고

switch_to 메소드로 프레임을 전환하여 cafe_main 하위에 있는 요소에 접근하였습니다.

driver.switch_to_default_content # 상위 프레임으로 전환
driver.switch_to.frame('cafe_main') # cafe_main 프레임으로 전환

html = driver.page_source # 현재 페이지의 주소를 반환 
soup = BeautifulSoup(html, 'html.parser')

# 댓글수와 조회수를 찾는다     
reply_sort = soup.find_all('div', class_='fl reply_sort')

 

 

5. 조회수를 알 수 없는 게시물

6. 삭제된 게시물

try-except 구문으로 감싸서

얼럿 창이 있을 경우 삭제되었거나 없는 게시물

없을 경우 댓글수/조회수 수집하도록 처리

 

 


2021-03-08 본 게시물의 크롤러는 공유가 어려운 점 참고부탁드립니다.

 

 

 

'프로그래밍 언어 > Python' 카테고리의 다른 글

Selenium 개발도구 로그 숨기기  (0) 2020.06.24