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

2014년 7월 26일 토요일

스마트폰 잠금 2분 안에 풀린다고?

** 업데이트 **

제작 피디님과 추가적으로 확인한 결과, 제가 아래에서 "화면 잠금 상태에서 쉽게 할 수 없다"고 했던 그 루팅을 학생들이 실제 했다고 합니다. 아래 피디님의 댓글에도 있지만 사전에 USB디버깅 활성화나 루팅이 되어 있지 않은 상태에서 화면을 잠그고 학생들에게 전달했고, 학생들이 이를 풀었다고 합니다. 인터뷰시 제게 보여준 영상은 이미 루팅이 되어 있는 상태에서 패스워드 파일을 지우는 것 뿐이었기 때문에 제가 오해를 했던 것 같습니다.

아직 이 학생들이 구체적으로 어떤 방법으로 루팅에 성공했는지는 파악하지 못했으나, 그것이 가능했다면 이는 매우 심각한 문제가 아닐 수 없습니다. 다만 이러한 형태의 루팅은 대개 특정 제조사의 특정 버전에 존재하는 알려지지 않은 버그를 이용하는 방식이라, 모든 안드로이드폰에 일괄적으로 적용 가능한 것은 아닐 것으로 생각됩니다. 해당 허점이 최신 버전의 안드로이드에서는 이미 개선되어 있을 수도 있으나, 구체적인 정보가 파악되는 대로 문제를 파악해 필요한 조치를 취하도록 하겠습니다.

** 추가 업데이트 **

자체적으로 분석하여 파악한 문제점에 대해 수정 조치하였습니다. 하고 싶은 말은 많으나 이쯤에서 마무리합니다.


-------------------------------------------------------------------------

오늘 KBS 추적60분에서 스마트폰 보안에 대해 다뤘다. 경각심을 불러 일으키기 위한 문제제기는 잘 했다고 본다. 그런데 방송 중간에 화면 잠금을 설정하고 고등학생들을 불러다 2분 안에 풀 수 있다고 하는 장면이 나왔는데, 이 부분은 오해의 소지가 있다. 나도 잠깐 인터뷰에 나왔는데, 약 1시간에 걸친 인터뷰 중 10초만 잘라서 나간거라 충분히 설명이 되지 않은 부분이 많다. 이번 기회에 스마트폰, 특히 안드로이드 스마트폰 보안에 대해 간략히 정리해 볼까 한다. 단 아래 내용은 LG전자의 공식 입장과는 무관한, 내 개인적인 견해임을 먼저 밝혀두고자 한다.

1. 방송에 나오지 않은 장면

방송 중 화면 잠금을 푸는 장면에서, 원래 영상에는 구체적으로 adb를 이용해서 잠금을 푸는 컴퓨터 화면이 등장했었다. 여기서 잠깐 adb에 대해 간략하게 설명하자면, 안드로이드 개발자를 위한 도구다. 커맨드를 입력할 수 있고 리눅스 쉘도 띄울 수 있다. 쉽게 말해 윈도우로 치면 도스 커맨드창 같은 그런 역할을 하는 거다. 그런데 학생들이 사용하는 adb shell의 프롬프트가 #로 되어 있었다. 이게 무슨 소리야 하는 분들을 위해 설명하자면, 해당 단말은 이미 루팅이 되어 있는 상태라는 것이다. 방송에서 "어떻게 풀었는지?" 인터뷰하는 장면이 나오는데 학생은 "비밀번호가 설정된 파일을 지웠다."고 설명한다. 실제 adb 동작하는 화면을 안 봤더라도 여기서 쉽게 유추할 수 있는데, 이 비밀번호를 저장하고 있는 파일은 루트 (관리자) 권한으로만 접근할 수 있다. 즉 일반 사용자 권한으로는 해당 파일을 삭제할 수 없고, 당연히 잠금도 풀 수 없다.

2. 정말 그렇게 쉽게 단말의 잠금을 풀 수 있나?

