スキル

APIを使わずにツイッターに動画を投稿してみた

色々苦労して挫折しかけましたが、Twitterのメディアアイコンから画像や動画を投稿する方法のメモです。

もっと簡単な方法があるかもしれないと思いますが、とりあえず思いついて作成して成功したコードを残しておきます。

Pythonでサンプルを書いています。初心者でpythonを知らないという方向けの基礎ガイドを書いてみましたので、参考にしてみてください。

メディアを添付して投稿する手順

まずは、手動で動画を登録するときの手順を確認しておきます。

手動でツイッターへメディア投稿する手順

動画などのメディアを添付する方法は簡単ですよね。やり方は2つありますね

  • ドラッグ&ドロップでメディアを添付する方法
  • メディアアイコンをクリックして投稿する手順

ドラッグ&ドロップの方法は説明不要ですかね。メディアアイコンは、ツイート画面の左下にアイコンがあります。

このメディアアイコンをクリックするとファイルを選択するダイアログを開きます。ここで、添付するファイルを選択して、「開く」ボタンをクリックするだけですね。

Seleniumで投稿するときの問題点

上記の手順をSeleniumで実現すれば良いだけです。

  1. メディアアイコンをクリック
  2. ファイルを選択
  3. 開くボタンをクリック

これだけですね。超シンプル。そう思っていたのですが、Mac初心者の私には2つ目のファイルの選択ができなかった。カレントディレクトリ上のファイルならできるのですが、別のディレクトリへの移動が困難。

ダイアログ中央のフォルダボックスから対象のディレクトリに移動しなければならないんです。それをseleniumの機能で実現する方法がわからなかった。その実現方法がなく別の方法を模索することに。

Twitterにドラッグ&ドロップでメディアを添付する方法

メディアアイコンからファイルを選択する方法を一旦諦めて、ドラッグ&ドロップの方法を探すことにしました。

ドラッグ&ドロップはSeleniumにも機能があって、「selenium.webdriver.common.action_chains」と言うのがあります。

これを使えばできるのかなと思いましたが、これは2つのWebページの特定要素を別のページにドラッグ&ドロップする機能みたいなので、ローカルファイルをアップロードするときの機能ではなさそう。

その他、SeleniumからJavaなどのコードを呼び出して、実装する方法もありましたが、それも作り込みが激しい。

できるだけシンプルにって考えて調べた結果、ドラッグ&ドロップでローカルファイルにアップロードするのは困難という結論に。。。

直接ファイル指定して添付する方法

手で実施する作業と同じ操作が一番シンプルだろうと思ってやり方を色々試行錯誤した結果、Inputタグでtype属性がfileであれば、ファイルを直接アップロードできることがわかってきました。

Twitterにファイルを直接添付する方法

出来上がりは非常にシンプルなステップです。

  1. メディアアイコンのInputタグを探す
  2. 添付するファイルを指定してクリック

これだけです。少なくともツイッターのメディアアイコンのところでは成功しました。

これだとファイル選択のダイアログボックスも表示されずに、ファイルの添付が始まります。

メディアを添付するPythonコード

ファイルを添付するコードはこんな感じ。シンプルです。

InputTags=self.driver.find_elements(By.TAG_NAME,"input")
for InputTag in InputTags:
    if InputTag.get_attribute("type")=="file"
                InputTag.send_keys(FilePath)

Inputタグでtypeがfileなら他のページでも使えると思います。

対象要素の絞り込み

ただ、同じようなタグが複数ある場合は、self.driver.find_elementsでinputタグを取得して、一つずつ属性でtypeがfileとなっている要素を探すことになります。

また、inputタグでtypeがfileの要素が複数ある場合は、get_attribute のところで対象を特定できるように別の条件を入れてあげる必要がありそうです。例えば、こんな感じ。

InputTags=self.driver.find_elements(By.TAG_NAME,"input")
for InputTag in InputTags:
    if InputTag.get_attribute("type")=="file" 
       and InputTag.get_attribute("data-testid")=="fileInput":

ファイルを直接添付

FilePathは変数なので、アップロードするファイルを事前にセットしておく必要がありますが、ここでは割愛しています。

send_keysに指定するFilePathはフルパスの必要がありますよ、念のため。

                InputTag.send_keys(FilePath)

アップロード完了の確認方法

アップロードできる動画は140秒以内だったかな。それよりも長い動画はカットなどする必要があります。

