기획자 본인만큼 잡다한 블로그

greentec.egloos.com

포토로그


통계 위젯 (블랙)

22
15
106553

flag counter

Flag Counter


트위터 언팔로워 트래커 프로그래밍




트위터에는 사용자에게 꼭 필요하지만 빠져 있는 기능이 있다. 바로 나를 언팔로우한 사람이 누군지 알려주는 기능이다. 언팔로우란 팔로우를 하다가 팔로우를 끊는 것을 말한다. 페이스북으로 치면 unfriend, 싸이월드로 치면 일촌끊기가 되겠다. 일단 관계가 있어야 관계를 끊을 수 있다. 먼 옛날 싸이월드와 달리 인스타그램이나 트위터는 팔로워 수가 이 계정의 유명세에 대한 하나의 지표가 된다. 유명세는 권력, 힘이 된다.

트위터를 처음 시작한 초반에는 팔로우를 해주는 사람들이 그냥 고마웠다. 그래서 내 관심주제랑 어느 정도 겹치면 자연스럽게 맞팔로우를 하기도 했다. 그런데 그러고나서 매우 짧은 시간 후에 나에 대한 팔로우를 끊는 것을 몇 번 목격했다. 이런 것을 반복하면 이 사람의 팔로잉 수는 줄고 팔로워 수만 늘어서 자연스럽게 힘을 획득하게 된다. 양심이라는 아주 싼 가격에 말이다.
(관련글 링크 : 인스타그램 맞팔 후 언팔)

뭐, 물론 언팔을 하는 쪽에서도 변명할 수는 있겠지만 그런 것보다 중요한 것은 트위터의 팔로워 수가 100 명을 넘어가기 시작하면 눈으로 보고 누가 언팔로우를 했는지 알아내기는 쉽지 않다는 사실이다. 인터넷에 검색해보니 언팔매니저 같은 것들이 있는데, 여기까지 들어온 분들이라면 직접 코드를 사용하는 방법에 관심이 있을 것 같다. tweepy 를 사용하면 매일 내 팔로워를 긁어온 다음에 어제의 날짜와 비교해서 누가 팔로우를 끊었는지 알아낼 수 있다. 언팔매니저는 맞팔을 안해준 사람들을 찾는 것이 목적이라면 내가 만드는 코드는 언팔로워만 찾는 것이 목적이다.

그럼 간단한 코드를 보자. 짧은 코드이니만큼 전체를 리뷰하며 한 줄 한 줄 설명하도록 하겠다.
이 글은 python 3.6.2, tweepy 3.6.0 을 기준으로 한다.

  1. 트위터 API 접속

  2. 트위터는 API 를 제공하기 때문에 접속해서 나의 팔로워 수, 팔로워 정보, 트윗 등을 얻어올 수 있고 직접 트윗을 올릴 수도 있다. 나도 이것으로 2개의 트위터 봇을 라즈베리파이에서 돌리고 있다. 라즈베리파이는 설정 과정이 너무 고통스러웠기 때문에 빨리 백업을 해놔서 보드가 죽어도 다른 곳에서 쓸 수 있게 해야 하는데.. 아직 귀찮아서 못하고 있다. 어쨌든 이 서두 부분은 Twitter API 에 접속하기 위해서 꼭 필요하다.


    import tweepy
    from credentials import *

    # tweeter initialize!!
    auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
    auth.set_access_token(access_token, access_token_secret)
    api = tweepy.API(auth, wait_on_rate_limit=True, wait_on_rate_limit_notify=True, compression=True)



    일단 tweepy 는 트위터 API 를 간단한 명령어로 편하게 쓸 수 있게 해주는 python 라이브러리다. 윈도우 환경에서는 보통 Anaconda 를 쓴다면 pip install tweepy 같은 간단한 명령어를 cmd 창에서 입력해서 설치할 수 있다.

    credentials 는 이 코드에서 다루는 파일과 같은 위치에 저장된 credentials.py 파일을 말한다. developer.twitter.com 에 접속해서 App 을 사용하도록 설정하면 다음과 같은 Keys and tokens 를 받을 수 있다. 이 값들을 credentials.py 에 저장해놓고, 불러와서 twitter API 접속에 사용하는 것이다.




    credentials.py 에는 다음처럼 값을 저장해준다.

    consumer_key = 'Zzzzzzzzzzzzzzzzzzzzzzzz'
    consumer_secret = 'Mmmmmmmmmmmmmmmmmmmmmmmmmm'
    access_token = '11111111111111111-222222222222222'
    access_token_secret = 'eeeeeeeeeeeeeeeeeeeeee'




  3. 어제, 오늘의 팔로워 정보 얻어오기

  4. 다음 부분은 어제의 팔로워 정보를 로드하는 부분이다. 그런데 이 글을 따라오는 분들이라면 어제의 팔로워 저장 파일은 당연히 없을 것이기 때문에,지금은 써놓기만 하고 주석처리 후 뒤에서 팔로워 정보를 한번 저장한 후에 로드하면 된다.

    # load file
    original_ids = []
    with open(pi_path + 'follower.txt', 'r') as f:
    for line in f.readlines():
    if line != '':
    original_ids.append(line.strip())




    오늘의 팔로워 정보는 직접 tweepy 에서 얻어온다. 여기서 나오는 Cursor 가 궁금한 분들은 이곳에서 간단한 글을 읽어보셔도 좋겠다. 요약하면 Cursor 는 기존의 page 방법과 다르게 boilerplate code (어떤 업무를 위해 반복적으로 작성해야 하는 코드) 를 없애고 간단하게 같은 작업을 할 수 있는 표현법이다.

    이 코드는 이 gist 에서 가져왔다.

    print("Loading followers..")
    followers = []
    for follower in tweepy.Cursor(api.followers).items():
    followers.append(follower)

    print("Found %s followers, finding friends.." % len(followers))
    friends = []
    for friend in tweepy.Cursor(api.friends).items():
    friends.append(friend)

    print('Found %s friends..' % len(friends))


    # creating dictionaries based on id's is handy too
    friend_dict = {}
    for friend in friends:
    friend_dict[str(friend.id)] = friend

    follower_dict = {}
    for follower in followers:
    follower_dict[str(follower.id)] = follower




  5. 어제, 오늘의 정보 비교해서 언팔로워 알아내기

  6. 이 부분도 2에서 어제의 팔로워 정보가 없어서 original_ids 가 [] 상태인 분들은 모든 사람이 unfollowers 로 뜰 것이다. 그렇지 않다면 정확한 unfollowers 와 unfollowers_and_still_friends 가 뜰 것이다. unfollowers 는 어제와 비교해서 오늘 follower 가 아닌 사람(언팔로우한 사람), unfollowers_and_still_friends 는 그 중에 아직 내가 팔로우하고 있는 사람이다. 내가 관심있는 건 뒷부분이다. 내가 팔로우 중이지만 나를 언팔로우한 경우.

    unfollowers = []
    unfollowers_and_still_friend = []
    for id_ in original_ids:
    if id_ not in follower_dict:
    unfollowers.append(id_)
    if id_ in friend_dict:
    unfollowers_and_still_friend.append(id_)

    print('unfollwers:', len(unfollowers))
    print('unfollowers_and_still_friend:', len(unfollowers_and_still_friend))




  7. 변경된 팔로워 저장

  8. 오늘의 팔로워 정보만 저장한다. 좀 더 자세히 한다면 이 사람이 언제 팔로워가 됐는지 하는 것들도 저장 가능하겠지만, 나는 라즈베리파이에서 이 스크립트를 돌릴 것이기 때문에 가능한 최소한의 저장 용량만 쓰고 싶었다. 오늘의 팔로워 목록만 있으면 내 목적은 달성된다.

    이제 2에서 어제의 팔로워 정보가 없어서 로드를 못하셨던 분들은 로드를 할 수 있다. 다만 팔로워가 많을 경우 tweepy 의 기능을 여러 번 사용하면 limit 가 걸릴 수 있다는 점에 주의하자. 이럴 때는 일정 시간 동안 기다렸다가 다시 시도하면 된다.

    # save file
    with open(pi_path + 'follower.txt', 'w') as f:
    for id_ in follower_dict:
    f.write(str(id_) + '\n')




  9. 메일로 보내서 자동화

  10. 이제 스크립트는 완성되었다. 이 스크립트를 매일 돌려도 된다. 하지만 좀 더 자동화하면 내 삶이 편해질 것 같다. 라즈베리파이에 넣어서 일정 시간마다 스크립트가 실행되도록 하고, 해당 내용을 메일로 받아보고 싶었다.

    나는 gmail 을 사용하는데 yagmail 이라는 라이브러리를 설치하면 좀 편하게 메일을 보낼 수 있다. 사용 방법은 아까처럼 cmd 창에서 pip install yagmail 을 입력하면 설치된다. 원래는 smtplib 라이브러리를 쓰려고 했는데 gmail 접속이 안돼서 이걸로 바꿨다. 그런데 스크립트로 메일이 안갈 때의 해결책이 지메일에서 '보안성이 낮은 앱의 접근을 허용' 옵션을 켜는 것이었기 때문에, 사실 smtplib 을 써도 되는 게 아니었나 생각한다.

    import smtplib
    from email.mime.text import MIMEText
    import datetime
    import yagmail

    if len(unfollowers) > 0:
    now = datetime.datetime.now()
    nowDate = now.strftime('%Y-%m-%d')

    mail_str = ''
    for id_ in unfollowers:
    if id_ in unfollowers_and_still_friend:
    mail_str += 'unfollower and still friend: ' + id_ + '\n'
    else:
    mail_str += 'just unfollower: ' + id_ + '\n'

    mail_str += '\n'
    mail_str += 'unfollower: ' + str(len(unfollowers)) + '\n'
    mail_str += 'unfollowers_and_still_friend: ' + str(len(unfollowers_and_still_friend)) + '\n'


    sub = '[트위터 Unfollower Tracker] ' + nowDate + ' unfollower 현황입니다.'

    yag = yagmail.SMTP("send_email_address", "password")
    yag.send("receive_email_address", subject=sub, contents=mail_str)





이것으로 자동화가 완성되었다. 이제 나를 팔로우하는 사람들에게 자신있게 맞팔로우를 할 수 있다...


* 후기

이 시스템을 만들고 며칠 동안 언팔로워가 없어서 제대로 테스트하지 못하다가, 드디어 오늘 언팔로워가 생겨서 메일을 받아볼 수 있었다. 결론은 잘 동작한다. 




핑백

덧글

댓글 입력 영역

애드센스