모든 안드로이드 폰이 방송에 나온 것처럼 "고등학생들도 아무나 인터넷에서 툴을 다운받아서 2분안에" 쉽게 풀리는 것이 아니다. 몇가지 이유가 있다.
  • adb 연결이 불가능하다 - 방송에서 내 인터뷰가 나간 장면인데, 긴 인터뷰 중 그 부분만 전후 설명없이 나가서, 뜬금없이 USB디버깅이 어쩌고 하는 것이 시청자 입장에서는 무슨 소리인가 했을 가능성이 높다. 쉽게 말하자면, 일반적인 소비자가 쓰고 있는 폰은 USB 케이블을 통해 컴퓨터와 연결해도, adb 실행을 시킬 수 없다. 설정 메뉴에서 "USB디버깅 허용"을 미리 활성화해야 adb 연결이 되기 때문이다. 이걸 사전에 미리 활성화해 놓지 않았다면, 화면이 잠겨 있는 상태에서는 활성화할 수 없다. 더구나 최신 안드로이드 버전에서는, 설령 해당 메뉴가 활성화되어 있다 하더라도, 컴퓨터에서 adb 접속 시도시 폰에서 허용 여부를 묻는 확인 팝업이 뜨게 되어 있다. 화면 잠김 상태에서는 이를 허용하게 할 수 없다.
  • 루팅되지 않은 단말은 잠금화면 초기화가 되지 않는다 - 방송에서는 패턴락이나 PIN, 패스워드를 저장하고 있는 파일을 지워버려서 초기화시킨 것인데, 루팅되지 않은 단말은 그렇게 되지 않는다. 설령 컴퓨터와 adb 연결이 되었다 하더라도, 파일 삭제를 시도해도 파일이 삭제되지 않는다. 권한이 없다는 에러 메시지만 뜬다.
  • 루팅을 쉽게 할 수 없다 - 앞에서 말한대로 방송에 사용된 폰은 사전에 루팅이 되어 있는 상태였다. 그럼 루팅이 안되어 있던 단말을 누군가 루팅할 수는 없을까? 루팅은 비교적 쉽게 할 수 있다고 알려져 있지만, 인터넷에 알려진 대부분의 루팅 방법은 사용자가 자기 폰에 대한 완전한 지배권을 이미 갖고 있는 상태를 가정한 것이다. 화면이 잠겨 있으면 이중 대부분이 무용지물이다. 물론 100% 불가능하다고 말하지는 않겠다. 원래 보안이란게 그렇다. 하지만, 절대 그렇게 쉽게 루팅이 되지는 않는다.

3. 안드로이드 폰을 안전하게 쓰려면?

솔직히 안드로이드 폰은 약간은 기술적인 지식이 있는 사용자를 대상으로 설계된 측면이 강하다. 따라서 많은 부분을 사용자의 선택에 맡겨 두고 있다. 아이폰에서는 탈옥이라는 방법을 통하지 않고는 할 수 없는 임의의 앱 설치 (애플 앱스토어를 통하지 않은 앱 설치)가 간단한 메뉴 설정 하나로 허용되는 것만 봐도, 컨셉 자체가 다르다는 것을 알 수 있다. 따라서 안드로이드 폰을 안전하게 사용하려면 최소한의 관심과 지식이 필요한 것이 사실이다. 대략 아래에 나와 있는 사항들만 잘 지켜도 큰 위험 없이 안드로이드를 사용할 수 있을 것이다.
  • 화면 잠금 반드시 설정할 것 : 이건 안드로이드와도 관계 없고, 어떤 스마트폰이든 반드시 해야 하는 일이다. 잠겨 있지 않은 폰을 잠시라도 다른 사람의 손에 들어갈 수 있게 허용하는 건 내 목숨을 다른 사람에게 내맡기는 격이다.
  • 루팅하지 말 것. 최소한 루팅 상태로 두지 말 것 : 이런 저런 목적에 의해서 루팅을 할 수도 있다. "내 소유 기기의 관리자 권한을 내가 갖겠다는 데 왜 막냐"고 하면 할 말 없다. 그러나 적어도 루팅을 하려면 기술적으로 자기가 무엇을 하고 있는지 정확히 알아야 하고 그에 따른 위험도 인지해야 한다. 루팅한 단말은 제조사에서 무상수리도 받을 수 없다. 그리고 만약 루팅을 했다면, 원하던 루팅의 목적을 달성했으면 다시 일반 사용자 모드로 돌려놓기 바란다. 항상 루팅 상태로 쓰는 것은 폰을 위험에 상시 노출시키는 것이다.
  • USB디버깅 허용하지 말 것 : 이건 사실 무슨 말인지 모르면 허용 안되어 있는 것이다. 이걸 허용하려면 설정 메뉴의 개발자 옵션에 들어가야 하는데, 최근 안드로이드 버전은 이 개발자 옵션 자체가 숨겨져 있다. 개발자라서 필요하다면, 어떤 이유로든 허용했다면, 평소에는 다시 비활성화해 놓고 다니기 바란다.
  • 알 수 없는 출처 앱 설치 허용하지 말 것 : 앞의 항목들이 물리적으로 폰을 잃어버리는 상황을 대비한 거라면, 이 항목은 내가 갖고 있어도 해킹당할 수 있다는 가능성에 대비하는 것이다. 이 옵션은 사실 완전히 없애버렸으면 좋겠는데, 황당하게도 은행 앱이나 회사에서 보안을 필요로 하는 앱을 설치하려면 이 설정을 허용으로 바꿔야 하는 경우가 많다. 꼭 필요한 앱에 한해, 출처를 100% 확신하는 경우에만 허용하자. 그리고 원하는 앱 설치가 끝났으면 반드시 다시 설정 메뉴에 들어가 이 설정을 해제해야 한다. 이게 허용으로 되어 있으면, 이상한 URL 클릭하면 바로 설치가 되어 버린다. 그 순간 이미 게임 끝난 거다.
  • 이상한 URL 클릭하지 말 것 : 해킹 앱을 설치하는 URL은 물론이고, 브라우저의 버그를 이용하는 해킹 사이트로 유도하거나, 사용자의 정보를 캐내기 위한 피싱 사이트로 유도할 수도 있다. 아무튼 잘 아는 지인이 대화를 주고받다가 보내주는 URL이 아닌 이상, 뜬금없이 URL만 달랑 오는 경우 십중팔구 그 지인도 해킹을 당해서 URL을 뿌리고 있는 거라고 보는 게 맞다. 클릭하기 전에 먼저 지인에게 무슨 내용인지 확인하는 건 필수다.
  • SW는 최신으로 유지할 것 : 구글에서는 보안 관련 위험성이 발견되면 지속적으로 패치를 내놓고 있다. 제조사에서는 이러한 구글의 패치와 자체적으로 발견한 문제점 패치들을 SW 업데이트에 포함시켜서 릴리즈한다. 비록 SW업데이트 설명에는 포함되지 않는 경우가 대부분이지만, 매 SW 업데이트는 이러한 다양한 보안 패치들을 포함하고 있으니 꼬박꼬박 최신 SW로 업데이트하도록 하자.
  • 중요한 정보 폰에 저장하지 말 것 : 주민등록증, 보안카드 등을 촬영해 저장한다거나, 공인인증서를 폰에 저장한다거나, 이런 일들은 가급적 안하는 게 좋다. 위에서 이야기한 걸 다 지키고 만반의 대비를 하더라도 만에 하나 그런 것들이 다 뚫려버렸을 때, 피해를 최소화하기 위해서다. 
  • 추가 보안 장치들
    • 킬 스위치 - 분실/도난시 원격으로 폰을 잠궈버려 USB연결은 물론 리커버리 모드나 강제 공장초기화도 불가능하게 만드는 것이다. 이렇게 잠기게 되면 잠김을 푸는 것 뿐 아니라, 중고로 파는 것도 불가능하다. G3를 비롯해 최신 폰들은 이런 서비스를 제공하고 있으니 확인해 볼 것. 단, 이것만 믿고 화면잠금도 설정 안한다거나 하면 곤란하다. 잃어버린 후 잠그기 전까지는 무방비 상태이고, 이 상황에서 폰을 끄거나 통신이 안되는 지하실로 가져가거나 한다면 원격으로 잠그는 명령이 폰에 도달하지 못하기 때문에 잠기지 않기 때문이다.
    • USIM 비밀번호(PIN) - 분실/도난시 폰은 안전하게 잘 잠겨 있더라도, USIM을 빼서 다른 기기에 옮겨 꽂으면 번호는 그대로 사용이 가능하다. 통신사에 분실정지를 시키기 전까지는 소액결재나 정보이용료, 본인인증에 따른 명의 도용까지 다양한 문제가 발생할 수 있다. 즉시 분실정지를 시키면 되지만 분실된 사실을 뒤늦게 알게 되는 경우 피해를 입을 수 있다. 이런 피해를 막으려면 USIM에 비밀번호를 설정하면 된다. USIM 비밀번호는 네자리로 아주 강한 비밀번호는 아니지만, 세번 연속 실패하면 더이상 시도할 수 없게 잠겨버리기 때문에 안전하다고 할 수 있다.
    • 데이터 암호화 - 요즘 안드로이드 폰은 데이터를 암호화할 수 있는 기능을 제공한다. 암호화된 데이터는 본인이 설정한 비밀번호로 풀지 않는 이상 해독해 낼 수 없다. 따라서 폰을 잃어버리더라도, 데이터가 유출될 위험으로부터는 안전하다. 다만 비밀번호를 잊어버리면 데이터를 살릴 방법은 없으니 (서비스센터에서도 불가) 주의하자.
