You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Shopify产品添加界面中Selenium操作iframe时脚本冻结问题求助

Shopify产品描述iframe自动化冻结问题

我正在编写Selenium脚本自动化填充Shopify产品列表,需要在HTML模式下的iframe中输入产品描述,但激活iframe时等待条件不触发,浏览器直接冻结,鼠标停留在超链接手势状态,脚本无报错退出。手动中断后得到KeyboardInterrupt报错。

我的代码

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException
import time

from dbase import get_vars, database_path, sheet_name, vendor_checkbox, login_, pw_
from LoginStart import Login
# from Pegador2 import inums
from commons.navigation import new_tab_

(...)

for index, row in dataframe.iloc[1:].iterrows():

(...)

    # Click the thingy that switches to html
    pshowhtml = driver.find_element(By.CSS_SELECTOR, 'button[aria-label="Show HTML"]')
    wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, 'button[aria-label="Show HTML"]')))
    pshowhtml.click()

    # Activate the iframe for the Description and send it
    desc_iframe = driver.find_element(By.ID, 'product-description_ifr')
    wait.until(EC.frame_to_be_available_and_switch_to_it((By.ID, 'product-description_ifr')))
    # driver.switch_to.frame(desc_iframe)
    wait.until(EC.element_to_be_clickable((By.ID, 'tinymce')))  # The freeze occurs around here
    product_description_iframe = driver.find_element(By.ID, 'tinymce')
    product_description_iframe.send_keys(row[2])
    driver.switch_to.default_content()

    # Click it again
    pshowhtml = driver.find_element(By.CSS_SELECTOR, 'button[aria-label="Show editor"]')
    wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, 'button[aria-label="Show editor"]')))
    pshowhtml.click()

(...)

Shopify对应界面HTML结构

<div id="product-description_parent">

<div id="product-description_iframecontainer">

<iframe id="product-description_ifr" frameborder="0" allowtransparency="true" title="Rich Text Area. Press ALT-F9 for menu. Press ALT-F10 for toolbar. Press ALT-0 for help" src="javascript:&quot;&quot;" style="width: 100%; height: 168px; display: block; min-height: 150px;">

<!DOCTYPE html><html style="overflow-y: hidden;">

<head><style id="mceDefaultStyles" type="text/css">
p {
margin-top: 0;
}

html, body {
cursor: text;
}

html {
font-size: 100%;
}

body {
overflow-x: hidden;
font-family: -apple-system, BlinkMacSystemFont, San Francisco, Segoe UI, Roboto, Helvetica Neue, sans-serif;
font-size: 0.875rem; /* Maps to var(--p-font-size-100) */
line-height: 1.4;
color: #1f2124; /* Maps to var(--p-color-text) */
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
margin: 0.6rem 0.75rem;
}
@media only screen and (max-device-width: 40em) {
body {
font-size: 1rem;
}
}

/* The body y margin of 0.66rem works well for type, but is too tight for solid elements. Push them down a bit. */
body > img:first-child,
body > iframe:first-child {
margin-top: .15rem;
}

h1 {
line-height: 1.2;
}

h1 {
margin: 0 0 .75rem;
}

h2, h3, h4, h5, h6 {
margin: 0 0 .66rem 0;
}

p, img, iframe {
margin: 0 0 1rem;
}

p > img,
p > iframe {
margin-bottom: 0;
}

body > *:last-child {
margin-bottom: 0;
}

table {
width: 100%;
}

table, td, th {
border: 1px dashed #CCC;
}

body {
min-height: 150px;
}

