プログラムで生活をHACKする

YRen-LaB

Python Selenium Webスクレイピング

【python】TwitterをSeleniumを使用し自動投稿する

投稿日:



初めに

Seleneiumを使用し、Twitterを自動投稿する内容を記載する。

※Twitterへのスクレイピング行為は規約で禁止されているので、ご利用は自己責任でお願いいたします。

Twitterの事前の承諾なしに本サービスのスクレイピングを行うことは明示的に禁じられています

引用:サービス利用規約

実装


from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

import os
from time import sleep

if __name__ == "__main__":

    # Seleneiumで参照するChromeのユーザープロファイル
    user_data_folder = R"C:\Users\UserName\xxxxxx\User Data"
    profile_folder_name = "Default"

    # 本来のChromeユーザープロファイルを見るならいらない
    if not os.path.exists(user_data_folder):
        os.mkdir(user_data_folder)

    # webdriver 諸々の設定
    webdriver_path = R"C:\Users\xxxxxx\chromedriver.exe"
    options =  webdriver.ChromeOptions()
    options.add_argument('--user-data-dir=' +  user_data_folder)
    options.add_argument('--profile-directory=' + profile_folder_name)

    browser = webdriver.Chrome(executable_path=webdriver_path,options=options)

    # Twitterへ接続して画面がロードされるまで待機
    browser.get("https://twitter.com/compose/tweet") # Twitterのtweet画面
    WebDriverWait(browser, 15).until(EC.presence_of_all_elements_located)
    sleep(2)

    # 上記パスにアクセスすると、ログインできてない場合ログイン画面が出る。
    if "login" in browser.current_url: 
        # URLにloginが含まれていたらという条件だが、ログイン画面がでたとわかれば何でも良い
        # WebDriver起動時にoptionでプロファイルフォルダを指定しているため、2回目以降は
        # ログイン画面はでないはず
        input("ログインが完了したら何かキーを押す")

        # ログイン処理も自動化したい場合以下で可能
        # browser.find_elements_by_xpath("//input[@class=\"r-30o5oe r-1niwhzg r-17gur6a r-1yadl64 r-deolkf r-homxoj r-poiln3 r-7cikom r-1ny4l3l r-1inuy60 r-utggzx r-vmopo1 r-1w50u8q r-1lrr6ok r-1dz5y72 r-1ttztb7 r-13qz1uu\"]")[0].send_keys("id")
        # browser.find_elements_by_xpath("//input[@class=\"r-30o5oe r-1niwhzg r-17gur6a r-1yadl64 r-deolkf r-homxoj r-poiln3 r-7cikom r-1ny4l3l r-1inuy60 r-utggzx r-vmopo1 r-1w50u8q r-1lrr6ok r-1dz5y72 r-1ttztb7 r-13qz1uu\"]")[1].send_keys("pass")
        # browser.find_element_by_xpath("//div[@class=\"css-18t94o4 css-1dbjc4n r-urgr8i r-42olwf r-sdzlij r-1phboty r-rs99b7 r-1w2pmg r-vlx1xi r-zg41ew r-1jayybb r-17bavie r-15bsvpr r-o7ynqc r-6416eg r-lrvibr\"]").click()

    # tweet内容
    browser.find_element_by_class_name("public-DraftEditor-content").send_keys("tweetしたい内容をここに入れる")

    # tweetボタン押下
    browser.find_element_by_xpath("//div[@class=\"css-18t94o4 css-1dbjc4n r-urgr8i r-42olwf r-sdzlij r-1phboty r-rs99b7 r-1w2pmg r-1n0xq6e r-1vuscfd r-1dhvaqw r-1fneopy r-o7ynqc r-6416eg r-lrvibr\"]").click()

解説

Seleniumの諸々の設定

    # Seleneiumで参照するChromeのユーザープロファイル
    user_data_folder = R"C:\Users\UserName\xxxxxx\User Data"
    profile_folder_name = "Default"

    # 本来のChromeユーザープロファイルを見るならいらない
    if not os.path.exists(user_data_folder):
        os.mkdir(user_data_folder)

    # webdriver 諸々の設定
    webdriver_path = R"C:\Users\xxxxxx\chromedriver.exe"
    options =  webdriver.ChromeOptions()
    options.add_argument('--user-data-dir=' +  user_data_folder)
    options.add_argument('--profile-directory=' + profile_folder_name)

    browser = webdriver.Chrome(executable_path=webdriver_path,options=options)

