import sys
import json
import streamlit as st
from selenium import webdriver
from selenium.webdriver.support.ui import Select
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from webdriver_manager.chrome import ChromeDriverManager
from time import sleep

# jsonへの保存
def save_to_json(data, filename):
    with open(filename, 'w') as f:
        json.dump(data, f)

# ユーザー情報取得
username = st.secrets["username"]
password = st.secrets["password"]

# インスタグラム トップ表示
browser = webdriver.Chrome(ChromeDriverManager().install())
url = "https://www.instagram.com"
browser.get(url)
sleep(3)

# インスタグラムへのログイン
loginForm = browser.find_element(By.ID, "loginForm")
browser.find_element(By.NAME, "username").send_keys(username)
browser.find_element(By.NAME, "password").send_keys(password)
browser.find_element(By.XPATH, '//*[@id="loginForm"]/div/div[3]').click()
sleep(5)
# ログイン試行回数エラー表示時
try:
    wait_message_element = browser.find_element(By.XPATH, '//p[contains(text(), "数分してから")]')
    if wait_message_element:
        print("ログイン試行回数エラーの表示のため処理を停止")
        sys.exit()
except NoSuchElementException:
    pass
# "情報を保存しますか？"の部分
try:
    save_info_button = browser.find_element(By.XPATH, '//button[@class="_acan _acap _acas _aj1-" and @type="button" and contains(text(), "情報を保存")]')
    save_info_text = save_info_button.text
    if save_info_text == '情報を保存':
        save_info_button.click()
        sleep(3)
except:
    pass
# "お知らせをオンにするをオフ"
try:
    notification_text = browser.find_element_by_xpath('//*[@id="mount_0_0_A+"]/div/div/div[2]/div/div/div[1]/div/div[2]/div/div/div/div/div[2]/div/div/div[2]/span[1]').text
    if notification_text == 'お知らせをオンにする':
        browser.find_element_by_xpath('/html/body/div[2]/div/div/div[2]/div/div/div[1]/div/div[2]/div/div/div/div/div[2]/div/div/div[3]/button[2]').click()
        sleep(3)
except:
    pass
print("ログイン: 成功")

# ループの開始
search_index = -1  # Initialize with -1
while True:
    print("--------------------------------")

    # ユーザーページへ遷移
    try:
        browser.get("https://www.instagram.com/{}/".format(username))
        print("ユーザーページへ遷移: 成功")
        sleep(5)
    except:
        print("ユーザーページへ遷移: 失敗")
        break

    # 各投稿のリンク取得
    post_elements = browser.find_elements(By.XPATH, '//a[contains(@href, "/p/")]')
    if post_elements:
        print("投稿リンクの要素発見: 成功")
        if search_index < len(post_elements) - 1:
            search_index += 1
            href = post_elements[search_index].get_attribute("href")
        else:
            print("全ての投稿を処理しました。")
            break
    else:
        print("投稿リンクの要素発見: 失敗")
        break

    if href:
        print("投稿リンクの取得: 成功")
    else:
        print("投稿リンクの取得: 失敗")
        break

    if href:
        print(f"生成リンク表示: {href}")
    else:
        print("生成リンク表示: None")
        break

    # 投稿リンクへアクセス
    try:
        browser.get(href)
        sleep(3)
        print("投稿リンクへのアクセス: 成功")
    except:
        print("投稿リンクへのアクセス: 失敗")
        break

