2017년 12월 31일 일요일

파이썬을 이용한 네이버 카페 업무 자동화 2

지난 글에서 네이버 카페 특정 레벨의 회원 아이디 리스트 얻기와 찾아진 명단으로 게시글 검색하는 내용까지 다루었다. 실제 해야 하는 작업은 검색 결과를 바탕으로 회원 레벨을 조정하는 것. 이제 이 마지막 작업을 자동화할 단계이다.

회원 레벨 조정은 어느 메뉴에서든 할 수 있지만, 관리 메뉴의 전체 멤버 관리 화면이 아이디로 검색해 원하는 멤버를 찾아 레벨 조정하기 편리하게 되어 있어 그걸 이용하기로 했다.

준비 과정은 동일하게 셀레늄을 import하고 크롬 드라이버를 띄운다. 이제 브라우저 화면의 원하는 자리에 원하는 값을 넣고 원하는 버튼을 누르는 작업을 파이썬으로 한줄씩 코딩해 넣으면 된다. 물론 아이디 목록이 들어있는 파일을 읽어와서 이 작업을 반복하는 for 루프 하나 만들고.

원하는 자리나 원하는 버튼을 찾아내는 것은 지난 글에서 쓴 대로, 크롬 브라우저에서 마우스 우클릭 후 맨 아래 "검사(N)" 메뉴를 클릭하면 된다. 오른쪽에 창이 열리면서 해당 element가 반전되어 보이는데, 먼저 반전된 element에 마우스 우클릭하여 copy - copy element를 눌러보자. 메모장 등에 붙여넣어보면 element 내용을 확인할 수 있는데, 여기 id나 name 등이 포함되어 있어야 find_element_by_id(), find_element_by_name() 등으로 찾을 수가 있다. 어떤 버튼은 copy element로 보면 별다른 정보가 없는데, 이때는 copy - copy xpath를 선택하고 find_element_by_xpath()를 이용해서 찾으면 된다.



가령 (2)번 버튼의 경우 copy element로 해서 보면 "<span>검색</span>" 이렇게밖에 안 나오지만, copy xpath로 보면 "//*[@id="frmSearch"]/div/div/div[1]/a[1]/span"로 나온다.

한단계 한단계 찾아나가는 과정에서는 파이썬 쉘을 띄워놓고 한 줄씩 실행해 보고 잘 되면 코드에 넣고 그런 식으로 하면 된다.

버튼을 클릭했을 때 팝업창이 뜨는 경우가 있다. 예를 들어 등급을 선택하고 (5)번 변경 버튼을 누르면 대상자를 확인하고 코멘트를 입력하는 팝업이 뜬다. 이때는 팝업창 쪽으로 포커스를 전환해 줘야 팝업 창에서 필요한 작업을 수행하고 팝업을 닫을 수 있게 된다. 이때 필요한 명령은 driver.switch_to_window()다. 먼저 handle = driver.window_handles 처럼 해서 현재 떠 있는 창들의 핸들값을 얻은 다음, 필요한 창으로 전환하면 된다. 메인 윈도우의 핸들은 handle[0]에, 팝업창의 핸들은 handle[1]에 저장된다. driver.switch_to_window(handle[1])로 포커스를 팝업창으로 전환하면 된다.

팝업창에서 코멘트 넣고 확인 버튼을 누르면 이번엔 경고창 (alert)이 뜬다. 확인 눌러서 닫으면 되는데 이것도 처리해줘야 한다. driver.switch_to.alert.accept() 명령으로 간단하게 처리 가능. 그리고 나면 팝업창은 닫히는데, 그렇다고 해서 핸들이 메인 윈도우로 저절로 돌아가지는 않으므로 driver.switch_to_window(handle[0])로 다시 포커스를 돌려줘야 한다.