ここではSeleneium使うための設定をしている。
Twitterのようなログインを求められるようなWebサービスでは
optionの【--user-data-dir】と【--profile-directory】を使用することで一度ログインしてしまえば
再度ログインを求められる回数が少なくなる。

いくつかのサイトでは【--user-data-dir】に
C:\Users\UserName\AppData\Local\Google\Chrome\User Data
を指定するように記載されているが、こっちを指定してしまうとツールChromeDriver起動中に
通常のChromeが起動できなくなるため、Chromeをデフォルトブラウザとして使っている人にはお勧めできない。

今回の場合だと【--user-data-dir】には空のフォルダを充てておけばサイト等にログインした際にその下にデータができるため個人的お勧め

Twitterへ接続/ログイン

    # Twitterへ接続して画面がロードされるまで待機
    browser.get("`https://twitter.com/compose/tweet`") # Twitterのtweet画面
    WebDriverWait(browser, 15).until(EC.presence_of_all_elements_located)

    # 上記パスにアクセスすると、ログインできてない場合ログイン画面が出る。
    if "login" in browser.current_url: 
        # URLにloginが含まれていたらという条件だが、ログイン画面がでたとわかれば何でも良い
        # WebDriver起動時にoptionでプロファイルフォルダを指定しているため、2回目以降は
        # ログイン画面はでないはず
        input("ログインが完了したら何かキーを押す")

        # ログイン処理も自動化したい場合以下で可能
        # browser.find_elements_by_xpath("//input[@class=\"r-30o5oe r-1niwhzg r-17gur6a r-1yadl64 r-deolkf r-homxoj r-poiln3 r-7cikom r-1ny4l3l r-1inuy60 r-utggzx r-vmopo1 r-1w50u8q r-1lrr6ok r-1dz5y72 r-1ttztb7 r-13qz1uu\"]")[0].send_keys("id")
        # browser.find_elements_by_xpath("//input[@class=\"r-30o5oe r-1niwhzg r-17gur6a r-1yadl64 r-deolkf r-homxoj r-poiln3 r-7cikom r-1ny4l3l r-1inuy60 r-utggzx r-vmopo1 r-1w50u8q r-1lrr6ok r-1dz5y72 r-1ttztb7 r-13qz1uu\"]")[1].send_keys("pass")
        # browser.find_element_by_xpath("//div[@class=\"css-18t94o4 css-1dbjc4n r-urgr8i r-42olwf r-sdzlij r-1phboty r-rs99b7 r-1w2pmg r-vlx1xi r-zg41ew r-1jayybb r-17bavie r-15bsvpr r-o7ynqc r-6416eg r-lrvibr\"]").click()

Twitterへ接続

https://twitter.com/compose/tweet
このURLは以下の画像の赤枠をクリックした際に表示される画面のもの。
正直https://twitter.com/homeでも問題はない!


Twitterへログイン 手動ログイン

どちらにしろログインがされていない場合はログイン画面が表示されるため
その時点のURLに「login」という文字列があればログイン画面が表示されたとしている。

    # 上記パスにアクセスすると、ログインできてない場合ログイン画面が出る。
    if "login" in browser.current_url: 
        # URLにloginが含まれていたらという条件だが、ログイン画面がでたとわかれば何でも良い
        # WebDriver起動時にoptionでプロファイルフォルダを指定しているため、2回目以降は
        # ログイン画面はでないはず
        input("ログインが完了したら何かキーを押す")

自分でログインIDとパスを入力し、ログインする。ログインが完了したらコンソールで何かしらのキーを押下することで次の処理へ進む。

