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:""" 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;"><div id="product-description_parent"></span></p><p><span data-sanitized-data-mce-style="text-decoration: underline;" data-mce-style="text-decoration: underline;" style="text-decoration: underline;"><div id="product-description_iframecontainer"></span></p><p><span data-sanitized-data-mce-style="text-decoration: underline;" data-mce-style="text-decoration: underline;" style="text-decoration: underline;"><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;"></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;"></iframe></div></div></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
相关产品推荐
相关产品推荐