사실 노하우는 이게 거의 전부다. 문제는 이렇게 해서 돌려보니 자꾸 오류가 나는데, 그건 버튼을 누른 후 해당 웹페이지를 가져올 때까지 기다린 후 다음을 진행해야 하는데 기다리는 시간이 충분치 않아서이다. 쉘에서야 한 줄씩 차례차례 실행하니 문제가 없지만 다 짜서 돌리면 딜레이를 주지 않으면 값을 읽어오지 못한다. 게다가 이 딜레이는 인터넷 상황, 서버 로딩에 따라 매우 유동적이다. 코딩 후 테스트시에는 각 단계에서 1초의 딜레이만으로 아무 문제없이 잘 돌았는데, 막상 실제 등급 조정 작업을 120명 걸어놓고 돌려보니 단계별 3초 딜레이로도 충분치 않은 경우가 있었다. 그렇다고 무작정 길게 할 수도 없는 것이고, 확실히 로딩이 된 걸 확인하고 넘어갈 수 있는 방법이 필요하다. 아래는 총 정리된 파이썬 코드.

향후 개선 방향은 현재 아이디만 추출하게 되어 있는 것을 아이디와 별명을 함께 추출하여 사람이 보기 좋게 적절히 포맷 만들어 저장하는 것, 단계별 막연히 3초 정도 딜레이 준 것을 try - catch 문으로 1초씩 딜레이 늘려가며 로딩 확실히 될 때까지 루프 돌다가 넘어가게 하는 것이다. 그러나 내가 원래 하려던 등급 조정 작업은 이미 끝났으므로, 이 개선 작업은 과연 언제 하게될지 기약이 없다. 아마 올 연말에나 다시 하게 되지 않을까?

2017년 12월 25일 월요일

스마트폰 잠금에 대한 설명

1. 스마트폰 화면잠금은 필수!

스마트폰을 왜 잠궈야 할까? 물론 내 스마트폰이 남의 손에 들어갈 일이 절대로 발생할 리가 없다면, 잠그지 않아도 괜찮다. 그러나, 도난, 분실의 우려는 물론이고, 잠시 부주의한 사이 누군가 내 스마트폰을 만질 수도 있다. "내 폰에는 중요한 게 없어서 잠그지 않아도 괜찮다."고 하는 분들이 있는데, 이분들은 한국 사회에서 "신원확인"의 대부분을 휴대폰으로 한다는 사실이 무엇을 의미하는지 진지하게 생각해 보지 않아서 그렇다. 휴대폰 소액결제는 물론이고, 고가의 유료 통화, 문자, 게임 아이템 구매 등 휴대폰 만으로 직접 돈을 쓸 수 있는 방법만도 수없이 많다. 게다가 휴대폰으로 신원 확인을 통해 대출을 받거나 할부로 물건을 구매하는 등 예상할 수 있는 피해는 한계를 정하기 어렵다.

물론 휴대폰이 잠시 내 손을 떠난게 겨우 5분이라면 그 사이에 누군가 내 명의로 대출을 완료하기는 어렵겠지만, 그정도 시간이면 누군가 내 폰에 악성 앱을 설치하기에는 충분한 시간이다. 악성 앱은 장기적으로 내 주소록과 사진은 물론, 카메라와 마이크를 원격 조정해 내 생활을 모두 감시하거나 모바일 뱅킹을 할 때 비밀번호, 공인인증서 비밀번호 등을 모두 훔쳐낼 수 있다.

그리고 분실, 도난이 내가 조심한다고 100% 막아지는 일인가? 휴대폰과 지갑을 같이 분실한다면? 그 휴대폰에 잠금이 안 걸려 있다면? 나는 이런 상황은 상상조차 하고 싶지 않다. 혹자는 휴대폰 잠금 걸어봐야 다 풀어낸다고도 하지만, 그 잠금을 푸는 데 걸리는 시간을 벌 수 있다면 그 사이에 통신사에 연락해 번호를 정지시킬 수 있다. 잠금이 안 걸려 있다면, 누군가 내 폰을 손에 넣는 순간부터 내가 그 사실을 인지하는 순간까지 내 인생은 완전히 다른 누군가의 손에 맡겨져 버리는 셈이다. 그 폰으로 내가 목숨보다 사랑하는 내 가족에게 전화를 해서 사기를 친다면? 그들의 생명을 위태롭게 한다면?

