簡體   English   中英

如何在 Python 中使用 chrome webdriver 在 selenium 中正確使用循環?

[英]How to properly use loop in selenium using chrome webdriver in Python?

我有一個網站有多個輸入字段,其中包含我想用 (Y) 替換的具有相同值 (X) 的 URL。 基本上,對於所有出現的 URL X,我想自動將 URL X 替換為 URL Y。每個輸入字段的右側都有一個編輯和保存按鈕。 每次您單擊“保存”時,都會為您更新的每個字段彈出一個警報。 簡而言之,我需要自動化的整個工作流程。

我在我的代碼中可以為一個字段成功執行此操作,但是當我使用 for 循環時,它只會更新一個元素/字段兩次而不是 rest。僅供參考 - 我將我的 for 循環限制為兩次迭代使用itertools.islice 是有意使用的,因為我想在完全運行之前將測試限制在一小部分。

下面是頁面的截圖: HTML

新錯誤:


C:\Users\me\OneDrive\Documents\Python\Web page entry automation\preferences_v3 copy.py:21: DeprecationWarning: use options instead of chrome_options   chrome_browser = webdriver.Chrome(service=service, chrome_options=chrome_options)

DevTools listening on ws://127.0.0.1:61787/devtools/browser/155908c1-8be2-40a1-85bf-27c44bf25506 Traceback (most recent call last):   File "C:\Users\me\OneDrive\Documents\Python\Web page entry automation\preferences_v3 copy.py", line 90, in <module>
    auto_ftp_url()   File "C:\Users\me\OneDrive\Documents\Python\Web page entry automation\preferences_v3 copy.py", line 57, in auto_ftp_url
    number = elem.get_attribute("id").split("_")[-1]
             ^^^^^^^^^^^^^^^^^^^^^^^^   File "C:\Users\me\AppData\Roaming\Python\Python311\site-packages\selenium\webdriver\remote\webelement.py", line 177, in get_attribute
    attribute_value = self.parent.execute_script(
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^   File "C:\Users\me\AppData\Roaming\Python\Python311\site-packages\selenium\webdriver\remote\webdriver.py", line 500, in execute_script
    return self.execute(command, {"script": script, "args": converted_args})["value"]
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   File "C:\Users\me\AppData\Roaming\Python\Python311\site-packages\selenium\webdriver\remote\webdriver.py", line 440, in execute
    self.error_handler.check_response(response)   File "C:\Users\me\AppData\Roaming\Python\Python311\site-packages\selenium\webdriver\remote\errorhandler.py", line 245, in check_response
    raise exception_class(message, screen, stacktrace) selenium.common.exceptions.StaleElementReferenceException: Message: stale element reference: element is not attached to the page document  (Session info: chrome=109.0.5414.120) Stacktrace: Backtrace:
        (No symbol) [0x00506643]
        (No symbol) [0x0049BE21]
        (No symbol) [0x0039DA9D]
        (No symbol) [0x003A09E4]
        (No symbol) [0x003A08AD]
        (No symbol) [0x003A12E5]
        (No symbol) [0x004079F7]
        (No symbol) [0x003EFD7C]
        (No symbol) [0x00406B09]
        (No symbol) [0x003EFB76]
        (No symbol) [0x003C49C1]
        (No symbol) [0x003C5E5D]
        GetHandleVerifier [0x0077A142+2497106]
        GetHandleVerifier [0x007A85D3+2686691]
        GetHandleVerifier [0x007ABB9C+2700460]
        GetHandleVerifier [0x005B3B10+635936]
        (No symbol) [0x004A4A1F]
        (No symbol) [0x004AA418]
        (No symbol) [0x004AA505]
        (No symbol) [0x004B508B]
        BaseThreadInitThunk [0x771300F9+25]
        RtlGetAppContainerNamedObjectPath [0x77847BBE+286]
        RtlGetAppContainerNamedObjectPath [0x77847B8E+238]

PS C:\Users\me\OneDrive\Documents\Python\Web page entry automation> [15148:25476:0201/123239.502:ERROR:device_event_log_impl.cc(215)] [12:32:39.502] USB: usb_service_win.cc:415 Could not read device interface GUIDs: The system cannot find the file specified. (0x2) [15148:25476:0201/123239.557:ERROR:device_event_log_impl.cc(215)] [12:32:39.557] USB: usb_device_handle_win.cc:1046 Failed to read descriptor from node connection: A device attached to the system is not functioning. (0x1F) [15148:25476:0201/123239.575:ERROR:device_event_log_impl.cc(215)] [12:32:39.575] USB: usb_device_handle_win.cc:1046 Failed to read descriptor from node connection: A device attached to the system is not functioning. (0x1F)

下面是我的代碼:

from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.common.alert import Alert
import itertools


def auto_ftp_url():
    username, password = login()

    chrome_options = Options()
    chrome_options.add_experimental_option("detach", True)

    service = Service(
        r"C:\Users\me\OneDrive\Documents\chromedriver_win32\chromedriver.exe"
    )

    chrome_browser = webdriver.Chrome(service=service, chrome_options=chrome_options)
    chrome_browser.get("https://somelink")

    # send text to username field
    userElem = chrome_browser.find_element(by="id", value="Username")
    userElem.click()
    userElem.send_keys(f"{username}")

    # send password to password field
    passwordElem = chrome_browser.find_element(by="id", value="Password")
    passwordElem.click()
    passwordElem.send_keys(f"{password}")

    # click login
    loginElem = chrome_browser.find_element(by="id", value="Button1")
    loginElem.click()

    # add some delay (2 seconds) to the webdriver so that the elements will load
    chrome_browser.implicitly_wait(2)

    # click on Admin button on left navigation pane
    adminElem = chrome_browser.find_element(By.XPATH, "//*[@id='btnAdminPage']")
    adminElem.click()

    # click on Data FTP button in the top center
    data_ftp_Elem = chrome_browser.find_element(
        By.XPATH, "//*[@id='menu-outer']/div[12]/a/div"
    )
    data_ftp_Elem.click()

    # find FTP URL with a value of 'aftersoftna.com'
    ftp_url_Elem = chrome_browser.find_elements(
        By.XPATH, "//*[@value='aftersoftna.com']"
    )
    for elem in itertools.islice(ftp_url_Elem, 2):
        if elem:  # if the value is 'aftersoftna.com' then do the following
            # click edit button
            editElem = chrome_browser.find_element(
                By.XPATH, "//*[@id='ContentPlaceHolder1_gvFTP_btnSave_7']"
            )
            editElem.click()
            # use WebDriverWait to wait for the element to be clickable
            textElem = WebDriverWait(chrome_browser, 20).until(
                EC.element_to_be_clickable(
                    (By.XPATH, "//*[@id='ContentPlaceHolder1_gvFTP_txtFtpUrl_7']")
                )
            )
            textElem.click()
            textElem.clear()
            textElem.send_keys(
                "catalog.com"
            )  # after clearing the old URL, enter the new URL
            # click save
            saveElem = chrome_browser.find_element(
                By.XPATH, "//*[@id='ContentPlaceHolder1_gvFTP_btnSave_7']"
            )
            saveElem.click()
            # popup or alert message comes up confirming changes saved. click ok
            WebDriverWait(chrome_browser, 10).until(EC.alert_is_present())
            chrome_browser.switch_to.alert.accept()


def login():
    username = input("Username: ")
    password = input("Password: ")
    return username, password


auto_ftp_url()

沒有看到頁面就不可能知道,但我猜這是因為你對每個 URL 的editElemtextElemsaveElem使用了相同的定位器。它們都以“_7”結尾,但我假設有頁面上的多個元素,您所描述的每個 URL 一組三個,例如“_8”、“_9”等。如果這是真的,那么您的定位器需要相對於您要編輯的 URL。

如果我進一步猜測,您應該能夠獲取ftp_url_Elem元素列表,從循環中的每個元素中獲取 ID,然后從ContentPlaceHolder1_gvFTP_txtFtpUrl_7中提取最終數字,例如7 ,然后將其外推到另一個 ID, ContentPlaceHolder1_gvFTP_btnSave_7

要獲得與行號對應的幻數,我們可以

  1. 使用elem.get_attribute("id")獲取第一個 ID, ContentPlaceHolder1_gvFTP_txtFtpUrl_7
  2. 用“_”拆分該 ID,得到['ContentPlaceHolder1','gvFTP','txtFtpUrl','7']
  3. 從該列表中獲取最后一個實例,即所需的行號“7”
  4. 現在我們可以將 append 這個數字加到其他元素的 ID 的“前綴”上,以獲得表格匹配行上的正確元素,例如編輯/保存按鈕的 ID 前綴, ContentPlaceHolder1_gvFTP_btnSave_ ,並添加“7”以獲得ContentPlaceHolder1_gvFTP_btnSave_7

然后,您只需為該行中需要單擊的所有元素重復最后一步。

這里以所有代碼為例

for elem in itertools.islice(ftp_url_Elem, 2):
    if elem:  # if the value is 'aftersoftna.com' then do the following
        # get row number from element ID
        row_number = elem.get_attribute("id").split("_")[-1]
        # click edit button
        editElem = chrome_browser.find_element(
            By.XPATH, "//*[@id='ContentPlaceHolder1_gvFTP_btnSave_" + row_number + "']"
        )
        ... and so on

如果這足以為您指出正確的方向來自行修復它,那就太好了。 如果沒有,請發布 HTML 的一些示例行,其中包含編輯、URL 字段和保存按鈕,以便我們可以創建代碼和相關定位器。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM