Help us understand the problem. What is going on with this article?

Pythonでつくる彼女入門 ~Tinder自動化プロジェクト~ 第1話

更新情報

2019/6/27 アクセストークンの取得を修正
2019/5/11 tinder.pyの一部を修正

はじめに

突然ですがみなさん、彼女がほしくないですか? 僕はほしいです。
ないものは作るのがエンジニアなので、彼女をつくりたいと思います。

彼女の作り方

エンジニア最大の問題は、出会いがないことでしょう。周囲に女子がいないのですから、手を打たずして彼女が出来るはずがありません。そこで今回は、Tinderを使います。言わずと知れたマッチングアプリです。
ただし、単にTinderを始めるだけでは彼女はできないので、Tinderを自動化したいと思います。

目次

やったこと 主な出来事
第1話 自動右スワイプ
第2話 自動メッセージ送信 女性とマッチした
第3話 ライブラリ化 マッチした女性とLINEを交換した
第3.5話 アクセストークンの再取得 これまでのコードではトークンが取得できなくなっていた
第4話 データ収集 LINEの返信が来なくなった
第5話 データ分析 プロフィール文編 仲良くなった人から情報商材を勧められた
第6話 データ分析 画像編 リアルの知り合い女子から最近やたらと深夜に電話がかかってくる(?)

コードはGitHubから閲覧できます。

開発環境

  • MacBookAir
  • Python3.7

準備

アカウント準備

まずFacebookのアカウントを用意します。

続いて、Tinderのアプリをスマホにダウンロードし、Facebookのアカウントを用いてTinderのアカウントを作成します。Tinderのアカウントの作成にはFacebookを用いる方法と電話番号を用いる方法がありますが、自動化のためにはFacebookでアカウントを作る必要があります。

アカウントを作り終えたら、出会う準備は完了です。
...普通ならね。僕らの努力はここからスタートです。

Facebookのトークンを取得

2019/06/27追記: Facebookの仕様変更に伴い、下記のコードは動作しなくなりました。
第3.5話を参考にFacebookのトークンを取得してください。

スマホからアプリにログインし、左右にスワイプするのを楽しむのもいいですが、エンジニアたるものコンソールからログインしたいですよね。Tinderにログインするためには、まずはFacebookからトークンを取得する必要があります。
取得方法は↓こちら1

accessToken.py
import re
import robobrowser


def getAccessToken(email, password):

    MOBILE_USER_AGENT = "Mozilla/5.0 (iPhone; CPU iPhone OS 11_2_1 like Mac OS X) AppleWebKit/604.4.7 (KHTML, like Gecko) Version/11.0 Mobile/15C153 Safari/604.1"
    FB_AUTH = "https://www.facebook.com/v2.6/dialog/oauth?redirect_uri=fb464891386855067%3A%2F%2Fauthorize%2F&display=touch&state=%7B%22challenge%22%3A%22IUUkEUqIGud332lfu%252BMJhxL4Wlc%253D%22%2C%220_auth_logger_id%22%3A%2230F06532-A1B9-4B10-BB28-B29956C71AB1%22%2C%22com.facebook.sdk_client_state%22%3Atrue%2C%223_method%22%3A%22sfvc_auth%22%7D&scope=user_birthday%2Cuser_photos%2Cuser_education_history%2Cemail%2Cuser_relationship_details%2Cuser_friends%2Cuser_work_history%2Cuser_likes&response_type=token%2Csigned_request&default_audience=friends&return_scopes=true&auth_type=rerequest&client_id=464891386855067&ret=login&sdk=ios&logger_id=30F06532-A1B9-4B10-BB28-B29956C71AB1&ext=1470840777&hash=AeZqkIcf-NEW6vBd"

    s = robobrowser.RoboBrowser(
        user_agent=MOBILE_USER_AGENT, parser="html.parser")
    s.open(FB_AUTH)
    # submit login form
    f = s.get_form()
    f["email"] = email
    f["pass"] = password

    s.submit_form(f)
    # click the 'ok' button on the dialog informing you that you have already authenticated with the Tinder app
    f = s.get_form()
    s.submit_form(f, submit=f.submit_fields['__CONFIRM__'])
    # get access token from the html response
    access_token = re.search(
        r"access_token=([\w\d]+)", s.response.content.decode()).groups()[0]

    return access_token

robobrowserをpip等でインストールしてから実行してください。

実行すると、400エラーが出ることがあるようです。これは、PythonからのFacebookへのアクセスが不正アクセスと疑われるのが原因のようです。ブラウザからFacebookにログインすると、「不審なアクセスを検知しました」などと言われますので、表示に従って本人確認等を行ってください。完了後に再びプログラムを実行すれば、トークンが取得できるハズです。

Tinderのトークンを取得

Tinderのアプリは内部でAPIを介して、Tinderのサーバーと通信を行っています。エンドポイントはhttps://api.gotinder.comです。
エンドポイントの下の/v2/auth/login/facebooktoken:先程取得したトークンというデータをPOSTで投げることで、サーバーからレスポンスが帰ってきます。早速アクセスしてみましょう。

tinder.py
from accessToken import getAccessToken
import requests
import json

FBemail = "Facebookのメールアドレス"
FBpass = "Facebookのパスワード"

#FBトークンの取得
token = getAccessToken(FBemail, FBpass)

#Tinderのトークンの取得
with requests.Session() as s:
    params = {"token": token}
    response = s.post(
        "https://api.gotinder.com/v2/auth/login/facebook", data=json.dumps(params))
    print(response.text)

うまく行けば、json形式の文字列が表示されます。中にある_idがあなたのアカウントのidで、api_tokenがTinderにログインするためのトークンです。