자, 만약 당신의 스마트폰에 화면잠금이 설정되어 있지 않다면 지금 당장 설정 메뉴에 들어가서 설정하도록 하자. 단순 패턴이라도 없는 것보다 낫다. 물론 패턴에서 기역자나 니은자, N이나 Z 이런 패턴은 두세번만 시도해 보면 바로 풀리니 이런 것보다는 어려운 걸로 설정해야 한다. 네자리 PIN 설정에 0000이나 1234 이런 걸 쓰지 말아야 하는 것처럼. 보다 길고 어려운 패스워드로 설정하는 사람도 있지만 사실 휴대폰 키보드로 매번 패스워드를 입력하는 것은 매우 불편하고 오타의 위험도 높으니 패스워드는 오히려 권장하지 않는다.


2. 휴대폰 전원 켤 때 잠금

휴대폰 전원 켤 때 잠금 메뉴는 일반 화면잠금과는 다른 것인데, 제대로 이해하고 사용하는 사람이 많지 않다. 사실 이해하기가 아주 쉽지는 않다. 잠금 설정할 때 이걸 선택해야 할지 고민하는 분들을 위해 이게 뭐하는 기능인지, 어떤 장점이 있고 또 어떤 위험성이 있는지 설명하려 한다. 휴대폰 전원 켤 때 잠금은 먼저 화면잠금 설정이 되어 있어야 추가로 설정 가능한 기능이다. 두 상황에서 같은 패스워드를 사용한다.

이 기능을 이해하려면, 먼저 "암호화"라는 것을 이해해야 한다. 이 기능은 데이터 암호화와 직접 관련되어 있는 기능이기 때문이다. 우리말로 암호라는 말이 두가지 의미로 쓰여 혼동이 되기 때문에, 이 글에서는 영어로 encryption은 "암호화"로, password는 "패스워드"로 구분해 사용하겠다. 그리고 안드로이드는 화면잠금에 패턴, PIN, 패스워드 세가지를 지원하는데 (LG 휴대폰은 노크코드도 지원한다), 편의상 이걸 통틀어 패스워드로 부르겠다.

아무튼 암호화란, "암호키"를 사용해 데이터를 알아볼 수 없는 형태로 바꾸고, 오직 암호키를 가진 사람만 본래 형태로 복호화하여 데이터를 알아볼 수 있게 하는 기능이다. 본래 안드로이드의 데이터 암호화는 원하는 사용자가 설정 메뉴에서 직접 "암호화하기" 버튼을 눌러 수동으로 하게 되어 있었는데, 이게 안드로이드 6.0 마쉬멜로우부터 기본 암호화로 바뀌었다. 즉 출시 시점부터 마쉬멜로우를 탑재하고 나온 안드로이드폰이라면 내가 폰을 사는 시점에 이미 데이터 저장 영역은 암호화가 설정되어, 내가 저장하는 모든 데이터는 자동으로 암호화되어 저장된다.

이게 왜 유용한 기능이냐 하면, 이렇게 암호화되어 저장된 데이터는 그 상태로 폰이 꺼져 있거나 메모리가 폰에서 분리된 상태로 누구의 손에 들어간다 해도 암호키를 모른다면 복호화할 수 없기 때문이다. 물론 보안에서 "절대 불가능한" 것은 없고, 암호를 푸는데 충분히 오랜 시간이 걸린다고 하는 것이 더 정확하겠다. 아무튼 현존하는 가장 강력한 컴퓨터로 수십년 이상의 시간이 걸린다면 충분히 안전하다고 봐도 좋을 것이다.

그런데 이렇게 암호화되어 있어도, 폰을 사용하려면 암호키를 사용해 데이터를 복호화해야 한다. 그럼 그 암호키는 어디서 오는 것일까? 당연히 어딘가에 저장되어 있다. 그러나 암호키를 그대로 어딘가에 저장해둔다면, 해커는 그 암호키를 읽어낼 수 있을 것이다. 따라서 암호키를 그대로 저장하면 안되고, 암호키를 다시 암호화해서 저장해야 한다. 마치 금고 열쇠를 안전한 곳에 두기 위해, 금고 열쇠를 저장하는 또 다른 금고를 마련하는 식이다. 그럼 이 두번째 금고 열쇠, 즉 암호키를 암호화하는데 쓰는 두번째 암호키는 또 어떻게 보호하는 걸까?