혹시 잘못된 점이나 궁금한 점이 있으면 코멘트 남겨 주시길...

2013년 12월 5일 목요일

국립국어원의 일방적 대화 단절

오랜 기간에 걸친 국립국어원과의 문답이 끝이 났습니다. 국립국어원의 결론은, "규정이고 뭐고 국립국어원 맘대로 '새너제이'라고 쓰는 게 맞고, 더이상 할 말 없다"입니다. 아래 문답을 모아놨으니 국립국어원의 답변을 직접 보시고 싶은 분은 참고하시기 바랍니다.

San Jose 표기법 관련 국립국어원과의 문답 모음


간단하게 제 주장을 아래에 다시 요약하고 마무리하겠습니다. 누가 맞고 누가 억지를 부리고 있는지, 글을 읽는 분들이 판단해 주시기 바랍니다.

1. '새너제이' 표기는 외래어 표기 규정을 위배하고 있다. 

San Jose는 두 단어로 이루어진 지명이므로, 해당 외래어 표기 규정에 따라 단독으로 쓰일 때의 표기대로 적어야 한다. (외래어 표기 규정 제3장 제1절 제10항)

제10항복합어(3)

1. 따로 설 수 있는 말의 합성으로 이루어진 복합어는 그것을 구성하고 있는 말이 단독으로 쓰일 때의 표기대로 적는다.

  • cuplike[kʌplaik] 컵라이크
  • bookend[bukend] 북엔드
  • headlight[hedlait] 헤드라이트
  • touchwood[tʌtʃwud] 터치우드
  • sit-in[sitin] 싯인
  • bookmaker[bukmeikə] 북메이커
  • flashgun[flæʃgʌn] 플래시건
  • topknot[tɔpnɔt] 톱놋