Tinderにログイン

ここまでくれば、あと少しです。Tinderにログインして、自分の情報を表示してみましょう。HeaderにX-Auth-token:api_tokenとして先程取得したapi_tokenを記入し、/meta/にGETでアクセスします。

tinder.py
from accessToken import getAccessToken
import requests
import json

FBemail = "Facebookのメールアドレス"
FBpass = "Facebookのパスワード"

# FBトークンの取得
token = getAccessToken(FBemail, FBpass)

# Tinderのトークンの取得
with requests.Session() as s:
    params = {"token": token}
    response = s.post(
        "https://api.gotinder.com/v2/auth/login/facebook", data=json.dumps(params))
    response = json.loads(response.text)
    api_token = response["data"]["api_token"]

    # Tinderにログイン
    headers = {"X-Auth-Token": api_token, "Content-type": "application/json",
               "User-agent": "Tinder/10.1.0 (iPhone; iOS 12.1; Scale/2.00)"}
    s.headers.update(headers)
    meta = s.get("https://api.gotinder.com/meta")
    print(meta.text)

ずらずらっと表示された情報の中に、アカウントを作成した際に記入した自分のプロフィールが見えていれば、アクセス成功です。

自動右スワイプ

Tinderのスマホアプリをインストールし、プロフィールの設定を終えると、異性のプロフィールが表示されます。
表示された写真と自己紹介文を見て、「いいな」と思ったら画面を右にスワイプし、「ないな」と思ったら左にスワイプ。自分が右スワイプした人が、自分のプロフィールを右スワイプしていてくれた場合、マッチが成立しその人とチャットできるようになるというのがTinderの基本的な使い方です。
今回は、この右スワイプを自動化したいと思います。

位置情報の設定

Tinderは、自身の位置情報を利用して、近くにいる異性を優先して提示します。
アプリが取得した位置情報は、APIを介してTinderのサーバーに送信される仕組みになっているので、まずはこれをプログラムで設定します。/v2/metaに{"lat": 緯度, "lon": 経度}というパラメーターをPOSTで渡すことで設定ができます。ということで、例えば渋谷スクランブル交差点でTinderをするコードは以下の通りになります。

tinder.py
from accessToken import getAccessToken
import requests
import json

FBemail = "Facebookのメールアドレス"
FBpass = "Facebookのパスワード"

# FBトークンの取得
token = getAccessToken(FBemail, FBpass)

# Tinderのトークンの取得
with requests.Session() as s:
    params = {"token": token}
    response = s.post(
        "https://api.gotinder.com/v2/auth/login/facebook", data=json.dumps(params))
    response = json.loads(response.text)
    api_token = response["data"]["api_token"]

    # Tinderのヘッダーをセット
    headers = {"X-Auth-Token": api_token, "Content-type": "application/json",
               "User-agent": "Tinder/10.1.0 (iPhone; iOS 12.1; Scale/2.00)"}
    s.headers.update(headers)

    # 位置情報の登録
    location = {"lat": 35.658034, "lon": 139.701636} # 渋谷スクランブル交差点
    ping = s.post("https://api.gotinder.com/v2/meta",
                  params=json.dumps(params))

周囲のユーザーを取得

続いて、設定した位置情報の周囲の異性のプロフィールを取得します。エンドポイントは/user/recsです。
アクセスしてみましょう。

tinder.py
    #周囲のユーザーを取得
    users=s.post("https://api.gotinder.com/user/recs")
    print(users.text)

ずらずらと大量のユーザーが表示されるはずです。

全自動LIKE

最後に、右スワイプです。/like/{id}をPOSTで叩くことで、そのidを持つアカウントを右スワイプすることが可能です。idは先程取得したユーザーの中から取り出すことができます。
ということで、最終的なコードは以下の通り。

tinder.py
from accessToken import getAccessToken
import requests
import json

FBemail = "Facebookのメールアドレス"
FBpass = "Facebookのパスワード"

# FBトークンの取得
token = getAccessToken(FBemail, FBpass)

# Tinderのトークンの取得
with requests.Session() as s:
    params = {"token": token}
    response = s.post(
        "https://api.gotinder.com/v2/auth/login/facebook", data=json.dumps(params))
    response = json.loads(response.text)
    api_token = response["data"]["api_token"]

    # Tinderのヘッダーをセット
    headers = {"X-Auth-Token": api_token, "Content-type": "application/json",
               "User-agent": "Tinder/10.1.0 (iPhone; iOS 12.1; Scale/2.00)"}
    s.headers.update(headers)

    # 位置情報の登録
    location = {"lat": 35.658034, "lon": 139.701636}
    s.post("https://api.gotinder.com/v2/meta",
           params=json.dumps(params))

    while True:
        # 周囲のユーザーを取得
        users = s.post("https://api.gotinder.com/user/recs")
        for user in json.loads(users.text)["results"]:
            id = user["_id"]
            # 右スワイプ
            s.get("https://api.gotinder.com/like/{}".format(id))

これにて自動右スワイプが可能となりました。お疲れ様でした。
果たして彼女は出来るのでしょうか。次回をお楽しみに...

第2話はこちら!

参考文献

[1]https://github.com/charliewolf/pynder/issues/171
[2]https://gist.github.com/rtt/10403467 2


  1. 参考文献[1]を参考に、コードの一部を改変しました。類似のコードがネット上にいくつか発見されたので、最初に書いた人が誰なのかはもはやわかりませんでした。 

  2. TinderがOAuth2.0に対応する以前の情報のようで、そのままでは動きません。 

Fulltea
( ; ; ) ← 無限ループに泣かされている人の顔文字です。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away