이 두번째 암호키가 바로 휴대폰 전원 켤 때 잠금 메뉴와 관련이 있다. 이 메뉴를 활성화하면, 사용자의 패스워드를 이 두번째 암호키를 만드는 데 사용하는 것이다. 이렇게 설정해 놓으면, 폰을 켜면 부팅이 진행되기 전에 사용자의 패스워드를 먼저 묻고, 사용자가 입력한 패스워드를 이용해 두번째 암호키를 얻어낸다. 이걸로 금고를 열어 첫번째 암호키를 꺼내고, 이걸로 사용자의 데이터를 복호화해 폰을 정상적으로 부팅시키게 된다. 반대로 이 메뉴를 활성화시키지 않으면, 사용자의 패스워드 대신 단말기에서 생성해 낸 "기본 암호키"를 이용하기 때문에 사용자의 패스워드 입력 없이도 폰이 정상적으로 부팅이 된다.

자 이제 휴대폰 전원 켤 때 잠금 메뉴를 활성화한 경우의 장단점을 설명해 보자. 이 모드의 장점은, 내가 패스워드를 입력해야만 그걸로 두번째 암호키를 얻어낼 수 있으므로, 패스워드를 모른다면 그 누구도 데이터를 복호화해 낼 수 없다는 것이다. 따라서 폰을 분실하거나, 도난당하거나, 파손되거나, 어떤 상황에 처하더라도 내 데이터는 안전하다는 것이 보장된다. 그리고 당연하게도, 데이터를 복호화할 수 없으니 내 폰의 전원이 꺼져 있다면 내가 아닌 그 누구도 내 폰을 켜서 사용할 수 없다. 그 어떤 화면잠금 해제 툴이나 루팅 툴도 모두 무용지물이다. 반면 단점은, 역시 그 누구도 데이터를 복호화낼 수 없다는 것이다. 즉 내가 패스워드를 잊어버린다면, 세상 그 누구도 데이터를 복호화낼 수 없게 된다. 제조사 서비스센터도, 구글도 데이터를 복호화해낼 수 없다.

이 모드는 또 하나의 단점이 있는데, 그건 부팅이 정상적으로 진행되려면 패스워드 입력을 받아야 하고, 패스워드 입력을 받기 전에는 아직 폰이 정상적으로 동작하지 않는 상태라는 것이다. 패스워드 입력을 기다리고 있는 상태에서는 비상전화를 제외하고는 그 어떤 기능도 동작하지 않는다. 알람도 울리지 않고, 전화도 오지 않고, 문자도 오지 않는다. 물론 전화를 걸 수도, 다른 어떤 기능도 사용할 수 없다. 오직 비상전화만 걸 수 있다. 이게 왜 문제냐면 밤에 자동으로 SW업데이트를 걸어놓거나 하면, SW업데이트 후 전원이 꺼졌다 켜지면서 아침에 알람이 울리지 않기 때문이다. 물론 전화도 오지 않으니, 지각은 물론 회사에서 애타게 전화를 해도 전혀 모른채로 꿀잠을 자게 될 수도 있다는 것. 다행히 제조사에서는 이 모드로 설정되어 있는 경우엔 야간 자동 SW업데이트를 하지 않도록 하고 있다.

보안에 도움이 되는 기능이긴 한데, 잘 모르고 사용하면 심각한 상황을 맞을 수 있으니 주의해야겠다. 패스워드를 잊어버리는 경우는 의외로 심심치 않게 자주 발생한다. 더구나 요즘은 지문인식 기능으로 인해 폰을 껐다 켜지 않는 이상 패스워드 입력을 전혀 하지 않고 수일~수주 이상 지나가 버리는 경우가 많아, 이 기능을 설정해 놓고서 까맣게 잊어버리는 경우가 생길 수 있다. 이렇게 패스워드를 잊어버리면 현재로서는 정말로 복구할 방법이 없으니 주의가 필요하다.

3. 원격 잠금

