2012 트윗대선 크롤링 코드 mahler83, 2018-07-302018-09-11 법정에서 개표방송 보다가 트위터에 자동으로 올라오면 좋겠다 싶어서 그자리에서 간단한 파싱 프로그램을 짰다고 했더니 사람들 눈이 휘둥그레진 장면이 기억에 남는다. 봇트윗 서버를 뒤져보니 이렇게 소스코드가 남아있더라. <?php $url = ‘http://info.nec.go.kr/electioninfo/electionInfo_report.xhtml?electionId=0020121219&requestURI=%2Felectioninfo%2F0020121219%2Fvc%2Fvccp09.jsp&topMenuId=VC&secondMenuId=VCCP&menuId=VCCP09&statementId=VCCP09_%231&electionCode=1&cityCode=0&sggCityCode=0&x=23&y=11’; $text = file_get_contents($url); $temp = getbetween($text, ‘<tbody>’, ‘</tbody>’); $temp = getarraybetween($temp, ‘<tr>’, ‘</tr>’); $temp = getarraybetween($temp[1], ‘>’, ‘<‘); // 6 박표 7 박퍼센트 9 문표 10 문퍼센트 30 개표율퍼센트 if(!$temp[7]) die(); $gap = str_replace(‘,’, ”, $temp[6]) – str_replace(‘,’, ”, $temp[9]); $status = ‘[18대 대선 개표현황] ‘.date(‘H:i’).’ 현재 | 박근혜 vs 문재인 = ‘.substr($temp[7],1,-1).’% vs ‘.substr($temp[10],1,-1).’%, ‘.number_format($gap).’표 차이 (개표율:’.$temp[30].’%)’; // 발송 $userId = 739634468; $connection = connectTwitter($userId); postTwt(‘statuses/update’, array(‘status’=>$status, ‘trim_user’=>true), 0, 1); 공부도 안 되고 논문도 안 읽히고 한 줄씩 읽어보자 $url = ‘http://info.nec.go.kr/electioninfo/electionInfo_report.xhtml?electionId=0020121219&requestURI=%2Felectioninfo%2F0020121219%2Fvc%2Fvccp09.jsp&topMenuId=VC&secondMenuId=VCCP&menuId=VCCP09&statementId=VCCP09_%231&electionCode=1&cityCode=0&sggCityCode=0&x=23&y=11’; $url이라는 변수에 중앙선거관리위원회의 실시간 개표 현황을 공개하는 웹페이지 주소를 담아둔다. (저 url 지금은 안 열리더라) $text = file_get_contents($url); 기억에 당시 페이지는 리퍼러나 user agent를 확인하지 않았다. 그냥 file_get_contents()로 실시간 개표 현황을 불러들일 수 있었다. $temp = getbetween($text, ‘<tbody>’, ‘</tbody>’); getbetween()은 내 개인 라이브러리에 있는 함수이다. 간단하게 두 문구 사이의 텍스트를 추출하는 함수. 여기서는 <tbody>와 </tbody> 사이의 테이블 내의 텍스트를 추출하는 작업을 수행. $temp = getarraybetween($temp, ‘<tr>’, ‘</tr>’); getarraybetween()도 개인 라이브러리 함수. 반복되는 두 문구 사이의 텍스트를 모두 추출해 배열에 담는다. 여기서는 <tr>와 </tr> 사이의 텍스트를 추출했다. $temp = getarraybetween($temp[1], ‘>’, ‘<‘); $temp[0]이 아니라 $temp[1]을 이용한 걸 보니 두번째 <tr></tr> 사이에 당시 실시간 개표율 내용이 들어있었던 듯. 테이블의 각 셀에 있는 내용을 추출하기 위해 저렇게 >와 < 사이를 가져오는 명령어를 쓴 것 같다. if(!$temp[7]) die(); 만약 8번째 칸에 내용이 없거나 0이면 코드를 종료시키는 내용이다. 왜 적었더라? $url을 읽어들이는 단계에서 확인할 작업을 뒤늦게 하는 것 같은데.. $gap = str_replace(‘,’, ”, $temp[6]) – str_replace(‘,’, ”, $temp[9]); 1,2위 표차를 계산한다. 7번제 셀과 10번째 셀의 내용에서 str_replace()를 이용해 콤마를 지우고(12,345,678 이런식으로 표기되어있었던듯) 서로 빼면 표 차이가 나온다. $status = ‘[18대 대선 개표현황] ‘.date(‘H:i’).’ 현재 | 박근혜 vs 문재인 = ‘.substr($temp[7],1,-1).’% vs ‘.substr($temp[10],1,-1).’%, ‘.number_format($gap).’표 차이 (개표율:’.$temp[30].’%)’; 트윗 내용을 작성하는 라인이다. date(‘H:i’)는 23:50 이런 형태로 시간을 정리하는 것 substr($temp[7], 1, -1)은 8번째 칸에 있는 내용의 앞뒤 한글자씩 제외한 텍스트. 앞뒤에 공백이 있었으려나? 왜 trim()을 안 썼지? number_format($gap)은 표차이를 3자리마다 콤마를 찍어서 표시하라는 것 $temp[30] 여기에 개표율이 적혀있었나보다. 암튼 이렇게 표에 있는 여러가지 숫자를 조합해서 한줄의 트윗을 만들어낸다. $userId = 739634468; 트위터 API를 통해 명령어를 내릴 때 숫자 아이디(user_id)나 영문아이디(screen_name) 둘 중 하나를 이용해서 내가 누구인지 밝히도록 되어있다. 저 번호가 2012 트윗대선 계정의 숫자 아이디였나보다. $connection = connectTwitter($userId); 트위터 API를 이용하기 위해 object를 만들어야 하는데 저렇게 아이디를 지정해서 선언하도록 되어있다. postTwt(‘statuses/update’, array(‘status’=>$status, ‘trim_user’=>true), 0, 1); 트윗을 보내라는 명령어이다. 트위터 API를 이용할 때는 4가지 로그인용 정보를 제출해야 명령을 내릴 수가 있다. 계정 아이디 계정 비밀번호 어플리케이션 아이디 어플리케이션 비밀번호 이중에 계정 아이디는 앞에 나온 숫자 아이디이고, 봇트윗 서버의 DB에 저 숫자에 매칭되는 비밀번호가 저장되어있다. 어플리케이션 아이디와 비밀번호는 봇트윗의 아이디와 봇트윗의 비밀번호를 이용했다. 내가 “봇트윗을 이용해서 트윗을 발송했다”라고 말하는 것은 트위터 API를 이용하기 위해 요구되는 4가지 로그인 정보 중에 3, 4번은 이미 봇트윗 서비스를 이용하면서 발급받아 사용중이었기 때문에 따로 대선 개표방송 자동트윗을 위해 어플리케이션을 생성하고 아이디와 비밀번호를 발급받을 필요 없이 기존 것을 이용했다는 뜻이다. 아무튼 저 코드는 4가지 로그인 정보를 트위터 API 서버에 전송하고, statuses/update라는 트윗 발송 명령을 수행한다. 떠오르는 몇가지 QnA Q. 1분 단위 개표 자료라고 올라온 것에 존재하지 않는 수치(미세한 오차가 있는 수치)들이 자동트윗에 올라왔더라. 없는 자료를 만들어낸거냐? A. 실시간 개표 현황 사이트에 1분 사이에도 개표 상황이 여러번 업데이트된 것 아닐까? 내가 당시 한가해서 자동트윗 코드를 쓰긴 했지만 일부러 오차를 생성하는 코드를 추가할 정도로 심심하진 않았다. Q. 시간대별 1, 2위 표차는 선관위에서 발표한 적 없는 자료이다. 왜 있지도 않는 자료를 만들어서 혹세무민을 하는가? A. 세자리 수 뺄셈은 우리 큰애도 할 줄 알더라. 나는 5자리수 뺄셈까지는 자신 있다. 좀 더 큰 숫자 뺄셈은 컴퓨터에게 시키면 놀라운 속도로 정확하게 계산해준다. Q. 크롤링은 웹페이지의 내용을 그대로 가져오는 기술이다. 선관위 홈페이지에 2012 트윗대선 계정에 올라온 형태의 자료는 없었다. 임의로 만들어낸거 아니냐? A. 위에 코드를 보면 저런 식으로 원하는 형태로 정리해서 자동으로 트윗발송이 가능하다. 끝에 날씨도 표시해줬으면 흑마술로 보였겠다. 저정도라 다행이다. Q. Klear.com를 보면 2012 트윗대선 계정의 트윗들은 대선 방송 이전에 발송되었다고 나와있다. 어느게 원본인 것 같냐? 당연히 날짜가 오래된 쪽 아니냐? A. Klear.com이라는 사이트는 아무 공신력이 없다. 그리고 웹상의 날짜라는게 서버 시계 설정을 잘못 건들거나 간단하게 편집해서 얼마든지 바뀔 수 있는 것이다. 원한다면 이 글의 날짜를 인터넷 개발 되기 이전으로 바꿔줄테니 알려달라. 10줄 정도 되는 코드 때문에 대통령 선거 조작범이라는 누명을 쓰질 않나, 법정에 증인으로 불려가질 않나 돌이켜 보면 어처구니가 없다. 내 인생의 가장 의미있는(?) 코드가 된 것 같아 블로그 포스팅 남김. Share this:FacebookX My Thoughts Twitter API
상호평가 첫 시행 2012-03-052013-11-07 약리학 실습 수업에 다른 조원들이 실습에 기여한 정도를 수치로 평가하는 Eval이라는 모듈을 개발해 처음으로 도입했다. 나를 제외한 조원들에게 100점을 분배하는 방식인데, 재미있게도 학생들이 첫 날부터 담합을 해서 총점을 맞추려는 시도를 하는 것이었다. 예를 들어 10명이 한 조를 이룬 경우 나머지 9명에게 100점을 분배해야 하는데, 모두 11점을 주고 나는 너에게, 너는… Share this:FacebookX Read More
트위터 API Ver 1.1의 변화 2013-04-162013-11-07 https://dev.twitter.com/calendar 내일 V 1.0 blackout을 한다고 해서 -_-; statuses/mentions ==> statuses/mentions_timeline REST obj에 favorite_count 드디어 추가됨 friendships/exist ==> frienships/show 쌍방으로 보여줌 statuses/destroy ==> statuses/destroy/{status_id} accounts/rate_limiting ==> applications/rate_limiting Share this:FacebookX Read More
맞팔 안해준 사람 한꺼번에 언팔 기능 – 원클릭 맞언팔 2012-02-032013-11-07 트위터는 스팸성 팔로잉을 막기 위해 2001팔로잉 이후에는 “최대팔로잉 = 현재팔로어 x 1.1 + 1″이라는 공식으로 팔로잉을 제한하고 있습니다. (관련 트위터 공식 문서: http://goo.gl/r9RHf) 예를 들어 20,000명 팔로어를 가지고 있다면 22,001명까지만 팔로잉이 가능하고 팔로어가 늘어나야 추가로 팔로잉이 가능해집니다. 저른 이런 제한을 ‘팔로잉 리밋’이라고 부르는데, 팔로잉 리밋에 걸린 경우에는 다음과 같은 2가지… Share this:FacebookX Read More