Instagram のあるアカウントの Follower をクロールする


概要

Instagram のあるアカウントの全てのフォロワー情報をクロールする.
公式の Instagram API には自分のフォロワーリストを取得する API はあるが, 他人のフォロワーリストを取得する API はない.
ので今回は任意のアカウントのフォロワー情報をクロールするプログラムを作成した.

前提条件

このプログラムを使用するにあたっての前提条件
1. Instagram のアカウントをもっている
2. 調べたいアカウントの User ID を知っている
3. 自身の Query ID なるものを知っている

2 と 3 についてはその調べ方を後述する.

プログラム

crawl_followers.py

import requests
import json

# Your Account info
def get_user_info():
    return {
            "username": "your_account",
            "password": "your_password"
            }

# HTTP Headers to login
def login_http_headers():
    ua = "".join(["Mozilla/5.0 (Windows NT 6.1; WOW64) ",
                  "AppleWebKit/537.36 (KHTML, like Gecko) ",
                  "Chrome/56.0.2924.87 Safari/537.36"])
    return {
            "user-agent": ua,
            "referer":"https://www.instagram.com/",
            "x-csrftoken":"null",
            "cookie":"sessionid=null; csrftoken=null"
            }

# login session
def logined_session():
    session = requests.Session()
    login_headers = login_http_headers()
    user_info = get_user_info()
    login_url = "https://www.instagram.com/accounts/login/ajax/"
    session.post(login_url, data=user_info, headers=login_headers)
    return session

# a fetch (max 3000 followers)
def fetch_followers(session, user_id, query_id, after=None):
    variables = {
        "id": user_id,
        "first": 3000,
    }
    if after:
        variables["after"] = after

    followers_url = "".join(["https://www.instagram.com/graphql/query/?",
                             "query_id=" + query_id + "&",
                             "variables=" + json.dumps(variables)])
    # HTTP Request
    followers = session.get(followers_url)
    dic = json.loads(followers.text)
    edge_followed_by = dic["data"]["user"]["edge_followed_by"]

    count = edge_followed_by["count"] # number of followers
    after = edge_followed_by["page_info"]["end_cursor"] # next pagination
    has_next = edge_followed_by["page_info"]["has_next_page"]
    return {
            "count": count,
            "after": after,
            "has_next":  has_next,
            "followers": edge_followed_by["edges"]
            }

def fetch_all_followers(session, user_id, query_id):
    after     = None # pagination
    followers = []  

    while(True):
        fetched_followers = fetch_followers(session, user_id, query_id, after)
        followers += fetched_followers["followers"]

        if fetched_followers["has_next"]:
            after = fetched_followers["after"]
        else:
            return {
                    "count": fetched_followers["count"],
                    "followers": followers
                    }

def main(user_id, query_id):
    session = logined_session()
    return fetch_all_followers(session, user_id, query_id)

if __name__ == '__main__':
    user_id  = "3425874156" # user id to search 
    query_id = "" # your query id
    main(user_id, query_id)

調べたいアカウントの User ID を知る

あるアカウントの user id を知るのは割と簡単. 普通に Instagram の GUI から確認できる.
例: taylorswift の user id を知る
手順 1: chrome を開く
手順 2: developer tool を開く
手順 3: Network の tab に移動
手順 4: https://www.instagram.com/taylorswift/ にアクセス
手順 5: ↓にある /query をクリック

手順 6: Response の tab に移動し, "owner" という key を探す

手順 7: "owner" の中の "id" という key の横にある文字列が User ID である

自身の query id を知る

手順 1: chrome を開く
手順 2: https://www.instagram.com/ から login
手順 3: https://www.instagram.com/taylorswift/ にアクセス
手順 4: developer tool を開く
手順 5: Network を開く
手順 6: taylor の Followers をクリック
手順 7: ↓の中のリクエストの ?query_id の部分が自身の query id である (隠している部分に実際はある)

Query ID についてわかったこと

・ ログインし直しても常に同じ
・ アカウントを変えたら違うものになる
・ Instagram の公式 API からはそれらしきものが取得できない
・ 結論, 正体はよくわからないが, アカウントと 1 対 1 の関係にある何かしらの ID

以上なり