# 投稿画面操作
    # キャプションコピー
    try:
        h1_caption_element = browser.find_element(By.XPATH, '//h1[contains(@class, "")]')
        h1_caption_text = h1_caption_element.text
        print("キャプション検索: 成功")
    except:
        print("キャプションがないため、次の投稿へスキップ")
        continue

    # キャプションをjsonへ保存
    try:
        save_to_json(h1_caption_text, "caption.json")
        print("キャプション保存: 成功")
    except:
        print("キャプション保存: 失敗")
        break

    # オプションボタンの押下
    try:
        more_options_button = browser.find_element(By.XPATH, '//button[@class="_abl-" and @type="button"]')
        more_options_button.click()
        print("オプションボタン押下: 成功")
        sleep(1)
    except:
        print("オプションボタン押下: 失敗")
        break

    # 編集ボタンの押下
    try:
        edit_button = browser.find_element(By.XPATH, '//button[@class="_a9-- _a9_1" and @tabindex="0"]')
        edit_button.click()
        print("編集ボタン押下: 成功")
        sleep(1)
    except:
        print("編集ボタン押下: 失敗")
        break

    # テキストエリアの選択
    try:
        caption_input_element = browser.find_element(By.XPATH, '//div[@aria-label]')
        print("Xpath(area-label検索)でテキストエリアの選択: 成功")
    except NoSuchElementException:
        print("Xpath(area-label検索)でテキストエリアの選択: 失敗")
        try:
            caption_input_element = browser.find_element(By.XPATH, f"//*[,.format(text)")
            print("Xpath(text検索)でテキストエリアの選択: 成功")
        except NoSuchElementException:
            print("Xpath(text検索)でテキストエリアの選択: 失敗")
            try:
                caption_input_element = browser.find_element(By.XPATH, '//*[@id="mount_0_0_bJ"]/div/div/div[2]/div/div/div[1]/div/div[3]/div/div/div/div/div[2]/div/div/div/div[2]/div[2]/div/div/div/div[2]/div[1]')
                print("Xpath(Xpath2)でテキストエリアの選択: 成功")
            except NoSuchElementException:
                print("Xpath(Xpath2)でテキストエリアの選択: 失敗")
                try:
                    caption_input_element = browser.find_element(By.XPATH, '//*[@id="mount_0_0_mu"]/div/div/div[2]/div/div/div[1]/div/div[3]/div/div/div/div/div[2]/div/div/div/div[2]/div[2]/div/div/div/div[2]/div[2]/div/span')
                    print("Xpath(Xpath3)でテキストエリアの選択: 成功")
                except NoSuchElementException:
                    print("Xpath(Xpath3)でテキストエリアの選択: 失敗")
                    try:
                        caption_input_element = browser.find_element(By.XPATH, '//*[@id="mount_0_0_EZ"]/div/div/div[2]/div/div/div[1]/div/div[3]/div/div/div/div/div[2]/div/div/div/div[2]/div[2]/div/div/div/div[2]/div[2]/div')
                        print("Xpath(text)でテキストエリアの選択: 成功")
                    except NoSuchElementException:
                        print("Xpath(text)でテキストエリアの選択: 失敗")
                        try:
                            caption_input_element = browser.find_element(By.XPATH, "//div[@aria-label and @role='textbox']/p/span | //div[@aria-label and @role='textbox']/p")
                            caption_input_element.click()
                            print("Xpath(yujisearch2)でテキストエリアの選択: 成功")
                        except NoSuchElementException:
                            print("Xpath(yujisearch2)でテキストエリアの選択: 失敗")
                            try:
                                caption_input_element = browser.find_elements(By.XPATH, "//div[@aria-label and @role='textbox'] | //textarea[@aria-label]")
                                print("Xpath(yujisearch1)でテキストエリアの選択: 成功")
                            except NoSuchElementException:
                                print("Xpath(yujisearch1)でテキストエリアの選択: 失敗")
                                print("テキストエリアの選択: 失敗")
                                break

    # キャプションの上書き
    try:
        caption_input_element.click()
        caption_input_element.send_keys(Keys.CONTROL + "a")
        caption_input_element.send_keys(Keys.DELETE)
        caption_input_element.send_keys("- overwrite -")
        print("キャプションの上書き: 成功")
        sleep(3)
    except:
        print("キャプションの上書き: 失敗")
        break

    # 完了ボタンの押下
    try:
        done_button = browser.find_element(By.XPATH, '//div[@role="button" and @tabindex="0" and contains(text(), "完了")]')
        done_button.click()
        print("完了ボタン押下: 成功")
    except:
        print("完了ボタン押下: 失敗")
        break

    # 2回目のオプションボタンの押下
    try:
        more_options_button = browser.find_element(By.XPATH, '//button[@class="_abl-" and @type="button"]')
        more_options_button.click()
        print("2回目のオプションボタン押下: 成功")
        sleep(1)
    except:
        print("2回目のオプションボタン押下: 失敗")
        break

    # 2回目の編集ボタンの押下
    try:
        edit_button = browser.find_element(By.XPATH, '//button[@class="_a9-- _a9_1" and @tabindex="0"]')
        edit_button.click()
        print("2回目の編集ボタン押下: 成功")
        sleep(1)
    except:
        print("2回目の編集ボタン押下: 失敗")
        break

    # 2回目のテキストエリアの選択
    try:
        caption_input_element = browser.find_element(By.XPATH, '//div[@aria-label]')
        print("Xpath(area-label検索)で2回目のテキストエリアの選択: 成功")
    except NoSuchElementException:
        print("Xpath(area-label検索)で2回目のテキストエリアの選択: 失敗")
        try:
            caption_input_element = browser.find_element(By.XPATH, '//*[@id="mount_0_0_5o"]/div/div/div[3]/div/div/div[1]/div/div[3]/div/div/div/div/div[2]/div/div/div/div[2]/div[2]/div/div/div/div[2]/div[1]/div[1]')
            print("Xpath(id)で2回目のテキストエリアの選択: 成功")
        except NoSuchElementException:
            print("Xpath(id)で2回目のテキストエリアの選択: 失敗")
            try:
                caption_input_element = browser.find_element(By.XPATH, '//*[@id="mount_0_0_EZ"]/div/div/div[2]/div/div/div[1]/div/div[3]/div/div/div/div/div[2]/div/div/div/div[2]/div[2]/div/div/div/div[2]/div[2]/div/span')
                print("Xpath(text)で2回目のテキストエリアの選択: 成功")
            except NoSuchElementException:
                print("Xpath(text)で2回目のテキストエリアの選択: 失敗")
                try:
                    caption_input_element = browser.find_element(By.XPATH, "//div[@aria-label and @role='textbox']/p/span | //div[@aria-label and @role='textbox']/p")
                    print("Xpath(yujisearch2)で2回目のテキストエリアの選択: 成功")
                except NoSuchElementException:
                    print("Xpath(yujisearch2)で2回目のテキストエリアの選択: 失敗")
                    try:
                        caption_input_element = browser.find_elements(By.XPATH, "//div[@aria-label and @role='textbox'] | //textarea[@aria-label]")
                        caption_input_element.click()
                        print("Xpath(yujisearch1)で2回目のテキストエリアの選択: 成功")
                    except NoSuchElementException:
                        print("Xpath(yujisearch1)で2回目のテキストエリアの選択: 失敗")
                        print("2回目のテキストエリアの選択: 失敗")
                        break

    # キャプションのペースト
    try:
        caption_input_element.send_keys(Keys.CONTROL + "a")
        caption_input_element.send_keys(Keys.DELETE)
        caption_input_element.send_keys(h1_caption_text)
        print("キャプションのペースト: 成功")
        sleep(3)
    except:
        print("キャプションのペースト: 失敗")
        break

    # 2回目の完了ボタンの押下
    try:
        done_button = browser.find_element(By.XPATH, '//div[@role="button" and @tabindex="0" and contains(text(), "完了")]')
        done_button.click()
        print("2回目の完了ボタン押下: 成功")
        sleep(1)
    except:
        print("2回目の完了ボタン押下: 失敗")
        break

    # 投稿リンクの削除
    try:
        post_elements.pop(0)
        print("投稿リンクの削除: 成功")
    except:
        print("投稿リンクの削除: 失敗")
        break

    # ループ処理後の待機時間
    if search_index >= len(post_elements):
        print("全投稿処理完了のため30分間待機")
        sleep(1800)  # 秒単位
        search_index = 0

'''

上記のコードを実行すると、下記のエラーが表示されます。説明部分は省略して、インデントを付与して改修部分のコードのみ表示してください

'''

---------------------------------------------------------------------------
NoSuchElementException                    Traceback (most recent call last)
Cell In [8], line 152
    151 try:
--> 152     caption_input_element = browser.find_element(By.XPATH, '//div[@aria-label]')
    153     print("Xpath(area-label検索)でテキストエリアの選択: 成功")

File ~/.config/jupyterlab-desktop/jlab_server/lib/python3.8/site-packages/selenium/webdriver/remote/webdriver.py:831, in WebDriver.find_element(self, by, value)
    829     value = f'[name="{value}"]'
--> 831 return self.execute(Command.FIND_ELEMENT, {"using": by, "value": value})["value"]

File ~/.config/jupyterlab-desktop/jlab_server/lib/python3.8/site-packages/selenium/webdriver/remote/webdriver.py:440, in WebDriver.execute(self, driver_command, params)
    439 if response:
--> 440     self.error_handler.check_response(response)
    441     response["value"] = self._unwrap_value(response.get("value", None))

File ~/.config/jupyterlab-desktop/jlab_server/lib/python3.8/site-packages/selenium/webdriver/remote/errorhandler.py:245, in ErrorHandler.check_response(self, response)
    244     raise exception_class(message, screen, stacktrace, alert_text)  # type: ignore[call-arg]  # mypy is not smart enough here
