質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.78%

【Python】Tweepyを用いて任意の時間に投稿されるツイートを自動更新して取得したい

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 138

___0xharu

score 1

前提・実現したいこと

はじめまして.独学でPythonの勉強をしているものです.
今回,Tweepyを用いて任意の時間に投稿されるツイートを自動更新して取得するコードについて質問があり,投稿させていただきます.

実現させたいことというのは,「ある任意の時間に投稿されるツイートを自動で更新して取得する」ということです.

書いてみたソースコード

さて,実際に色々と試してみた結果,ある任意の時間より前に投稿された最新ツイートは取得できたのですが,その時間に投稿されるツイートを取得するには至りませんでした.以下がそのコードです.

import tweepy
import datetime
import re

CK = "*********"
CS = "*********"
AT = "*********"
AS = "*********"

auth = tweepy.OAuthHandler(CK, CS)
auth.set_access_token(AT, AS)
api = tweepy.API(auth)

set_time = "" # ここに任意の時間を指定
username = "" # 任意のTwitterユーザ名を記入

dt = datetime.datetime.now()
dt_min = dt.strftime("%M")

while set_time != dt_min:
    dt = datetime.datetime.now()
    dt_min = dt.strftime("%M")
    tweet = tweepy.Cursor(api.user_timeline, id = username, tweet_mode = "extended").items(1)
    for status in tweet:
        content = re.findall(r"\w+", status.full_text)
        tt = re.findall(r"\d+", str(status.created_at))
        tt_min = tt[4]
        print(content, tt) # もともと入れる予定はありませんでしたが,動作確認用に入れてみました.
    if tt_min == set_time:
        tweet = tweepy.Cursor(api.user_timeline, id = username, tweet_mode = "extended").items(1)
        for status in tweet:
            content = re.findall(r"\w+", status.full_text)
            tt = re.findall(r"\d+", str(status.created_at))
            tt_min = tt[4]
            print(content, tt)
            break

出力結果

上記のコードを実行した結果,任意の時間までに投稿された最新ツイート1件を出力することはできたのですが,set_timeで設定した時間になると実行が終了してしまいます.

['*****', '*****'] (set_time以前の最新ツイートのツイート時間)
['*****', '*****'] (set_time以前の最新ツイートのツイート時間)
['*****', '*****'] (set_time以前の最新ツイートのツイート時間)
['*****', '*****'] (set_time以前の最新ツイートのツイート時間)
['*****', '*****'] (set_time以前の最新ツイートのツイート時間)

(ここでset_timeになる)

何も出力されずに終了

試したこと

記載したソースコードの他にも,

import sys

while set_time != dt_min:
    dt = datetime.datetime.now()
    dt_min = dt.strftime("%M")
    tweet = tweepy.Cursor(api.user_timeline, id = username, tweet_mode = "extended").items(1)
    for status in tweet:
        content = re.findall(r"\w+", status.full_text)
        tt = re.findall(r"\d+", str(status.created_at))
        tt_min = tt[4]
    if set_time == tt_min:
        sys.exit()

while set_time == dt_min and set_time != tt_min:
    dt = datetime.datetime.now()
    dt_min = dt.strftime("%M")
    tweet = tweepy.Cursor(api.user_timeline, id = username, tweet_mode = "extended").items(1)
    for status in tweet:
        content = re.findall(r"\w+", status.full_text)
        tt = re.findall(r"\d+", str(status.created_at))
        tt_min = tt[4]
    if set_time == dt_min and set_time == tt_min:
        tweet = tweepy.Cursor(api.user_timeline, id = username, tweet_mode = "extended").items(1)
        for status in tweet:
            content = re.findall(r"\w+", status.full_text)
            tt = re.findall(r"\d+", str(status.created_at))
            tt_min = tt[4]
            print(content, tt_min)


と複雑にしてみたり... 
そもそもツイート内の数字のみを取得したいという特性も利用して,

import time

tweet = tweepy.Cursor(api.user_timeline, id = username, tweet_mode = "extended").items(1)
    for status in tweet:
        content = re.findall(r"\d+", status.full_text)
        tt = re.findall(r"\d+", str(status.created_at))
        tt_min = tt[4]

while len(content) == 0:
    sys.stdout.write("\r更新中...")
    sys.stdout.flush()
    time.sleep(0.01)
    if len(content) >= 1 and set_time == tt_min:
        print(content, tt)
        break


など,考えつきそうなものは手当たり次第試してみたのですが,どれもset_timeに投稿されるツイートの取得には至りませんでした.

Pythonの勉強を始めたばかりですので,そもそものコードに無駄がある・使い方が違うなどの意見も下さると嬉しいです.

何卒宜しくお願い申し上げます.

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • sfdust

    2020/10/18 11:22 編集

    冒頭に「Tweepyを用いて最新ツイートを1件取得するコード」についてといいつつ、「ある任意の時間に投稿されるツイートを自動で更新して取得する」コードを希望されているようです。
    また、コードを見ると、「分」を指定して現在時刻(の分(%M))と比較しています。

    希望している動作は以下のどちらでしょうか。

    (1)「ある任意の時間」とは、「毎時(hours)の、指定した分(minute)」という意味でしょうか。
    すなわち、毎時(hours)の、指定した分(minute)内にツイートされたものだけを取得したいのでしょうか。
    すなわち、たとえば、「11時07分00秒以降、11時08分00秒より前」の1分間にツイートされた内容、「12時07分00秒以降、12時08分00秒より前」の1分間にツイートされた内容・・・を1時間ごとに取得すればよく、
    その間の59分間にツイートされた内容は無視してもよいということでしょうか。

    それとも

    (2)単純に1分間隔でツイートの有無を監視して、その都度、最新のツイートがあればそれを取得したいということでしょうか?

    キャンセル

  • ___0xharu

    2020/10/18 12:33

    sfdust様
    ありがとうございます.
    >>冒頭に「Tweepyを用いて最新ツイートを1件取得するコード」についてといいつつ、「ある任意の時間に投稿されるツイートを自動で更新して取得する」コードを希望されているようです。
    たしかに質問したい内容と実現したい内容が少し乖離したように感じますね... 申し訳ないです.

    >> また、コードを見ると、「分(%M)」を指定して現在時刻と比較しています。
    set_timeとdt_minの比較のことを指しているのでしょうか.もしそのことについて言及されているのでしたら私の言葉足らずです.すみません.set_timeとは任意の分(minute)を指定するもので,これをdt_min(分)と比較しているつもりでした.

    >>希望している動作は以下のどちらでしょうか。
    私の希望に近いのは(1)です.ただ,毎時の何分内にツイートされた内容というよりは私の指す「ある任意の時間」は何時何分というように,1日のうちでただ1点に限定されます.それではなぜ,分(minute)のみを指定するのかと言いますと,取得したいツイートを投稿しているユーザは,完全にランダムにツイートを更新しているという前提のもとで成り立っています.

    説明が難しく言葉足らずかもしれませんが,宜しくお願い申し上げます.

    キャンセル

  • sfdust

    2020/10/18 12:39 編集

    確認です。
    たとえば対象の時刻として「午前11:07:00秒以降、午前11:08:00秒前」を指定する、
    この場合、毎日「午前11:07:00秒以降、午前11:08:00より前」の60秒間だけリアルタイムに監視し、ツイートされた場合はその60秒間のツイートだけを取得すればよく
    それ以外の時間はツイート監視もせず、それ以外の時間にツイートされているものは無視する、
    そういう理解でよろしいですね?

    キャンセル

  • ___0xharu

    2020/10/18 12:51

    sfdust様
    返信いただき,大変感謝します.
    確認についてですが,sfdust様のおっしゃる通りです.お手を煩わせてしまい,大変申し訳ありません.
    宜しくお願い申し上げます.

    キャンセル

回答 1

checkベストアンサー

+1

元質問文の1番目に掲示されたコードですと、指定した分(settime)と現在時刻の分が同じになった場合、whileループを抜けて終了してしまいます。

while set_time != dt_min:   <--- set_time == dt_min である場合、whileループを抜けてプログラムが終わる
    (処理)

したがって、元のコードを生かすならば、下記のように、無限ループにしたうえで、1秒ごとに現在時刻が指定した時刻であるかどうか監視する形になります。

質問により仕様を明確化させていただいた結果を踏まえ、監視対象時間を時・分の形に変え、
かつ監視対象時間外のツイートについては一切無視する形としています。

(無限ループを抜ける場合は、CTRL+C(macの場合Command+Zでも終了できると思います。)を押してください)

(前略)
import time
(前略)
set_time = "1107" # ここに監視したい時間+分を24時間制のHHMM形式で記入 例1107=午前11時07分
username = "" # 任意のTwitterユーザ名を記入

# 重複判定のために取得済みのツイートのIDを格納するset
fetched_tweet_ids = set()

while True:
    dt = datetime.datetime.now()
    dt_hour_min = dt.strftime("%H%M")  # 現在時刻(時間+分)を格納する。※apiで取得される時間はUTCなのでUTC以外と比較する場合は適宜調整すること

    # 現在時刻が指定した時刻であるか判定し、指定した時刻ならば、処理を行う。
    if  dt_hour_min == set_time:

        tweet = tweepy.Cursor(api.user_timeline, id = username, tweet_mode = "extended").items(1)

        for status in tweet:
            # 取得したツイートが、すでに取得済のツイートと重複していないか判定する。
            # 重複している場合はforループを抜ける。
            if status.id in fetched_tweet_ids:
                break
            # 取得したツイートのIDを重複判定用のsetに格納する。
            fetched_tweet_ids.add(status.id)

            # ツイートの時・分を取得
            tt = re.findall(r"\d+", str(status.created_at))
            tt_hour_min = ''.join((tt[3],tt[4]))
            # 指定した時間以外のツイートであった場合は、forループを抜ける。(本来ならば、前日の同じ時刻のツイートの存在まで考慮すべきですが、ここでは簡便のため考慮していません)
            if tt_hour_min != set_time:
                break

            # ここ以下にやりたい処理を書きます。
            content = re.findall(r"\w+", status.full_text)
            print(content, tt)

    # 1秒ごとにチェックする 
    time.sleep(1)

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/10/18 16:20

    sfdust様
    回答ありがとうございます.
    sfdust様のご教示下さったコードとあわせて,ツイート投稿時間がutcで表示されることを踏まえてutc基準で時間を調整すると無事,取得することができました.
    何から何まで本当にありがとうございました.

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.78%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る