カット方法はページ作ったら展開しますが、ここでは、アップロードが完了したかどうかを判断するコードです。

アップロードが始まると、ツイートウィンドウの下段にアップロード状況が表示されるので、100%完了するまで待たないで画面閉じたりリフレッシュするとアップロードがキャンセルされます。

だから、まず、その要素が現れるのを待って、その要素が100%になるまで待機する必要がある。

ステータス確認のPythonコード

ステータスのある要素はdivタグなので、ページに大量にあるので、要素を特定して、そのテキストのチェックをやります。

それなりに泥臭いコードです。

DivTags=self.driver.find_elements(By.TAG_NAME,"div")
for DivTag in DivTags:
    if DivTag.get_attribute("aria-live")=="polite" and 
       DivTag.get_attribute("role")=="status":
        LoopCount=5
        for i in range(LoopCount): 
               Status =DivTag.find_element(By.TAG_NAME,"span")
               if Status.text == "アップロード完了(100%)":
                    return True
               time.sleep(10)
return False

ステータスの要素探し

divタグは至る所にあるので、それを片っ端から調べてます。もう少し絞り込んでからでも良かったんですけど、シンプルなページなので、全部読ませてます。

それをforループで一つずつ属性をattributeで確認してます。Twitterのアップロードの状況は、aria-live=politeとrole=statusの2つの属性で一意に特定できましたので、その条件で検索しています。

さらに、アップロード後すぐにタグは出てきますが、100%になるまでに時間がかかります。サイズ次第ですが、1分以内には完了するので、100%の表示になるまで、最大1分間繰り返し確認を入れています。

それでも100%が確認できない場合は、エラーで処理する処理を書いていくことになります。

DivTags=self.driver.find_elements(By.TAG_NAME,"div")
for DivTag in DivTags:
    if DivTag.get_attribute("aria-live")=="polite" and 
       DivTag.get_attribute("role")=="status":
        LoopCount=6
        for i in range(LoopCount): 
               Status =DivTag.find_element(By.TAG_NAME,"span")
               if Status.text == "アップロード完了(100%)":
                    return True
               time.sleep(10)
#1分経っても100%にならない場合のエラー処理を記述
return False

ステータス確認

これまでの経験上、100%にならないと、どこかのタイミングで「エラー」表記に変わるので、その場合は、表示中のメディアをクローズして通常のツイートに戻すって処理を追加するなら次のような感じですかね。

DivTags=self.driver.find_elements(By.TAG_NAME,"div")
for DivTag in DivTags:
    if DivTag.get_attribute("aria-live")=="polite" and 
       DivTag.get_attribute("role")=="status":
        LoopCount=6
        for i in range(LoopCount): 
               Status =DivTag.find_element(By.TAG_NAME,"span")
               if Status.text == "アップロード完了(100%)":
                    return True
               elif Status.text == "エラー":
                    #メディアの削除などの処理
                    return True
               time.sleep(10)
#1分経っても100%にならない場合のエラー処理を記述
return False

プログラミングの学習方法について

基本的なPyhotnの文法などの解説は割愛していますが、ググってみればやり方はたくさん見つかるので、始めるまでの第一歩を頑張って踏み出せば、プログラマとしての道は広がっていくと思います。

それでも、独学で始めるのは不安という方は、最初なスクールなどに通って始め方を学ぶことをお勧めします。pythonの全体概要やどんなアプリケーション開発に向いているのかなど体系立てて学ぶことができます。

特にこちらのTechAcademyはpythonだけではなく、昨今注目されているテクノロジ全般を基礎から学べるスクールです。無料でカウンセリングも受けられますので、将来的に副業やフリーランスとして収入源を増やす手段にプログラマを選ぶのであれば、相談してみると、将来像が具体的に形となって見えてくると思います。

そして、受講を始めれば、すぐに大きなリターンが得られるスクールだと思います。早期の経済的自立を考えているのであれば、自分の投資先として、ここで最低半年修行することを強くお勧めします。

まとめ

Twitterに投稿する処理を中心にpythonの機能を使ってどんなことができるのかを日々試行錯誤している中で気づいたことをまとめています。

試しているうちに、ツイッターは結構癖のあるアプリだということがわかってきたので、そのうち別のSNSへ移行するかもしれませんが、当面はTwitterを使ったツイートの自動化を考えていこうと思います。

パーツ毎にブログを書いているので、組み合わせることであなたが作りたいものの助けになれば幸いです。

-スキル
-, , ,