만약 화면잠금이나 휴대폰 전원 켤 때 잠금을 설정하지 않았는데 폰을 잃어버렸다면 어떻게 해야 할까? 일단 당장 시급한 것은 통신사에 연락해 분실 신고하고 번호를 정지시키는 것이다. 이것만으로도 당장 소액결제나 유료전화를 막는 것은 물론, 명의 도용 등의 사고를 막을 수 있다. 그러나 폰에 저장되어 있는 개인정보 유출은 막을 수 없다. 이때 이용 가능한 것이 바로 원격 잠금이다. 원격 잠금을 별도로 제공하는 업체나 통신사업자의 서비스를 이용해도 되지만, 안드로이드 폰이라면 구글에서 기본적으로 제공하므로 이걸 이용하면 된다. 여기에 간략한 설명이 있으니 참고. 당연한 이야기지만, 구글에서 제공하는 서비스이므로 사용하려면 본인의 구글 계정을 알아야 한다. 안타깝게도 우리나라에서 아직도 꽤 많은 사용자가 본인의 구글 계정이 뭔지 모르고 안드로이드 폰을 사용한다. 패스워드를 기억 못하는 경우도 아주 흔하고. 이런 상황이라면 이 기능을 사용하기도 어렵게 된다.

게다가 원격 잠금의 한계는, 단말기가 데이터망이든 와이파이든 접속되어 있어야 한다는 것이다. 서버에서 단말기로 명령을 보내는 것이므로, 단말기가 연결되어 있지 않다면 명령을 보낼 수가 없기 때문이다. 즉 휴대폰 도둑이 명의 도용 등이 목적이 아니라 내 단말기의 개인정보를 빼낼 목적이었다면, 내 폰을 손에 넣은 즉시 비행기모드로 바꾸어 버리면 원격 잠금이 동작하지 않게 된다.

결국 기기 추적이나 잠금, 데이터 삭제 등 원격으로 제어 가능한 방법이 있긴 하지만, 한계가 있으므로 이걸 너무 믿지 말고 평소에 화면잠금을 반드시 걸어두어야 한다. 매번 휴대폰을 쓸 때마다 패스워드를 입력하는 게 귀찮다면 지문인식 기능이 있는 폰을 사도록 하자. 지문의 보안성이 그다지 높지 않다고 하지만, 일상적인 상황에서 내 폰을 보호하는 목적으로는 충분하다.

2017년 11월 10일 금요일

파이썬을 이용한 네이버 카페 업무 자동화

네이버의 영어책 읽기 카페에서 스탭으로 활동하고 있는데, 연말에 회원 레벨 조정 작업을 할 일이 생겼다. 간단한 일이지만 수백명이나 되는 회원에 대해 확인을 수동으로 다 하려니 상당히 지루한 일이 될 것 같아, 자동화를 위해 방법을 찾아보기로 했다.

일단 아래 적은 것들 대부분 인터넷 검색하면 다 나오는 것이므로, 다른 사이트에서 자세히 설명되어 있는 내용을 부가적으로 설명하지는 않고 전체적인 흐름만 기록하고자 한다. 전체적으로 여기의 도움을 많이 받았다.

첫번째로 필요한 것은 파이썬 설치다. 아직 파이썬2를 쓰는 사람도 있지만 특별한 이유가 없다면 가급적 파이썬3를 설치하도록 하자. Windows 피씨에도 무리없이 설치할 수 있고, path도 설정해 주면 cmd 터미널에서 현재 어느 디렉토리에 있든지 쉽게 사용 가능하다.

둘째 웹 자동화에 필수적인 것이 셀레늄(Selenium)이다. 파이썬 모듈로 설치하면 된다. pip install selenium 명령으로 쉽게 설치할 수 있다. 또한 웹페이지를 읽고 처리하려면 Beautiful Soup의 도움이 필요하다. 역시 pip을 써서 pip install bs4 명령으로 쉽게 설치할 수 있다.

세째 셀레늄에서 다룰 수 있는 브라우저 설치다. 크롬 드라이버를 설치하면 된다. 위에서 언급한 블로그에 자세히 나와 있으므로 따라하면 된다.