.mce-content-body div.mce-resizehandle {position: absolute;border: 1px solid black;box-sizing: box-sizing;background: #FFF;width: 7px;height: 7px;z-index: 10000}.mce-content-body .mce-resizehandle:hover {background: #000}.mce-content-body img[data-mce-selected],.mce-content-body hr[data-mce-selected] {outline: 1px solid black;resize: none}.mce-content-body .mce-clonedresizable {position: absolute;outline: 1px dashed black;opacity: .5;filter: alpha(opacity=50);z-index: 10000}.mce-content-body .mce-resize-helper {background: #555;background: rgba(0,0,0,0.75);border-radius: 3px;border: 1px;color: white;display: none;font-family: sans-serif;font-size: 12px;white-space: nowrap;line-height: 14px;margin: 5px 10px;padding: 5px;position: absolute;z-index: 10001}
.mce-visual-caret {position: absolute;background-color: black;background-color: currentcolor;}.mce-visual-caret-hidden {display: none;}*[data-mce-caret] {position: absolute;left: -1000px;right: auto;top: 0;margin: 0;padding: 0;}
.mce-content-body .mce-offscreen-selection {position: absolute;left: -9999999999px;max-width: 1000000px;}.mce-content-body *[contentEditable=false] {cursor: default;}.mce-content-body *[contentEditable=true] {cursor: text;}
</style><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"></head>



<body id="tinymce" class="mce-content-body " data-id="product-description" contenteditable="true" style="overflow-y: hidden; padding-left: 0px; padding-right: 0px; padding-bottom: 0px;" data-mce-style="overflow-y: auto; padding-left: 0px; padding-right: 0px; padding-bottom: 0px;" data-new-gr-c-s-check-loaded="14.1117.0" data-gr-ext-installed="" data-new-gr-c-s-loaded="14.1117.0" spellcheck="false"><p><span data-sanitized-data-mce-style="text-decoration: underline;" data-mce-style="text-decoration: underline;" style="text-decoration: underline;">&lt;div id="product-description_parent"&gt;</span></p><p><span data-sanitized-data-mce-style="text-decoration: underline;" data-mce-style="text-decoration: underline;" style="text-decoration: underline;">&lt;div id="product-description_iframecontainer"&gt;</span></p><p><span data-sanitized-data-mce-style="text-decoration: underline;" data-mce-style="text-decoration: underline;" style="text-decoration: underline;">&lt;iframe id="product-description_ifr" frameborder="0" allowtransparency="true" title="Rich Text Area. Press ALT-F9 for menu. Press ALT-F10 for toolbar. Press ALT-0 for help" src="javascript:&amp;quot;&amp;quot;" style="width: 100%; height: 168px; display: block; min-height: 150px;"&gt;</span></p><p><span data-sanitized-data-mce-style="text-decoration: underline;" data-mce-style="text-decoration: underline;" style="text-decoration: underline;"><br data-sanitized-data-mce-bogus="1" data-mce-bogus="1"></span></p><p><span data-sanitized-data-mce-style="text-decoration: underline;" data-mce-style="text-decoration: underline;" style="text-decoration: underline;">&lt;/iframe&gt;&lt;/div&gt;&lt;/div&gt;</span><!----></p></body><grammarly-desktop-integration data-grammarly-shadow-root="true"></grammarly-desktop-integration></html>

</iframe></div></div>

手动中断后的报错信息

Under Armour Men's Armour Fleece Hoodie (Black)
Traceback (most recent call last):
  File "C:\Users\fvckr\OneDrive\Documents\Code\py\jon\jonMain.py", line 56, in <module>
    product_description_iframe.send_keys(row[2])
  File "C:\Users\fvckr\OneDrive\Documents\Code\py\venv\Lib\site-packages\selenium\webdriver\remote\webelement.py", line 231, in send_keys
    self._execute(
  File "C:\Users\fvckr\OneDrive\Documents\Code\py\venv\Lib\site-packages\selenium\webdriver\remote\webelement.py", line 403, in _execute
    return self._parent.execute(command, params)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\fvckr\OneDrive\Documents\Code\py\venv\Lib\site-packages\selenium\webdriver\remote\webdriver.py", line 438, in execute
    response = self.command_executor.execute(driver_command, params)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\fvckr\OneDrive\Documents\Code\py\venv\Lib\site-packages\selenium\webdriver\remote\remote_connection.py", line 290, in execute
    return self._request(command_info[0], url, body=data)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\fvckr\OneDrive\Documents\Code\py\venv\Lib\site-packages\selenium\webdriver\remote\remote_connection.py", line 311, in _request
    response = self._conn.request(method, url, body=body, headers=headers)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\fvckr\OneDrive\Documents\Code\py\venv\Lib\site-packages\urllib3\request.py", line 78, in request
    return self.request_encode_body(
           ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\fvckr\OneDrive\Documents\Code\py\venv\Lib\site-packages\urllib3\request.py", line 170, in request_encode_body
    return self.urlopen(method, url, **extra_kw)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\fvckr\OneDrive\Documents\Code\py\venv\Lib\site-packages\urllib3\poolmanager.py", line 376, in urlopen
    response = conn.urlopen(method, u.request_uri, **kw)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\fvckr\OneDrive\Documents\Code\py\venv\Lib\site-packages\urllib3\connectionpool.py", line 703, in urlopen
    httplib_response = self._make_request(
                       ^^^^^^^^^^^^^^^^^^^
  File "C:\Users\fvckr\OneDrive\Documents\Code\py\venv\Lib\site-packages\urllib3\connectionpool.py", line 449, in _make_request
    six.raise_from(e, None)
  File "<string>", line 3, in raise_from
  File "C:\Users\fvckr\OneDrive\Documents\Code\py\venv\Lib\site-packages\urllib3\connectionpool.py", line 444, in _make_request
    httplib_response = conn.getresponse()
                       ^^^^^^^^^^^^^^^^^^
  File "C:\Users\fvckr\AppData\Local\Programs\Python\Python311\Lib\http\client.py", line 1377, in getresponse
    self.close()
  File "C:\Users\fvckr\AppData\Local\Programs\Python\Python311\Lib\http\client.py", line 954, in close
    def close(self):

KeyboardInterrupt

Process finished with exit code -1073741510 (0xC000013A: interrupted by Ctrl+C)

我是自学编程数月的新手,首次提问若有表述不当请见谅。已尝试修改等待条件、将选择器改为By.TAGNAME定位'body',但均无效,困惑的是即使添加等待脚本仍会冻结,恳请帮助。


解决方案

  • 修复元素定位顺序问题
    当前代码先获取元素再等待,会导致元素未加载时直接报错,正确逻辑是先等待元素可交互,再执行操作:

    # 切换到HTML模式
    wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, 'button[aria-label="Show HTML"]'))).click()
    
  • 优化iframe切换与元素等待逻辑
    frame_to_be_available_and_switch_to_it已包含切换操作,无需提前获取iframe元素。同时,Shopify的TinyMCE编辑器在HTML模式下,需等待body元素可见且可编辑,而非仅可点击:

    # 切换到描述iframe
    wait.until(EC.frame_to_be_available_and_switch_to_it((By.ID, 'product-description_ifr')))
    # 等待编辑器body可见
    desc_body = wait.until(EC.visibility_of_element_located((By.ID, 'tinymce')))
    # 清空原有内容后输入新描述
    desc_body.clear()
    desc_body.send_keys(row[2])
    # 切回主文档
    driver.switch_to.default_content()
    
  • 处理编辑器加载延迟
    切换到HTML模式后编辑器可能有额外加载时间,可添加超时重试逻辑:

    try:
        wait.until(EC.frame_to_be_available_and_switch_to_it((By.ID, 'product-description_ifr')), timeout=10)
    except TimeoutException:
        # 超时后刷新页面并重试
        driver.refresh()
        wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, 'button[aria-label="Show HTML"]'))).click()
        wait.until(EC.frame_to_be_available_and_switch_to_it((By.ID, 'product-description_ifr')))
    
  • 禁用干扰性浏览器扩展
    HTML结构中存在Grammarly集成元素,这类扩展可能干扰Selenium操作,启动浏览器时禁用扩展:

    chrome_options = webdriver.ChromeOptions()
    chrome_options.add_argument('--disable-extensions')
    driver = webdriver.Chrome(options=chrome_options)
    

内容的提问来源于stack exchange,提问作者Baldomero

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 17:17:02