2. 원어에서 띄어 쓴 말은 띄어 쓴 대로 한글 표기를 하되, 붙여 쓸 수도 있다.

  • Los Alamos[lɔs æləmous] 로스 앨러모스/로스앨러모스
  • top class[tɔpklæs] 톱 클래스/톱클래스

San은 '샌', Jose은 '호세' 혹은 '호제이'로 적을 수 있으므로, San Jose는 '샌호세' 혹은 '샌호제이'로 적어야 한다. 그렇지 않으면 위 10항의 2를 따를 방법이 없다. '새너제이'를 원어에서 띄어 쓴 대로 한글 표기를 하려면 도대체 어떻게 해야 하는가? '새 너제이'? '새너 제이'? 따라서 위 표기 원칙을 위배하고 San Jose를 붙여서 연음 처리한 '새너제이'라는 표기는 틀렸다. 새너제이라는 발음이 맞다면, 맞는 표기법은 '새너제이'가 아니라 '샌어제이'다. 물론 Jose를 '어제이'라고 적는다는 가정하에.

2. San Jose의 발음은 '새너제이'가 아니다.

원어민이 water를 '워러'에 가깝게 발음한다고 해서 한국어로 '워러'로 적지는 않는다. 한글 표기법은 흘려서 내는 발음이 아니라, 또박또박 읽을 때의 원래 발음을 기준으로 해야 하는 것이다. 귀에 들리는 발음이 아니라 발음기호를 기준으로 해야 한다는 것이다.

국립국어원은 롱맨 발음 사전에 [sӕnəzéi]로 되어 있고, 그걸 따랐다고 주장한다. 그러나 온라인 롱맨 사전에는 /ˌsæn hoʊˈzeɪ/로 되어 있고, 위키피디아에도 /ˌsæn hoʊˈzeɪ/로 발음을 표시하고 있다. 둘 중 어느 발음이 맞는 발음인지 논란이 있다면, 온라인이든 오프라인이든 가능한 많은 사전을 조사하여 주 발음이 무엇인지 확인하는 것이 순리이다. 그리고 [sӕnəzéi]는 /ˌsæn hoʊˈzeɪ/를 흘려서 발음한 것이라 설명이 가능하므로, /ˌsæn hoʊˈzeɪ/를 기준 발음으로 삼는 것이 논리적이기도 하다.

사전을 떠나 실제 발음은 구글에서 "how to pronounce san jose?"로 검색해 보면 아주 쉽게 확인할 수 있다. 모두가 "샌호제" 혹은 "샌호제이"에 가깝게 발음하고 있고, "새너제이"처럼 들리지 않는다는 것을 알 수 있다.


이제 제가 더이상 국립국어원을 상대로 할 수 있는 일은 없는 것 같습니다. 개인적으로 피해 본 일이 없으니 행정소송을 할 수도 없고... 똥고집을 부리겠다는데 말릴 방법이 없네요. 아마 저를 귀찮은 똥파리 정도로 여기고 있는지도 모르지요. 저는 일단 여기까지 하렵니다. 뭐 사실 그렇게 중요한 일도 아니구요. 좀 보기 싫을 뿐, 새너제이라고 쓴다고 큰 문제가 생기는 것도 아니죠. ^^ 논리적인 설득을 통해 의도했던 결과를 얻지 못해서 아쉽지만, 뭐 언젠가는 바뀌지 않겠습니까?

2013년 11월 6일 수요일

체계적인 미루기 - 미루기쟁이가 많은 성과를 내는 방법

오늘 우연히 이 글을 읽게 되었는데, 나와 너무나 잘 맞아 떨어지는 내용이라 전문을 번역해 볼까 한다. 저자가 이 내용으로 책도 냈고, 찾아보니 이미 한국에 번역서도 나와 있다.

원문은 여기: http://www.structuredprocrastination.com/

Structured Procrastination
체계적인 미루기

``. . . anyone can do any amount of work, provided it isn't the work he is supposed to be doing at that moment." -- Robert Benchley, in Chips off the Old Benchley, 1949
"누구나 얼마든지 많은 일을 해낼 수 있다. 그게 그 순간에 그가 해야만 하는 일이 아니라면 말이다."