Twitterへログイン 自動ログイン

        # ログイン処理も自動化したい場合以下で可能
        # browser.find_elements_by_xpath("//input[@class=\"r-30o5oe r-1niwhzg r-17gur6a r-1yadl64 r-deolkf r-homxoj r-poiln3 r-7cikom r-1ny4l3l r-1inuy60 r-utggzx r-vmopo1 r-1w50u8q r-1lrr6ok r-1dz5y72 r-1ttztb7 r-13qz1uu\"]")[0].send_keys("id")
        # browser.find_elements_by_xpath("//input[@class=\"r-30o5oe r-1niwhzg r-17gur6a r-1yadl64 r-deolkf r-homxoj r-poiln3 r-7cikom r-1ny4l3l r-1inuy60 r-utggzx r-vmopo1 r-1w50u8q r-1lrr6ok r-1dz5y72 r-1ttztb7 r-13qz1uu\"]")[1].send_keys("pass")
        # browser.find_element_by_xpath("//div[@class=\"css-18t94o4 css-1dbjc4n r-urgr8i r-42olwf r-sdzlij r-1phboty r-rs99b7 r-1w2pmg r-vlx1xi r-zg41ew r-1jayybb r-17bavie r-15bsvpr r-o7ynqc r-6416eg r-lrvibr\"]").click()

手でログインなんて嫌だ!!って方はこちら。
ブラウザでF12を押下し、IDとパスの要素を確認する。

そうすると、IDとパスのclassが同じ要素で構成されているのがわかる。
正確には0要素がID、1要素目がPassになっていた。

要素がわかればあとは.send_key("str")を使用し、入力したい文字列を引数として投げることで
目的の文字列を入力することができる

IDとパスが入力終わったらあとはログインボタンの押下。

これでログインはできたはず。

ツイート

    # tweet内容
    browser.find_element_by_class_name("public-DraftEditor-content").send_keys("tweetしたい内容をここに入れる")

    # tweetボタン押下
    browser.find_element_by_xpath("//div[@class=\"css-18t94o4 css-1dbjc4n r-urgr8i r-42olwf r-sdzlij r-1phboty r-rs99b7 r-1w2pmg r-1n0xq6e r-1vuscfd r-1dhvaqw r-1fneopy r-o7ynqc r-6416eg r-lrvibr\"]").click()

あとはツイートするだけ。
やることはログインの時と一緒で、要素を確認し、ツイートしたい文字列をsend_keys("str")で投げ
ツイートボタンを押下するだけ。

ということでツイートする箇所の要素を確認する。

どの要素に対してsend_key()をすればよいかよくわからないときは
要素名に「textarea」や「inputタグ」とか入っているとこを探すと見つけやすいかも?まあサイト第だが...

ツイートボタンはツイートする文字列を入力しないと活性化しなことに注意。
ボタン系の要素を探すときは「submit」「button」「span」とかが目印になると思う

まとめ

以上、Seleneiumを使用してTwitterへ自動投稿する方法。
Webスクレイピング自体HTMLがなんとなくわかればできるので皆さんも是非。

ただ、サイトによってTwitterのようにスクレイピングを禁止しているサイトも多いので
必ず常識の範囲内での活用をしましょう。

おまけ

誰か「画像も一緒に投稿したいけど無理だよね...」

....できらぁ!!


from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

import os
import pywinauto

# ----------------------------------------------------------
# Twitterでの画像アップロード処理
# 
# ----------------------------------------------------------
def upload_item_photo():
    # # フォルダを取得
    photo_folder = os.path.abspath(R"C:\Users\xxxxxxxxxx\photo")

    # 開くダイアログを探して接続する
    # ダイアログタイトルを手掛かりにwindowを探す
    findWindow = lambda: pywinauto.findwindows.find_windows(title=u'開く')[0]

    # 上記Wndowを探す処理が完了したかチェックする
    # pywinauto.timings.wait_until(タイムアウトまでの時間, 繰り返す間隔(Sec), 組み込み関数)
    dialog = pywinauto.timings.wait_until_passes(20, 1, findWindow)

    # pywinauto に探し出したダイアログを接続
    pwa_app = pywinauto.Application()
    pwa_app.connect(handle=dialog)
    window = pwa_app[u"開く"]

    addres = window.children()[39]
    addres.click()

    # エクスプローラーのフォルダパス変更
    exp_folder_path = window.children()[43]
    exp_folder_path.type_keys(photo_folder+'{ENTER}',with_spaces=True)

    file_name = "testImg.jpg"

    # テキストボックス(ファイル名)にPATHを入力
    tb = window[u"ファイル名(&N):"]
    if tb.is_enabled():
        tb.click()
        edit = window.Edit4
        edit.set_focus()
        # ファイルを選択し、Alt + Oを押下
        edit.type_keys(file_name + '%O',with_spaces=True)    

