使用Selenium无法访问Blogger文章页内的iFrame内容
Blogger编辑器iFrame切换失败,无法执行send_keys问题解决
问题描述
操作Blogger文章编辑页时,尝试切换到内容编辑iFrame并执行send_keys操作时触发NoSuchElementException错误。相关iFrame及内部HTML结构如下:
iFrame代码:
<iframe frameborder="0" class="ZW3ZFc editable" id="nsoPic1674433476127" style="padding: 0px; background-color: white;"></iframe>
iFrame内部HTML:
<html style="background:none transparent;min-width:0;"> <head> <style></style> <style type="text/css">td.tr-caption:empty:after{color:gray;content:"Add caption";}</style> <style type="text/css">img { cursor: move; }</style> </head> <body g_editable="true" hidefocus="true" contenteditable="" class="editable " id="nsoPic1674463885278" style="min-width: 0px; direction: ltr; text-align: left;" role="textbox"> <p> rwerwer</p> </body> </html>
尝试通过标签名切换iFrame,但Blogger的iFrame和内部元素ID动态变化,指定ID或类名均失败,无法成功切换并定位输入元素。
现有代码问题分析
- 硬编码等待不可靠:
time.sleep()固定等待时间,受网络影响易导致元素未加载完成就执行操作,引发找不到元素的错误。 - iFrame定位不准确:仅通过
By.TAG_NAME定位iFrame,若页面存在多个iFrame会定位错误;且未等待iFrame加载完成就切换。 - 内部元素定位错误:使用
//*[@id=""]/p无效XPATH,无法正确定位可编辑元素。 - 类名定位错误:多个类名的元素不能直接用
By.CLASS_NAME,该方法仅支持单个类名。 - 拼写错误:最后一行
drive应为driver。
解决方案
- 用显式等待替代固定睡眠:利用
WebDriverWait等待元素出现,确保元素加载完成后再操作,提升稳定性。 - 准确定位iFrame:通过iFrame的
class属性结合CSS_SELECTOR定位,避免动态ID影响;同时等待iFrame可切换。 - 正确定位可编辑元素:直接定位iFrame内带
contenteditable属性的body元素,这是实际输入区域。 - 修复类名定位:多个类名的元素使用
CSS_SELECTOR,格式为.类名1.类名2。 - 修正拼写错误:将
drive改为driver。
修改后的完整代码
import time from selenium import webdriver from selenium.webdriver.common.by import By from selenium.common.exceptions import NoSuchElementException from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC # 配置信息 title = "测试标题" response = "测试内容" blogpost_email = "你的邮箱" blogpost_password = "你的密码" # 初始化浏览器 driver = uc.Chrome(use_subprocess=True) url1 = 'https://www.blogger.com/' driver.get(url1) # 等待登录按钮并点击 WebDriverWait(driver, 20).until( EC.element_to_be_clickable((By.XPATH, '/html/body/header/div[1]/div[2]/a[1]/span')) ).click() # 输入邮箱并点击下一步 email_block = WebDriverWait(driver, 20).until( EC.visibility_of_element_located((By.XPATH, '//*[@id="identifierId"]')) ) email_block.send_keys(blogpost_email) WebDriverWait(driver, 20).until( EC.element_to_be_clickable((By.XPATH, '//*[@id="identifierNext"]/div/button')) ).click() # 输入密码并点击下一步 block_password_block = WebDriverWait(driver, 20).until( EC.visibility_of_element_located((By.XPATH, '//*[@id="password"]/div[1]/div/div[1]/input')) ) block_password_block.send_keys(blogpost_password) WebDriverWait(driver, 20).until( EC.element_to_be_clickable((By.XPATH, '//*[@id="passwordNext"]/div/button/span')) ).click() # 处理无博客的情况 try: WebDriverWait(driver, 10).until( EC.element_to_be_clickable((By.XPATH, '//*[@id="yDmH0d"]/c-wiz/div/div/div/div[2]/div[4]/div[1]/button/span')) ).click() except NoSuchElementException: pass # 等待页面加载并点击新建文章 WebDriverWait(driver, 30).until( EC.element_to_be_clickable((By.CLASS_NAME, 'MIJMVe')) ).click() # 输入文章标题 post_title = WebDriverWait(driver, 20).until( EC.visibility_of_element_located((By.XPATH, '//*[@id="yDmH0d"]/c-wiz[2]/div/c-wiz/div/div[1]/div[1]/div[1]/div/div[1]/input')) ) post_title.click() post_title.send_keys(title) # 切换到内容编辑iFrame content_iframe = WebDriverWait(driver, 20).until( EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR, 'iframe.ZW3ZFc.editable')) ) # 定位并输入内容到可编辑区域 edit_body = WebDriverWait(driver, 20).until( EC.visibility_of_element_located((By.CSS_SELECTOR, 'body.editable[contenteditable]')) ) edit_body.send_keys(response) # 切回主文档 driver.switch_to.default_content() # 点击发布按钮 publish_button = WebDriverWait(driver, 20).until( EC.element_to_be_clickable((By.CSS_SELECTOR, '.ZFr60d.CeoRYc')) ) publish_button.click() # 点击确认发布按钮 submit_button = WebDriverWait(driver, 20).until( EC.element_to_be_clickable((By.CSS_SELECTOR, '.RveJvd.snByac')) ) submit_button.click() # 可选:关闭浏览器 # driver.quit()
内容的提问来源于stack exchange,提问作者Adzetto
相关产品推荐
相关产品推荐