다 설치되었으면 cmd 창에서 python shell을 띄우고 크롬을 띄워보자. 크롬 브라우저가 새로 뜨면서 "자동화된 테스트 소프트웨어에 의해 제어되고 있습니다"라는 안내창이 보일 것이다. 아래에서 물론 경로는 크롬 드라이버가 깔려 있는 디렉토리명이다.

>>> from selenium import webdriver
>>> driver = webdriver.Chrome('c:/temp/chromedriver')

네째로 알아야 할 것은 브라우저의 개발자 도구다. 이건 별도로 설치할 필요는 없고 크롬 메뉴에서 개발자 도구를 선택하면 된다. 웹페이지에서 특정 리스트 항목이나 버튼의 element나 xpath를 확인하기 위해서는 마우스 오른쪽 버튼을 클릭하고, 맨 아래 "검사(N)" 메뉴를 선택하면 된다. 즉시 오른쪽에 새로운 창이 생기면서 상세한 내용을 보여준다.

이제 본격적으로 네이버를 공략할 차례다. 매일 자동으로 사람 손을 거치지 않고 반복해서 해야 하는 일이 있다면 로긴을 위해 아이디, 패스워드를 자동으로 보낼 수도 있으나, 코드에 하드코딩하는 것은 가급적 피하는 것이 좋다. 나는 아이디까지만 입력된 상태에서 파이썬 코드는 잠시 대기시키고, 패스워드 입력은 수동으로 하는 쪽을 택했다. input()을 이용해 파이썬은 대기시킨 상태에서, 패스워드 입력 후 로긴에 성공하고 나서 cmd 창에서 enter를 눌러 이후 코드를 진행시켜주면 된다.

네이버 카페에서 내가 필요로 하는 작업은 두가지였다. 하나는 관리 메뉴에서 특정 레벨의 회원 명단을 조회하여 아이디 리스트를 얻어오는 것, 둘째는 특정 게시판에서 이 아이디로 각각 검색하여 검색 결과 (게시물의 개수)를 얻어오는 것. 현재는 해당 레벨의 회원 수가 수백명 수준이라 대충 마우스로 긁어다 엑셀에 넣는 방식으로 아이디 리스트를 뽑아내는 것도 가능하겠지만, 만약 수천명이 된다면 그렇게는 불가능할 것이다.

1. 특정 레벨의 아이디 리스트 얻기
네이버 카페 관리 메뉴의 전체 회원 조회 페이지를 보면, 드롭 다운 메뉴로 레벨을 고르고, 또 그 옆의 드롭 다운 메뉴로 한 페이지에 보여지는 회원수를 설정하게 되어 있다. 회원수가 한번에 보여줄 수 있는 숫자를 넘게 되면 하단에 페이지 번호가 표시된다.