--> 245 raise exception_class(message, screen, stacktrace)

NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":"//div[@aria-label]"}
  (Session info: chrome=113.0.5672.53)
Stacktrace:
#0 0x558c98e8f133 <unknown>
#1 0x558c98bc3966 <unknown>

During handling of the above exception, another exception occurred:

InvalidSelectorException                  Traceback (most recent call last)
Cell In [8], line 157
    155 print("Xpath(area-label検索)でテキストエリアの選択: 失敗")
    156 try:
--> 157     caption_input_element = browser.find_element(By.XPATH, f"//*[,.format(text)")
    158     print("Xpath(text検索)でテキストエリアの選択: 成功")
    159 except NoSuchElementException:

File ~/.config/jupyterlab-desktop/jlab_server/lib/python3.8/site-packages/selenium/webdriver/remote/webdriver.py:831, in WebDriver.find_element(self, by, value)
    828     by = By.CSS_SELECTOR
    829     value = f'[name="{value}"]'
--> 831 return self.execute(Command.FIND_ELEMENT, {"using": by, "value": value})["value"]

File ~/.config/jupyterlab-desktop/jlab_server/lib/python3.8/site-packages/selenium/webdriver/remote/webdriver.py:440, in WebDriver.execute(self, driver_command, params)
    438 response = self.command_executor.execute(driver_command, params)
    439 if response:
--> 440     self.error_handler.check_response(response)
    441     response["value"] = self._unwrap_value(response.get("value", None))
    442     return response

File ~/.config/jupyterlab-desktop/jlab_server/lib/python3.8/site-packages/selenium/webdriver/remote/errorhandler.py:245, in ErrorHandler.check_response(self, response)
    243         alert_text = value["alert"].get("text")
    244     raise exception_class(message, screen, stacktrace, alert_text)  # type: ignore[call-arg]  # mypy is not smart enough here
--> 245 raise exception_class(message, screen, stacktrace)

InvalidSelectorException: Message: invalid selector: Unable to locate an element with the xpath expression //*[,.format(text) because of the following error:
SyntaxError: Failed to execute 'evaluate' on 'Document': The string '//*[,.format(text)' is not a valid XPath expression.
  (Session info: chrome=113.0.5672.53)
Stacktrace:
#0 0x558c98e8f133 <unknown>
#1 0x558c98bc3966 <unknown>