uitspitss blog

プログラミングと音楽とエッセイ ※記載内容は個人の見解であり、所属する組織とは一切関係がありません。

tweepy(もしくはrequests-oauthlib)とsqlite3でフォロー状況を見る

だいぶ前に、遊びで使っているtwitterアカウントでリフォローをしようとしたときに、 フォロー制限のためにリフォローができなかった。 ということで、python用のtwitterライブラリtweepyを使って、 sqlite3のデータベースにフォロー状況を書き出すものを作った。 個人的にはsqlite3などのRDBの勉強としての意味合いもあった。

環境

  • python - 3.5.2
  • tweepy - 3.5.0
  • sqlite3

tweepyを使う準備

tweepyを介して、twitterAPIにアクセスするには、

  • consumer keyconsumer secret
  • access tokenaccess secret

が必要になるので、https://apps.twitter.com/でアプリケーション登録をして、トークン等を準備する。

friendsとfollowersを取得

大抵のWebAPIにはアクセス制限が付きものなので、まずはそのあたりを調べた。 なお、以下のサイトを参考にした。

api.friends_idsapi.followers_idsは、それぞれ5000ids/回を取得でき、15回/15分のリミットなので、 フォロー数が1万を超えていても安心という数を捌ける。

以下のコードで、自アカウントがフォローしているfriends、自アカウントをフォローしているfollowersを取得できる。

import tweepy

CONSUMER_KEY = "CONSUMER_KEY"
CONSUMER_SECRET = "CONSUMER_SECRET"
ACCESS_TOKEN = "ACCESS_TOKEN"
ACCESS_SECRET = "ACCESS_SECRET"

auth = tweepy.OAuthHandler(CONSUMER_KEY, CONSUMER_SECRET)
auth.set_access_token(ACCESS_TOKEN, ACCESS_SECRET)
api = tweepy.API(auth)

friends_ids = []
for _id in tweepy.Cursor(api.friends_ids).items():
    friends_ids.append(_id)

followers_ids = []
for _id in tweepy.Cursor(api.followers_ids).items():
    followers_ids.append(_id)

実際に使ったコードでは、この後にそれぞれのListをSetにして、set.unionをとり、相互フォローを出す処理なども入れていた。

追記:2016-10-27 ここから

今日、何気なくQiitaを見てて、tweepy がメンテナンスされなくなった という記事を見かけた。「あれっ」と思って、tweepyのgithubページを見たら、 本当に「もうメンテしない」って書いてた。 近い将来、twitterAPIの仕様変更などで動かなくなることは目に見えてるので、requests-oauthlibを使って書き直したものを以下に載せる。

from requests_oauthlib import OAuth1Session
import json

twitter = OAuth1Session(CONSUMER_KEY, client_secret = CONSUMER_SECRET,
                        resource_owner_key = ACCESS_TOKEN, resource_owner_secret = ACCESS_SECRET)

friends_ids = []
cursor = -1
while cursor:
    req = twitter.get('https://api.twitter.com/1.1/friends/ids.json?cursor={}'.format(cursor))

    if req.status_code == 200:
        data = json.loads(req.text)
        friends_ids.extend(data['ids'])
        cursor = data['next_cursor']
    else:
        print("request error : {}".format(req.status_code))
        break

followers_ids = []
cursor = -1
while cursor:
    req = twitter.get('https://api.twitter.com/1.1/followers/ids.json?cursor={}'.format(cursor))

    if req.status_code == 200:
        data = json.loads(req.text)
        followers_ids.extend(data['ids'])
        cursor = data['next_cursor']
    else:
        print("request error : {}".format(req.status_code))
        break

以下のページが参考になった。

追記:2016-10-27 ここまで

取得したfriendsとfollowersをデータベースに保存

そして、sqlite3のデータベースに保存しておく。 以下のコードは上のコードに続くような形で書いている。

import sqlite3

con = sqlite3.connect("{}.db".format("db_name"))

cur = con.cursor()
cur.execute("select * from sqlite_master where type='table'")

tables = []
for item in cur.fetchall():
    tables.append(item[1])

if "friends" not in tables:
    con.execute("create table friends(user_id integer primary key not null unique, friend integer, follower integer)")

for _id in friends_ids:
    con.execute("replace into friends(user_id, friend) values({}, {})".format(_id, 1))

for _id in followers_ids:
    con.execute("insert or ignore into friends(user_id, follower) values({}, {})".format(_id, 1))
    con.execute("update friends set follower = {} where user_id = {}".format(1, _id))

con.commit()
con.close()

followersのほうの処理で面倒なことになっているのは、sqlite3のreplaceがdelete処理を含んでしまうので、 insert or ignoreupdateを組み合わせるという方法を採っているから。 これはStack Overflowあたりで見かけたような。

データベースを見る

あとは、sqlite3の操作でフォロー状況を確認できる。

データベースを指定して開く

sqlite3 db_name.db

相互フォロー数を出す

select count(*) from friends where friend = 1 and follower = 1;

リフォローしていない数を出す

select count(*) from friends where friend = 0 and follower = 1;

最後に

いかにも業者なアカウントのフォローは避けたいものです。 ただし、idからそのような判別はできないので、tweepyのapi.lookup_users()screen_nameを引っ張てきて、リフォロー用の即席htmlページを書き出したりもしていた。 あと、この関数の説明がtweepyドキュメントになくて、 githubで確認したのを思い出した。