I have been intending to write this essay for months. Why am I finally doing it? Because I finally found some uncommitted time? Wrong. I have papers to grade, textbook orders to fill out, an NSF proposal to referee, dissertation drafts to read. I am working on this essay as a way of not doing all of those things. This is the essence of what I call structured procrastination, an amazing strategy I have discovered that converts procrastinators into effective human beings, respected and admired for all that they can accomplish and the good use they make of time. All procrastinators put off things they have to do. Structured procrastination is the art of making this bad trait work for you. The key idea is that procrastinating does not mean doing absolutely nothing. Procrastinators seldom do absolutely nothing; they do marginally useful things, like gardening or sharpening pencils or making a diagram of how they will reorganize their files when they get around to it. Why does the procrastinator do these things? Because they are a way of not doing something more important. If all the procrastinator had left to do was to sharpen some pencils, no force on earth could get him do it. However, the procrastinator can be motivated to do difficult, timely and important tasks, as long as these tasks are a way of not doing something more important.
나는 몇달간 이 에세이를 쓰려고 했었다. 어떻게 지금 마침내 이걸 쓰고 있을까? 마침내 한가한 시간을 찾았기 때문에? 틀렸다. 점수를 매겨야 하는 과제들, 주문해야 하는 교과서 목록, 심사해야 하는 NSF 제안서, 읽어야 하는 학위논문 초안들이 쌓여 있다. 나는 이 에세이를, 이런 모든 일들을 하지 않기 위해서 쓰고 있는 중이다. 이것이 바로 내가 "체계적인 미루기"라고 부르는, 미루기를 좋아하는 사람을 많은 일을 성취하며 오히려 시간을 효과적으로 쓴다고 존경과 찬사를 받는 사람으로 바꿔놓는 놀라운 전략의 핵심이다. 모든 미루기쟁이들은 해야만 하는 일들을 뒤로 미룬다. 체계적인 미루기는 이러한 나쁜 버릇을 유용하게 활용하는 기술이다. 핵심 아이디어는, 미룬다는 것이 아무것도 안하는 것을 의미하는 건 아니라는 것이다. 정말 아무것도 하지 않는 경우는 거의 없다. 대개 그들은 어느정도 쓸모있는 일들, 예를 들어 정원을 손질한다든지 연필을 깎는 일, 혹은 파일을 재정렬하기 위해 다이어그램을 그린다든지 하는 일들을 한다. 이들이 왜 이런 일을 할까? 그건 그 일들이 더 중요한 일을 하지 않기 위한 방법이기 때문이다. 만약 미루기쟁이들이 해야 할 일이 순전히 연필을 깎는 일밖에 없다면, 이들은 절대로 그 일을 하지 않을 것이다. 하지만, 미루기쟁이들은 더 중요한 일을 피하기 위해서라면, 어렵고, 급하고 중요한 일들도 하도록 동기부여될 수 있다.

Structured procrastination means shaping the structure of the tasks one has to do in a way that exploits this fact. The list of tasks one has in mind will be ordered by importance. Tasks that seem most urgent and important are on top. But there are also worthwhile tasks to perform lower down on the list. Doing these tasks becomes a way of not doing the things higher up on the list. With this sort of appropriate task structure, the procrastinator becomes a useful citizen. Indeed, the procrastinator can even acquire, as I have, a reputation for getting a lot done.
체계적인 미루기는 이러한 사실을 활용할 수 있는 방식으로, 해야 할 일들을 체계화하는 것이다. 할 일의 목록은 머리 속에서 중요도에 따라 정렬될 것이다. 가장 급하고 중요해 보이는 것이 맨 위에 위치한다. 하지만 어느 정도 가치있는 일들도 목록 중간 어디쯤엔가 있을 것이다. 이러한 일들을 하는 것은 목록의 더 위에 있는 일들을 하지 않을 수 있는 방법이 된다. 이런 식으로 적절히 할 일을 체계화한다면, 미루기쟁이들도 가치있는 시민이 될 수 있다. 사실, 미루기쟁이도 내가 그런 것처럼, 오히려 많은 일을 해낸다는 평판을 얻을 수 있다.

The most perfect situation for structured procrastination that I ever had was when my wife and I served as Resident Fellows in Soto House, a Stanford dormitory. In the evening, faced with papers to grade, lectures to prepare, committee work to be done, I would leave our cottage next to the dorm and go over to the lounge and play ping-pong with the residents, or talk over things with them in their rooms, or just sit there and read the paper. I got a reputation for being a terrific Resident Fellow, and one of the rare profs on campus who spent time with undergraduates and got to know them. What a set up: play ping pong as a way of not doing more important things, and get a reputation as Mr. Chips.
내가 경험했던 가장 이상적인, 체계적인 미루기의 상황은 아내와 내가 스탠퍼드 기숙사의 사감교수로 일했을 때였다. 과제 채점, 강의 준비, 위원회 활동 등이 밀려 있는 저녁에, 나는 집을 나와 라운지로 가서 학생들과 탁구를 치거나 그들의 방에서 이야기를 나누거나, 아니면 그냥 거기 앉아서 뭘 읽곤 했다. 덕분에 나는 끝내주는 사감 교수, 학부생들과 시간을 보내고 그들을 이해하는 몇 안되는 교수라는 평판을 얻었다. 멋진 설정 아닌가. 중요한 일을 하지 않기 위해 탁구를 치고, 미스터 칩스 (Mr. Chips - "Goodbye, Mr. Chips"라는 단편소설의 주인공으로 학생들로부터 사랑받는 교사) 라는 평판을 얻다니 말이다.

