SeleniumでX(旧Twitter)をスクレイピングしてログインとポスト投稿を自動で実行、最新ポストまで取得しちゃう【Python】

Selenium

n番煎じなのは理解していますが、今回はX(旧Twitter)のスクレイピングについてです。

スクレイピングは使い方次第で毒にも薬にもなります・・・という話は他のサイトや記事に委ねます。
ここで紹介する方法はあくまで研究目的、ということを事前に注記しておきます。

概要

今回の目的は、「X(旧Twitter)への自動ログイン」「ポスト(ツイート)の自動投稿」「指定アカウントの最新ポスト取得」に限定します。

Seleniumを使用しますので、知識に不安のある方はこちらからSeleniumの扱い方をご確認ください。

コーディング

事前準備

今回はSeleniumが必要になるので、pipでインストールします。

pip install selenium

ソースコードでは、ユーザー情報とともに使用するライブラリも指定します。

import time
from selenium import webdriver
from selenium.webdriver.common.by import By

username = "@ユーザー名"
password = "パスワード"

誰でも使いまわしできるようコード中でユーザー情報を指定していますが、セキュリティ的にはinitファイルなど別ファイルに入れておくと安心です。

ログイン

def login_func(driver, username, password):
    driver.get("https://x.com/login")
    driver.find_element(By.XPATH, '//input[@name="text"]').send_keys(username)
    driver.find_element(By.XPATH, '//div/span/span[text()="次へ"]').click()
    time.sleep(5)
    
    driver.find_element(By.XPATH, '//input[@name="password"]').send_keys(password)
    driver.find_element(By.XPATH, '//div/span/span[text()="ログイン"]').click()
    time.sleep(5)

webdriverを引数として、ユーザー名とパスワードを入力フォームに入力・クリックします。
関数名のセンスがないのは許してください(笑)。

XPATH指定していますが、もちろん他の方法でも大丈夫です。
ただ、div/div/div/div/div/…みたいな長文XPATH指定は、「HTML書いたことないんだな」と思われますので、IT系を生業にしたい方は絶対に避けましょう。

ポスト投稿

def send_post(driver, post_text):
    driver.get("https://x.com/")
    element = driver.find_element(By.CLASS_NAME, 'notranslate')
    element.click()
    element.send_keys(post_text)
    time.sleep(5)

    element = driver.find_element(By.XPATH, '//*[@data-testid="tweetButtonInline"]')
    driver.execute_script("arguments[0].click();", element)

必要最低限の機能しか入れていません。不足があれば適宜補いましょう。

実行内容は以下の通りです。

  1. 入力テキストを見つけて引数のpost_textを入力する
  2. ポスト投稿を実行する

動的サイトあるあるですが、投稿ボタンのクリックが曲者で、要素指定だけではうまく実行できないため、JavaScriptで無理やりに投稿ボタンを押します。

ポスト取得

def get_post(driver, account):
    driver.get(f"https://x.com/{account}")
    posts = [element.text for element in driver.find_elements(By.CLASS_NAME, 'css-1jxf684')]
    return posts

不完全ではありますが、こちらであらかた取得できます。
余計なものが混ざるのは、勉強だと思って頑張って除いていきましょう。

関数実行により、ポスト内容(テキスト)がリスト形式で取得できるはずです。

全体コード

まとめると以下のようになります。

import time
from selenium import webdriver
from selenium.webdriver.common.by import By

username = "@ユーザー名"
password = "パスワード"

def login_func(driver, username, password):
    driver.get("https://x.com/login")
    driver.find_element(By.XPATH, '//input[@name="text"]').send_keys(username)
    driver.find_element(By.XPATH, '//div/span/span[text()="次へ"]').click()
    time.sleep(5)
    
    driver.find_element(By.XPATH, '//input[@name="password"]').send_keys(password)
    driver.find_element(By.XPATH, '//div/span/span[text()="ログイン"]').click()
    time.sleep(5)

def send_post(driver, post_text):
    element = driver.find_element(By.CLASS_NAME, 'notranslate')
    element.click()
    element.send_keys(post_text)
    time.sleep(5)

    element = driver.find_element(By.XPATH, '//*[@data-testid="tweetButtonInline"]')
    driver.execute_script("arguments[0].click();", element)

def get_post(driver, account):
    driver.get(f"https://x.com/{account}")
    posts = [element.text for element in driver.find_elements(By.CLASS_NAME, 'css-1jxf684')]
    return posts

driver = webdriver.Chrome()
login_func(driver, username, password)
send_post(driver, "ポストしたいテキスト")
posts = get_post(driver, "@取得したいアカウント名")
print(posts)

欲しい機能や実行したい関数に応じて適宜変更してから実行してください。

まとめ

スクレイピングはサーバーに負荷をかけたり、本来提供側が望んでいないこと(データ引き抜きなど)を実行するので悪だと思われがちですが、実際にはリバースエンジニアリングにより技術進歩を促したり、運営者が外部視点でWebサイトを監視できたりと、必ずしも悪い側面ばかりではないと考えています。

もちろん、DoS攻撃になりうるようなスクレイピングは否定されて然りですが、良い方向で使ってくれる人が増えればと記事を書いてみました。

以上です。

スポンサーリンク

Selenium

Posted by このめ