我无法使用selenium将图像上传到谷歌表单

问题描述 投票:0回答:1

我在使用 Selenium 和 unDetected_chromedriver 自动上传 Google 表单中的文件(照片)时遇到问题。我的目标是填写 Google 表单并通过“文件”输入字段上传图像。然而,我面临着一个重大挑战:表单包含一个 iframe,并且 iframe 的 ID 在每次加载时都会发生变化,使得与 iframe 内的元素进行交互变得困难。 问题

当我尝试与 iframe 内的元素交互以上传文件时,我注意到 iframe 的 ID 会动态变化,这会阻止 Selenium 在每次运行时可靠地定位元素。我的目标是成功地在此 iframe 内导航并上传照片,但我在处理动态 iframe ID 方面遇到了困难。 我尝试过的事情

Locating the iframe using XPath: I’ve used WebDriverWait to wait for the iframe to be present before selecting it. However, since the iframe’s ID changes on each run, this isn’t reliable.

Switching to the iframe using CSS Selectors: I also tried locating the iframe using a generic CSS selector (like iframe), but this fails when the page structure changes.

Sending the file path via send_keys(): Once I manage to navigate to the iframe, I try to click on the “Browse” button, but sometimes the element isn’t interactive yet, causing errors.

我的目标

我正在寻找一个解决方案,让我能够:

Reliably locate and interact with the iframe, despite the dynamic change of its ID.
Click the "Browse" button (or equivalent) inside the iframe.
Upload a photo using the "file" input field.
Submit the form after uploading the file.

具体问题

How can I handle the dynamic change of the iframe’s ID? Is there a more robust way to select the iframe even when its ID keeps changing (for example, using another attribute like class or name)?

What are the best ways to ensure the "Browse" element is clickable? I’d like to know if there are reliable approaches for interacting with elements inside a dynamic iframe by waiting for them to become truly interactive.

Do you have suggestions for avoiding errors related to timing issues? How can I improve the management of wait times and avoid synchronization problems between interacting with the page and the iframe?

我非常感谢有关此问题的任何帮助或建议。如果您遇到过类似的情况或有在 Selenium 中管理动态 iframe 的技巧,我很想听听您的见解。

非常感谢您的时间和专业知识!

import undetected_chromedriver as webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import os
import time

# Configuration des options de Chrome
options = webdriver.ChromeOptions()
profile = r"C:\\Users\\User\\AppData\\Local\\Google\\Chrome\\User Data\\Profile 1"
options.add_argument(f"user-data-dir={profile}")
options.add_argument("profile-directory=Profile 1")
driver = webdriver.Chrome(options=options, use_subprocess=True)

# Chemin du fichier à uploader
file_path = os.path.abspath("./01.png")  # Remplacez par le chemin réel de votre fichier

try:
    # Étape 1 : Ouvrir le formulaire
    print("Étape 1 : Ouvrir le formulaire")
    try:
        driver.get("https://forms.gle/HcKLXz9ErXkm63qK8")
        print("Formulaire ouvert avec succès.")
    except Exception as e:
        print(f"Erreur à l'étape 1 : {e}")
        driver.quit()
        exit()

    # Étape 2 : Cliquer sur le bouton "Add File" pour ouvrir le popup
    print("Étape 2 : Cliquer sur le bouton 'Add File'")
    try:
        add_file_button = WebDriverWait(driver, 10).until(
            EC.element_to_be_clickable((By.XPATH, "/html/body/div/div[3]/form/div[2]/div/div[2]/div/div/div/div[2]/div/div[3]/span/span[2]"))
        )
        add_file_button.click()
        print("Bouton 'Add File' cliqué avec succès.")
    except Exception as e:
        print(f"Erreur à l'étape 2 : {e}")
        driver.quit()
        exit()

    # Étape 3 : Localiser et basculer vers l'iframe
    print("Étape 3 : Localiser et passer à l'iframe")
    try:
        iframe = WebDriverWait(driver, 20).until(
            EC.presence_of_element_located((By.CSS_SELECTOR, "iframe"))
        )
        driver.switch_to.frame(iframe)
        print("Passé à l'iframe avec succès.")
    except Exception as e:
        print(f"Erreur à l'étape 3 : {e}")
        driver.quit()
        exit()

    # Étape 4 : Cliquer sur le bouton "Browse" dans l'iframe
    print("Étape 4 : Cliquer sur le bouton 'Browse'")
    try:
        browse_button = WebDriverWait(driver, 10).until(
            EC.element_to_be_clickable((By.XPATH, "/html/body/div[1]/div[2]/div[3]/div[2]/div[2]/div/div/div/div[1]/div/div[2]/div/button"))
        )
        browse_button.click()
        print("Bouton 'Browse' cliqué avec succès.")
    except Exception as e:
        print(f"Erreur à l'étape 4 : {e}")
        driver.quit()
        exit()

    # Étape 5 : Trouver le champ input et envoyer le chemin du fichier
    print("Étape 5 : Envoyer le chemin du fichier au champ de téléchargement")
    try:
        file_input = WebDriverWait(driver, 10).until(
            EC.presence_of_element_located((By.CSS_SELECTOR, "input[type='file']"))
        )
        file_input.send_keys(file_path)
        print("Fichier téléchargé avec succès.")
    except Exception as e:
        print(f"Erreur à l'étape 5 : {e}")
        driver.quit()
        exit()

    # Étape 6 : Revenir au contexte principal et soumettre le formulaire
    print("Étape 6 : Soumettre le formulaire")
    try:
        driver.switch_to.default_content()  # Revenir au contexte principal
        submit_button = WebDriverWait(driver, 10).until(
            EC.element_to_be_clickable((By.XPATH, "/html/body/div/div[3]/form/div[2]/div/div[3]/div/div[1]/div/span"))
        )
        submit_button.click()
        print("Formulaire soumis avec succès.")
    except Exception as e:
        print(f"Erreur à l'étape 6 : {e}")
        driver.quit()
        exit()

except Exception as e:
    print(f"Erreur générale : {e}")

finally:
    time.sleep(5)  # Attendre avant de fermer
    driver.quit()

我想将图片上传到 Google 表单

selenium-webdriver google-forms
1个回答
0
投票

使用 XPath 定位 iframe:我使用 WebDriverWait 等待 iframe 出现后再选择它。但是,由于 iframe 的 ID 在每次运行时都会发生变化,因此这是不可靠的。

假设这是您正在寻找的第二个 iframe

driver.findElement(By.xpath("//div[contains(@class,'picker-dialog-content')]/descendant::iframe")

使用CSS选择器切换到iframe:我还尝试使用通用CSS选择器(如iframe)来定位iframe,但是当页面结构发生变化时,这会失败。

使用上面的代码获取 iframe 的当前 id,然后执行 driver.switchTo().iframe

通过send_keys()发送文件路径:当我成功导航到iframe后,我尝试单击“浏览”按钮,但有时该元素尚未交互,从而导致错误。

只需等待按钮可点击即可

WebElement 按钮 = wait.until(ExpectedConditions.elementToBeClickable(By.id("buttonID")));

您可能需要尝试一些不同的方法才能使其正常工作,但是一旦您修复了切换到 iframe 的问题,其余的事情就应该很简单了。希望这有帮助

© www.soinside.com 2019 - 2024. All rights reserved.