Procrastinators often follow exactly the wrong tack. They try to minimize their commitments, assuming that if they have only a few things to do, they will quit procrastinating and get them done. But this goes contrary to the basic nature of the procrastinator and destroys his most important source of motivation. The few tasks on his list will be by definition the most important, and the only way to avoid doing them will be to do nothing. This is a way to become a couch potato, not an effective human being.
미루기쟁이들은 종종 완전히 틀린 길을 따라간다. 해야 할 일이 적다면 그들의 미루는 버릇을 끝내고 일을 마칠 수 있을 거라 생각해, 가급적 해야 할 일을 최소화하려 든다. 하지만 이렇게 되면 그들의 미루는 본성과 반대로 가게 되어, 그들의 가장 중요한 동기부여의 근원을 잃게 된다. 할 일 목록에 가장 중요한 일들만 남게 되면, 그것들을 피하는 유일한 방법은 아무것도 하지 않는 것이다. 이것은 소파에서만 뒹굴거리는, 비생산적인 사람이 되는 길이다.

At this point you may be asking, "How about the important tasks at the top of the list, that one never does?" Admittedly, there is a potential problem here.
이 시점에서 아마 이런 의문이 들 것이다. "그럼 목록의 가장 위에 있는, 가장 중요한 일은 영원히 못하게 되는 것 아닌가요?" 그렇다. 사실 여기에는 잠재적인 문제가 있다.

The trick is to pick the right sorts of projects for the top of the list. The ideal sorts of things have two characteristics, First, they seem to have clear deadlines (but really don't). Second, they seem awfully important (but really aren't). Luckily, life abounds with such tasks. In universities the vast majority of tasks fall into this category, and I'm sure the same is true for most other large institutions. Take for example the item right at the top of my list right now. This is finishing an essay for a volume in the philosophy of language. It was supposed to be done eleven months ago. I have accomplished an enormous number of important things as a way of not working on it. A couple of months ago, bothered by guilt, I wrote a letter to the editor saying how sorry I was to be so late and expressing my good intentions to get to work. Writing the letter was, of course, a way of not working on the article. It turned out that I really wasn't much further behind schedule than anyone else. And how important is this article anyway? Not so important that at some point something that seems more important won't come along. Then I'll get to work on it.
해결책은 올바른 종류의 일들을 목록의 첫머리에 놓는 것이다. 여기에 딱 들어맞는 일은 두가지 특징을 갖고 있다. 첫째, 그것들은 명확한 데드라인을 갖고 있는 것처럼 보여야 한다. (사실상은 그렇지 않다.) 둘째, 아주아주 중요한 것처럼 보여야 한다. (사실은 그렇지 않다.) 다행히도, 인생은 그런 일들로 가득하다. 대학교에서는 대부분의 업무가 이 범주에 해당되며, 아마도 대부분의 다른 기관들도 동일하리라 믿는다. 지금 내 목록의 맨 위에 있는 것을 예로 들어보자. 언어철학 분야의 출판물을 위한 에세이를 끝내는 것이다. 이것은 11개월 전에 끝냈어야 하는 일이다. 나는 이것을 하지 않기 위해, 그동안 어머어마하게 많은 중요한 일들을 해냈다. 두어달 전에 나는 죄책감에 괴로워하며, 편집자에게 내가 마감을 지키지 못해 얼마나 미안해 하고 있는지, 그리고 이 일을 얼마나 하고 싶어하는지 적은 편지를 보냈다. 편지를 쓴 것 역시, 물론 에세이를 쓰지 않기 위해서였다. 알고보니 사실, 다른 사람들도 역시 다들 마감을 지키지 않고 있었던 것으로 밝혀졌다. 그리고 이 에세이가 사실 얼마나 중요하겠는가? 어느 시점엔 더 중요한 일이 생길 테고, 그 때가 되면 난 이걸 쓰기 시작할 것이다.

Another example is book order forms. I write this in June. In October, I will teach a class on Epistemology. The book order forms are already overdue at the book store. It is easy to take this as an important task with a pressing deadline (for you non-procrastinators, I will observe that deadlines really start to press a week or two after they pass.) I get almost daily reminders from the department secretary, students sometimes ask me what we will be reading, and the unfilled order form sits right in the middle of my desk, right under the wrapping from the sandwich I ate last Wednesday. This task is near the top of my list; it bothers me, and motivates me to do other useful but superficially less important things. But in fact, the book store is plenty busy with forms already filed by non-procrastinators. I can get mine in mid-Summer and things will be fine. I just need to order popular well-known books from efficient publishers. I will accept some other, apparently more important, task sometime between now and, say, August 1st. Then my psyche will feel comfortable about filling out the order forms as a way of not doing this new task.
또다른 예는 책 주문서다. 지금은 6월이고, 나는 10월에 인식론에 대한 수업을 할 예정이다. 이 책 주문서는 이미 서점의 시한을 넘겼다. 데드라인에 대한 압박 때문에, 이 일은 쉽게 중요한 것으로 여겨지게 된다. (미루기쟁이가 아닌 분들을 위해, 나는 진짜 데드라인의 압박은 시한을 한두 주 넘긴 이후에 시작된다고 본다.) 나는 거의 매일 학과 비서로부터 독촉을 받고 있고, 학생들은 종종 무슨 책을 읽어야 할지 물어보고, 빈 주문서는 내 책상 한 가운데, 정확히 어제 내가 먹은 샌드위치 포장지 아래에 놓여 있다. 이 일은 내 할 일 목록 거의 최상위에 위치해 있고, 나를 불편하게 하며, 이걸 피하기 위해 다른 유용하고 겉으로 덜 중요해 보이는 다른 일을 하도록 나를 동기부여시킨다. 하지만 사실상, 서점은 이미 미루기쟁이가 아닌 다른 사람들이 보낸 주문서로 충분히 바쁘다. 나는 한여름에 책을 받을 수 있고 그러면 문제 없을 것이다. 단지 효율적인 출판사에서 나온 인기있는 유명한 책을 주문하면 된다. 나는 아마 지금부터 8월 1일 정도 사이에, 명백히 더 중요한 다른 어떤 일들을 하기로 약속할 것이다. 그때쯤엔 아마 내 심리가, 이 새로운 일을 하지 않기 위한 방법으로, 주문서를 쓰는 것에 대해 편안함을 느끼게 될 것이다.

