業務に合間にUI使用が変わっていてエラーになっていたツイッターの自動投稿のコードを修正しました。
作るに際してSeleniumエラーあるあるの代表格である no such element: Unable to locate elementで少し苦しんだが、原因はツイッターのUIではなくSeleniumの仕様変更でした。
というのも昔のSeleniumはby_classname
で暮らすをそのままコピペすればその部分の要素を取得してくれたが、どうやらアプデでBootstrap系のクラスを
使用した空白のあるクラスはCSS扱いすることにしたらしく空白のあるクラスはby_css
の方で取得しないと取れなくなっていた。
XPATHで取得しようと思ったのだが、クリックアクションで動的にHTML要素が変わっているいるらしく、うまくXPATHが定まらなかった。
ツイッターの方も昔はボタンでデータ送信というかわいい仕様だったが久しぶりにデベロッパーツールでソースを見てみると昔より気持ち悪くなっててスクレイピング泣かせになってました。
PythonとSeleniumでツイッターに自動投稿するスクリプト
# ライブラリの読み込み from selenium import webdriver import time import random import requests import pandas as pd # ドライバーの呼び出し(executable_pathは自分のWEBDRIVERのPATH) drv = webdriver.Chrome( executable_path="chromedriver.exe") # ツイッターに自動投稿する関数 def auto_tweet(id, password, tweet): """[twitterに自動投稿するスクリプト] id : str 自分のツイッターのID password : str 自分のツイッターのパスワード tweet : str 投稿したいツイート """ global driver drv.get('https://twitter.com/login/') drv.find_element_by_xpath( '//*[@id="page-container"]/div/div[1]/form/fieldset/div[1]/input')\ .send_keys(id) time.sleep(2) drv.find_element_by_xpath( '//*[@id="page-container"]/div/div[1]/form/fieldset/div[2]/input')\ .send_keys(password) time.sleep(2) drv.find_element_by_xpath( '//*[@id="page-container"]/div/div[1]/form/div[2]/button').click() time.sleep(2) drv.get('https://twitter.com/compose/tweet') time.sleep(4) drv.find_element_by_css_selector( '.notranslate.public-DraftEditor-content').send_keys(tweet) drv.find_element_by_css_selector( '.css-18t94o4.css-1dbjc4n.r-urgr8i.r-42olwf.r-sdzlij.r-1phboty.r-rs99b7.\ r-1w2pmg.r-1vsu8ta.r-aj3cln.r-1fneopy.r-o7ynqc.r-6416eg.r-lrvibr').click() drv.quit() # ツイートを投稿する例 auto_tweet('@id', 'password', 'helloworld')
time.sleepは要らないけど一応書いているだけです。
ツイッターは基本的にYahooFinanceと同じでスクレイピングや自動操作の類は嫌っており、しょっちゅう仕様変更するのでこのコードも一年くらいしたら使えなくなると思います。
まあRechercheの類され来なければ、ちょっとコードを変えるだけでなんとかなるけどそろそろ来るかもしれない。まあこんなコード作っていうのもなんかもしれませんが大人しくAPI使って操作すればいいでしょう。
2021/11/25追記
動かなくなっていたので更新しました
⇒ 【2021年版】Python+Seleniumでツイッターに自動でログインしてツイートする
コメント