드롭 다운 메뉴가 골라진 상태(특정 등급, 한번에 보여주는 회원 수)의 쿼리 URL이 있을 법한데 찾기 어려워, 셀레늄을 이용해 드롭 다운 메뉴를 선택시켰다. 드롭 다운 메뉴를 골라 선택하기 위해서는 브라우저의 개발자 모드를 이용해 element의 id를 찾고, 셀레늄의 Select를 활용해 해당 값을 찾아내어 select하면 된다. (하기 코드 #18~#26 참고)

이제 원하는 명단이 화면에 떴으니, 필요한 정보를 골라 저장하면 된다. Beautiful Soup을 활용하면 다양한 조건에 맞는 element들을 찾아낼 수 있다. 리스트로 뽑아진 결과물에서 내가 필요로 하는 것은 memberid 뿐이므로, 리스트에서 memberid만 추출해 파일에 따로 저장한다.

멤버 명단이 한 페이지가 넘어가면 다음 페이지로 넘겨야 한다. 다행히 총 멤버 수를 명시해 주기 때문에, 해당 멤버수를 근거로 몇번이나 페이지를 넘겨야 할지 알 수 있다. 문제는 1000명이 넘어가면 정확한 숫자가 아니라 "1000이상"으로 출력한다는 것이고, 이 문제는 나중에 따로 생각해 봐야 할 것 같다. 10페이지 단위로 페이지 넘김이 컨트롤되기 때문에 1000명 이상의 임의의 숫자에 잘 대응하는 코드를 작성하려면 좀 고민이 필요해 보인다. 당장 내가 작업해야 하는 등급의 멤버는 400여명 수준이라 이 고민은 일단 생략.

아무튼 페이지 넘기는 버튼은 크롬 개발자 도구에서 xpath를 찾아내어 Selenium으로 클릭해 준다. 여기서 나중에 실행시 이 버튼이 안 찾아진다는 오류 메시지를 만나서 당황했었는데, 알고보니 네이버에서 플래쉬 관련 공지가 해당 버튼을 덮어버려서 생긴 문제였다. 명단 첫 페이지 띄울 때 한번만 뜨기 때문에 나는 그냥 수동으로 닫았는데, 찾아서 자동으로 닫는 걸 시도해도 좋을 듯 하다.

새로운 페이지를 띄울 때마다 Beautiful Soup에 넘기기 전에 살짝 sleep을 주는게 좋다. 안 그러면 덜 완성된 부정확한 정보가 넘어가게 될 수 있다. Selenium Webdriver의 wait을 이용하는 방법과 그냥 간단히 time.sleep()을 이용하는 방법이 있는데 다양하게 테스트해보고 싶었으나 귀찮으므로 일단 2, 3초간 sleep()을 주는 것으로 간단히 해결.

네이버 로긴부터 아이디 수집까지 정리된 코드를 아래 정리했다. 인원수에 따른 반복 처리 및 페이지 넘김 부분은 생략했으니 필요시 추가하면 된다.


2. 찾아진 명단으로 게시판 검색
게시판 검색은 다행히 URL을 이용한 쿼리로 대부분 가능하기 때문에, 앞의 경우처럼 버튼의 xpath를 찾아서 클릭해줘야 할 필요는 없었다. 나는 검색으로 찾아진 게시물의 개수만 필요했기 때문에 (50개가 넘는 경우도 굳이 알 필요 없었기에) 간단하게 끝났지만, 해당 게시물들을 크롤링하며 추가 정보를 찾는 경우나 50개를 넘어서 정확한 게시물의 개수를 다 세어야 하는 경우라면 좀더 복잡한 로직이 필요할 것이다.

쿼리는 아래와 같이 필요한 정보를 넣으면 된다. 기간 정보도 아래처럼 search.searchdate로 포함시킬 수 있다. 검색 버튼을 마우스 우클릭하고 새 탭에서 열기를 누르면 쿼리 URL을 볼 수 있으며, 이 중 불필요한 것은 지우고 필요한 것만 사용하면 된다.

http://cafe.naver.com/카페주소?iframe_url=/ArticleSearchList.nhn%3Fsearch.clubid=클럽아이디%26search.menuid=1280%26search.searchdate=2017-01-012017-12-31%26userDisplay=50%26search.query=검색어

검색으로 나온 게시글 리스트에 접근하려면 먼저 iframe으로 전환해야 한다. 이후 Beautiful Soup select로 원하는 리스트를 찾아서 개수를 저장했다.

아래 정리된 코드는 네이버 로긴 부분은 생략하고, 파일에서 멤버 아이디를 읽어와서 해당 아이디로 검색하고, 해당하는 게시글의 개수를 구해서 저장하는 루틴이다.



결론적으로 네이버 카페도 Selenium과 Beautiful Soup, 그리고 크롬 개발자 도구를 이용해 원하는 작업을 대부분 자동화시킬 수 있을 것으로 보인다. 다만 대부분 iframe 안에서 테이블 리스트 구조로 컨텐츠가 되어 있고 한 화면에 최대로 보여줄 수 있는 리스트의 수가 정해져 있어, 여러 페이지로 결과물이 나오게 될 경우 페이지를 넘겨 가며 작업하는 루틴을 짜는 것이 좀 번거로울 듯 하다.


참고한 글
1. 나만의 웹 크롤러 만들기(3): Selenium으로 무적 크롤러 만들기
2. Django selenium으로 iframe 내부에 접근하기
3. Beautiful Soup 4.4.0 documentation
4. http://selenium-python.readthedocs.io/waits.html
5. 블로그 등에 소스 코드 Snippet 붙여넣기 - GitHub Gist