The observant reader may feel at this point that structured procrastination requires a certain amount of self-deception, since one is in effect constantly perpetrating a pyramid scheme on oneself. Exactly. One needs to be able to recognize and commit oneself to tasks with inflated importance and unreal deadlines, while making oneself feel that they are important and urgent. This is not a problem, because virtually all procrastinators have excellent self-deceptive skills also. And what could be more noble than using one character flaw to offset the bad effects of another?
주의 깊은 독자라면 이 시점에서 아마 체계적인 미루기를 위해서는 스스로를 속여야 한다고 느낄 것이다. 사실상 자기 스스로에 대해 계속해서 피라미드 사기를 치는 것이기 때문이다. 정확하다. 어떤 일들에 대해 한편으로는 그것들이 정말 중요하고 급하다고 스스로 믿게 만들면서, 또한 과장된 중요도와 사실이 아닌 데드라인을 감지하고 받아들여야 한다. 이건 문제될 게 없다. 왜냐하면 거의 모든 미루기쟁이들은 자기를 속이는 데도 탁월하기 때문이다. 그리고 하나의 성격상 결함을 다른 결함의 나쁜 결과를 상쇄하기 위해 사용하는 것보다 더 고귀한 일이 무엇이겠는가?


이 글의 저자와 같이 명확히 짚어내지는 못했지만, 나도 사실상 지금까지 해 온 일들을 보면, 마감시간에 쫓겨 어쩔 수 없이 해야 하는 일들을 울면서(?) 했던 경우도 있지만, 오히려 그렇게 해야만 하는 일들을 피하기 위한 방법으로 다른 많은 일들을 했던 것 같다. 사실상 이 글을 쓰고 있는 자체가, 더 중요한 일들, 예를 들어 테크니들에 글 쓰는 걸 피하기 위해서이다. 정말 중요한 일부터 차례대로 순서대로 하라는 일반적인 성공방정식(?)과는 다른 방향이지만, 정말 체계적으로 잘 활용할 경우 나와 같은 미루기쟁이들에게 정말 유용한 방법이 될 것 같다. 앞으로 잘 써먹어야겠다.

2013년 9월 24일 화요일

California Dreaming 가사와 해석

일하며 흘러간 팝송을 듣는데 California Dreaming이란 노래가 나왔다. 마침 오늘 날씨도 캘리포니아가 생각나는 날이라 기분좋게 듣고 있는데 가사가 잘 이해가 안되는 거다. 사실 가사를 주의해서 들어본 적이 없었다. 교회가 어쩌고 기도가 어쩌고 하는데 그런 가사가 있는 줄은 전혀 알지도 못했다. 아마 어릴 때 내 듣기 실력이 워낙 안좋았기 때문이겠지만. 그래서 가사를 찾아봤다.

All the leaves are brown and the sky is gray
I've been for a walk on a winter's day
I'd be safe and warm if I was in L.A.
California dreamin' on such a winter's day

Stopped in to a church I passed along the way
Well I got down on my knees and I pretend to pray
You know the preacher liked the cold
He knows I'm gonna stay
California dreamin' on such a winter's day

All the leaves are brown and the sky is gray
I've been for a walk on a winter's day
If I didn't tell her I could leave today
California dreamin' on such a winter's day
California dreamin' on such a winter's day
California dreamin' on such a winter's day

추운 날 따뜻한 캘리포니아를 그리워하는 내용인 줄은 대충 알겠는데 군데군데 무슨 말인지 도무지 이해가 안되는 거다. 특히 중간에 "You know the preacher liked the cold. He knows I'm gonna stay" 이 부분과 마지막에 "If I didn't tell her I could leave today" 부분이 문맥상도 그렇고 무슨 뜻인지 감을 잡을 수가 없었다. 목사님이 왜 추위를 좋아하는 건가? 그가 내가 머무를 거라는 걸 안다는 건 또 뭔가? 그리고 그녀는 누구고 어딜 떠난다는 건가?

구글과 네이버에서 한글 해석을 검색해 봤지만 대부분 그냥 가사 그대로 번역을 해 놓았을 뿐 (오역을 포함해서) 그게 무슨 뜻인지 고민해 가며 번역하거나 해설한 글은 찾기 어려웠다.

다시 구글에서 영어로 가사를 풀어 해석해 놓은 곳이 있는지 찾아본 결과, 여기에서 만족할 만한 답변을 찾았기에 아래에 옮겨 본다. 그리고 내 해석도 덧붙인다.

