10
8

More than 3 years have passed since last update.

Python Tweepyを使ってフォローを自動化

Last updated at Posted at 2021-02-02

Python Tweepyを使ってフォローを自動化

はじめに

Tweepyインストール、OAuth認証、キーワード検索の詳細は以下の投稿を参考にしてください
Python Tweepyを使ってキーワードを含むツイートを取得
Python Tweepyを使っていいねを自動化

tweepy インストール

Twitter API の操作はtweepyが便利、是非使おう。

$ pip install tweepy

OAuth 認証

Twitter API を操作するには OAuth認証が必要
Developerサイトで取得したAPI KEYを使い認証を行う。

import tweepy


# 取得したAPI KEY、TOKENを入力
API_KEY = ""
API_SECRET_KEY = ""
ACCESS_TOKEN = ""
ACCESS_TOKEN_SECRET = ""


def twitter_api() -> tweepy.API:
    auth = tweepy.OAuthHandler(API_KEY, API_SECRET_KEY)
    auth.set_access_token(ACCESS_TOKEN, ACCESS_TOKEN_SECRET)
    return tweepy.API(auth)

キーワード検索

キーワード検索しフォロー処理に必要なパラメーターを取得

def get_search(api: tweepy.API, q: str, since_id: int, count: int = 10) -> pd.DataFrame:

    q = f"{q} -filter:retweets -from:{ACCOUNT}"

    df = pd.DataFrame(
        columns=[
            "user_id",
            "following",
            "follow_request_sent",
            "followers_count",
            "friends_count",
            "tweet_id",
            "tweet_created_at",
        ]
    )

    last_id = -1
    while len(df) < count:
        count = count - len(df)
        try:

            tweets = api.search(
                q=q,
                count=count,
                tweet_mode="extended",
                locale="ja",
                lang="ja",
                include_entities=False,
                max_id=str(last_id - 1),
                since_id=str(since_id),
            )

            if not tweets:
                break

            for tweet in tweets:
                df = df.append(
                    {
                        "user_id": tweet.user.id,
                        "user_name": tweet.user.name,
                        "user_screen_name": tweet.user.screen_name,
                        "following": tweet.user.following,
                        "follow_request_sent": tweet.user.follow_request_sent,
                        "followers_count": tweet.user.followers_count,
                        "friends_count": tweet.user.friends_count,
                        "tweet_id": tweet.id,
                        "tweet_created_at": tweet.created_at + timedelta(hours=+9),
                    },
                    ignore_index=True,
                )

            last_id = df.iloc[-1]["tweet_id"]

        except tweepy.TweepError as e:
            raise e

    return df

フォローの処理

キーワード検索した結果をループしてUser IDを指定してcreate_friendshipを実行することでいいねが実行される
今回はFOLLOWにフォロー実行回数を設定し10回でフォロー処理を終了させる

フォロー履歴はBigQueryに保存

row.followingはフォロー済
row.follow_request_sentはフォロー申請済判定を行う

COUNT = 200
FOLLOW = 10
KEYWORDS = [
    "#週末ハッカソン",
]

BQ = bigquery.Client()


def follow(event, context):

    df = pd.DataFrame(
        columns=[
            "execution_at",
            "search",
            "since_id",
            "follow_success",
            "follow_failure",
        ]
    )

    api = twitter_api()

    # 直近フォロー履歴取得
    follow_history = _get_follow_history()

    for keyword in KEYWORDS:

        print(f"search: {keyword}")

        follow_success = 0
        follow_failure = 0
        execution_at = datetime.now()
        since_id = 0

        # 前回、TweetID
        tmp_df = follow.query(f"search == '{keyword}'")
        if len(tmp_df):
            since_id = tmp_df.iloc[0]["since_id"]

        search = get_search(api, keyword, since_id, COUNT)

        print(f"検索数:{COUNT} ヒット数:{len(search)}")

        if len(search):

            # 次回、TweetID
            since_id = search[0:1]["tweet_id"]

            for _, row in search.iterrows():

                # 合計10回フォローAPI実行終了
                if follow_success + follow_failure >= FOLLOW:
                    break

                try:
                    # 条件追加
                    if not row.following and not row.follow_request_sent:
                        # フォローの処理
                        api.create_friendship(id=row.user_screen_name)
                        follow_success += 1
                        print(f"follow_success: {row.user_id}")
                        time.sleep(4)

                except tweepy.TweepError as e:
                    follow_failure += 1
                    print(f"follow_failure: {row.tweet_id} {e.reason}")

        # 結果保存用のDataFrame
        df = df.append(
            {
                "execution_at": execution_at,
                "search": keyword,
                "since_id": since_id,
                "follow_success": follow_success,
                "follow_failure": follow_failure,
            },
            ignore_index=True,
        )

    print(df)

    # 結果をBigQueryに保存
    _add_follow_history(df)

フォロー履歴をBigQueryに保存

データセット、テーブル作成

保存用のデータセット作成

# データセット追加
bq --location=US mk --dataset --description "twitter_functions dataset using" weekend-hackathon:twitter_functions

保存用のテーブル作成

# テーブル作成
bq mk --table --description "favorite_history" \
weekend-hackathon:twitter_functions.follow_history schema/follow_history_schema.json

スキーマー

[
    {
        "description": "API実行日",
        "mode": "REQUIRED",
        "name": "execution_at",
        "type": "TIMESTAMP"
    },
    {
        "description": "検索",
        "mode": "REQUIRED",
        "name": "search",
        "type": "STRING"
    },
    {
        "description": "最終TweetID",
        "mode": "REQUIRED",
        "name": "since_id",
        "type": "INTEGER"
    },
    {
        "description": "成功フォロー数",
        "mode": "REQUIRED",
        "name": "follow_success",
        "type": "INTEGER"
    },
    {
        "description": "失敗フォロー数",
        "mode": "REQUIRED",
        "name": "follow_failure",
        "type": "INTEGER"
    }
]

フォロー履歴を取得して検索Tweetをsence_id以降で取得

def _get_follow_history():
    # 前回結果取得
    sql = f"""
    SELECT
      search,
      MAX(since_id) AS since_id,
    FROM
      `weekend-hackathon.twitter_functions.follow_history`
    GROUP BY
      search
    ORDER BY
      since_id DESC
    """

    return BQ.query(sql).to_dataframe()

フォロー履歴を保存

def _add_follow_history(df: pd.DataFrame):
    # 結果をBigQueryに保存
    table_id = "weekend-hackathon.twitter_functions.follow_history"
    job = BQ.load_table_from_dataframe(df, table_id)
    job.result()

いいね!と思ったら LGTM お願いします :clap::clap::clap:

【PR】週末ハッカソンというイベントやってます! → https://weekend-hackathon.toyscreation.jp/about/

10
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
8