if __name__ == "__main__":

    # Seleneiumで参照するChromeのユーザープロファイル
    user_data_folder = R"C:\Users\xxxxxxxxxx\User Data"
    profile_folder_name = "Default"

    # 本来のChromeユーザープロファイルを見るならいらない
    if not os.path.exists(user_data_folder):
        os.mkdir(user_data_folder)

    # webdriver 諸々の設定
    webdriver_path = R"C:\Users\xxxxxxxxxx\chromedriver.exe"
    options =  webdriver.ChromeOptions()
    options.add_argument('--user-data-dir=' +  user_data_folder)
    options.add_argument('--profile-directory=' + profile_folder_name)

    browser = webdriver.Chrome(executable_path=webdriver_path,options=options)

    # Twitterへ接続して画面がロードされるまで待機
    browser.get("https://twitter.com/compose/tweet") # Twitterのtweet画面
    WebDriverWait(browser, 15).until(EC.presence_of_all_elements_located)

    # 上記パスにアクセスすると、ログインできてない場合ログイン画面が出る。
    if "login" in browser.current_url: 
        # URLにloginが含まれていたらという条件だが、ログイン画面がでたとわかれば何でも良い
        # WebDriver起動時にoptionでプロファイルフォルダを指定しているため、2回目以降は
        # ログイン画面はでないはず
        input("ログインが完了したら何かキーを押す")

        # ログイン処理も自動化したい場合以下で可能
        # browser.find_elements_by_xpath("//input[@class=\"r-30o5oe r-1niwhzg r-17gur6a r-1yadl64 r-deolkf r-homxoj r-poiln3 r-7cikom r-1ny4l3l r-1inuy60 r-utggzx r-vmopo1 r-1w50u8q r-1lrr6ok r-1dz5y72 r-1ttztb7 r-13qz1uu\"]")[0].send_keys("ID")
        # browser.find_elements_by_xpath("//input[@class=\"r-30o5oe r-1niwhzg r-17gur6a r-1yadl64 r-deolkf r-homxoj r-poiln3 r-7cikom r-1ny4l3l r-1inuy60 r-utggzx r-vmopo1 r-1w50u8q r-1lrr6ok r-1dz5y72 r-1ttztb7 r-13qz1uu\"]")[1].send_keys("pass")
        # browser.find_element_by_xpath("//div[@class=\"css-18t94o4 css-1dbjc4n r-urgr8i r-42olwf r-sdzlij r-1phboty r-rs99b7 r-1w2pmg r-vlx1xi r-zg41ew r-1jayybb r-17bavie r-15bsvpr r-o7ynqc r-6416eg r-lrvibr\"]").click()

    # tweet内容
    browser.find_element_by_class_name("public-DraftEditor-content").send_keys("tweetしたい内容をここに入れる")
    # 画像も付ける
    browser.find_element_by_xpath("//div[@class=\"css-18t94o4 css-1dbjc4n r-1niwhzg r-42olwf r-sdzlij r-1phboty r-rs99b7 r-1w2pmg r-1vuahiu r-mvpalk r-1imd94c r-1vuscfd r-53xb7h r-mk0yit r-o7ynqc r-6416eg r-lrvibr\"]").click()
    upload_item_photo()

    # tweetボタン押下
    browser.find_element_by_xpath("//div[@class=\"css-18t94o4 css-1dbjc4n r-urgr8i r-42olwf r-sdzlij r-1phboty r-rs99b7 r-1w2pmg r-1n0xq6e r-1vuscfd r-1dhvaqw r-1fneopy r-o7ynqc r-6416eg r-lrvibr\"]").click()

ファイルの添付はWindowsGUIを自動操作する必要があるためSeleneiumだけでは不可能。
ここでは「pywinauto」というライブラリを使用している

pywinautoについては以前記事にしたのでそちらを見ていただければ。
関連:pywinautoでWindowsGUIからファイルアップロード





単純作業にお悩みではありませんか?

何百とあるワードを検索してファイルにまとめたり 数ある商品情報から条件にあるものだけ目で探してリ...

その単純作業プログラムで解決できるかもしれません。 もしよろしければ単純作業からの解放をお手伝いさせてください。

詳しくは以下のページからDM、または見積もり相談お願い致します。

お仕事依頼 ・ 見積もり依頼

adsense




-Python, Selenium, Webスクレイピング
-, ,

Copyright© YRen-LaB , 2021 AllRights Reserved Powered by AFFINGER4.