>All the leaves are brown and the sky is gray     잎들은 모두 갈색이고 하늘은 회색이네
>I've been for a walk on a winter's day                나는 겨울날에 걸어가는 중이지
>I'd be safe and warm if I was in L.A.                 LA에 있었더라면 안전하고 따뜻했을텐데
>California dreamin' on such a winter's day         이런 겨울날 캘리포니아를 꿈꾸네

[I was out walking on a gloomy winter day]
나는 우울한 겨울날 밖에서 걷고 있는 중이었다.
[I realized if I was in sunny LA I'd be warm and comfortable] 
만약 화창한 LA에 있었더라면 따뜻하고 편안했을 거란 걸 깨달았다.

>Stopped in to a church I passed along the way  지나는 길에 있는 교회에 들렸지
>Well I got down on my knees and I pretend to pray 무릎을 꿇고 기도하는 척 하지
>You know the preacher liked the cold                목사님은 그 추운 날씨를 좋아했지
>He knows I'm gonna stay                                 내가 머무를 거라는 걸 알거든
>California dreamin' on such a winter's day          이런 겨울날 캘리포니아를 꿈꾸네

[To get out of the cold, I stopped in a church and knelt pretended to pray.]
추위를 피하려고, 나는 한 교회로 들어가서 무릎을 꿇고 기도하는 척 했다.
[The pastor is pleased that the cold weather is draws people into his church.] 
목사님은 추운 날씨가 사람들을 그의 교회로 들어오게 만들기 때문에 기뻤다.

>All the leaves are brown and the sky is gray     잎들은 모두 갈색이고 하늘은 회색이네
>I've been for a walk on a winter's day                나는 겨울날에 걸어가는 중이지
>If I didn't tell her I could leave today                  그녀에게 말하지만 않는다면 오늘이라도 떠날 수 있을텐데
>California dreamin' on such a winter's day         이런 겨울날 캘리포니아를 꿈꾸네
>California dreamin' on such a winter's day         이런 겨울날 캘리포니아를 꿈꾸네
>California dreamin' on such a winter's day         이런 겨울날 캘리포니아를 꿈꾸네

[I was out walking on a gloomy winter day thinking of sunny LA]
나는 우울한 겨울날 화창한 LA를 생각하며 밖에서 걷고 있는 중이었다.
[I knew I could just pull up stakes and leave for LA today, but if I told my S.O. she wouldn't let me go]
나는 오늘이라도 짐을 꾸려서 LA로 떠날 수 있다는 걸 안다. 하지만 내 반려자(S.O. = Significant Other)에게 말한다면 그녀는 나를 보내주지 않을 것이다.
[But I kept thinking of sunny LA on that gloomy winter day]
하지만 나는 우울한 겨울날 계속해서 화창한 LA를 생각했다.

갑자기 교회에 왜 들어가서 기도하는 척 하는지, 목사님이 추위를 왜 좋아하는지는 명확하게 이해가 됐지만, 여전히 좀 애매한 부분은 "If I didn't tell her I could leave today"의 해석이다. 일단, 과거형을 썼으므로 과거의 사실에 대한 이야기인 것 같지만, 가정법에서 과거형은 과거 사실의 반대를 가정하는 게 아니라 현재 사실의 반대를 가정하는 용법이다. 과거 사실의 반대, 즉 "만약 내가 그녀에게 말하지만 않았더라면"이란 뜻이라면 과거 분사를 써서 "If I hadn't told her"라고 해야 한다. 반대로 "만약 내가 그녀에게 말하지 않는다면"이라면 미래에 일어날 일을 가정하는 것이므로 현재형으로 "If I don't tell her"라고 해야 한다. 그럼 "If I didn't tell her"는 어떻게 해석해야 하는 걸까?

첫번째 가능성은 노래 가사에서 문법은 무시하고, 그냥 과거 사실을 반대로 가정하는 표현을 그렇게 썼다고 보는 것이다. 이 경우 그녀에게 이미 말을 했고, 그것 때문에 떠나지 못하는 것이 된다. 그녀에게 사랑의 고백이나 결혼하자는 프로포즈나 아무튼 무엇인가 중요한 책임질 말을 했고, 그것 때문에 떠나지 못하는 것일 수도 있고, LA에 가겠다고 말했는데 그녀가 완강하게 반대했기 때문에 못 가는 것일 수도 있다.

두번째 가능성은 일어날 가능성이 없는 일이므로 과거형을 썼다고 보는 것이다. 즉 내가 그녀에게 말할 것이고 말할 수밖에 없다는 걸 나도 잘 알고 있지만, 만에 하나 말하지만 않는다면, 그녀 몰래 떠날 수도 있을 것임을 의미하는 것이 된다. 이 경우는 떠나고 싶다는 사실, 떠난다는 사실을 그녀에게 말하지 않는다는 의미가 된다.

두번째 해석이 맞을 것 같다는 느낌이 들지만, 어차피 노래 가사이고 일종의 시이니 어떤 해석이 꼭 맞다고 주장할 수는 없을지도. 아래는 영화 중경삼림에 삽입된 California Dreaming.