<iframe frameborder="0" id="nsoPic1674433476127" style="padding: 0px; background-color: white;"></iframe>
And it's 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="" id="nsoPic1674463885278" style="min-width: 0px; direction: ltr; text-align: left;" role="textbox"><p> rwerwer</p></body></html>
I am getting NoSuchElementException
error when trying to enter the above iframe. Below is the code. I just want to enter the text box and use send_keys
.
I tried to this for entering iframe:
driver.switch_to.frame(driver.find_element(By.TAG_NAME, "iframe"))
element = driver.find_element(By.XPATH, '//*[@id=""]/p')
element.send_keys("Hello")
It seems blogger uses a different id for each post post screen so I tried using the id number but failed. I try to use CLASS_NAME
but still I keep getting the same error. I guess I can't get inside the iframe. Can you help me? The whole code block is below.
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.common.exceptions import NoSuchElementException
#information
title = ""
response = ""
blogpost_email = ""
blogpost_password = ""
#blogger entering
driver = uc.Chrome(use_subprocess=True)
url1 = 'https://www.blogger.com/'
driver.get(url1)
#waiting page
time.sleep(5)
driver.find_element(By.XPATH, '/html/body/header/div[1]/div[2]/a[1]/span').click()
#waiting page
time.sleep(5)
#entering information
email_block = driver.find_element(By.XPATH, '//*[@id="identifierId"]')
email_block.send_keys(blogpost_email)
driver.find_element(By.XPATH, '//*[@id="identifierNext"]/div/button').click()
#waiting page
time.sleep(10)
#entering information
block_password_block = driver.find_element(By.XPATH, '//*[@id="password"]/div[1]/div/div[1]/input')
block_password_block.send_keys(blogpost_password)
driver.find_element(By.XPATH, '//*[@id="passwordNext"]/div/button/span').click()
#controlling there is no blog
try:
driver.find_element(By.XPATH, '//*[@id="yDmH0d"]/c-wiz/div/div/div/div[2]/div[4]/div[1]/button/span').click()
except NoSuchElementException:
pass
#waiting page
time.sleep(30)
#entering new post
driver.find_element(By.CLASS_NAME, 'MIJMVe').click()
#waiitng page
time.sleep(10)
#entering information
post_title = driver.find_element(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)
driver.switch_to.frame(driver.find_element(By.TAG_NAME, "iframe"))
element = driver.find_element(By.XPATH, '//*[@id=""]/p')
element.send_keys("Hello")
driver.switch_to.default_content()
#publishing
publish_button = driver.find_element(By.CLASS_NAME, 'ZFr60d CeoRYc')
publish_button.click()
#submiting
submit_button = drive.find_element(By.CLASS_NAME, 'RveJvd snByac')
submit_button.click()
CodePudding user response:
Notice that these commands are different
driver.find_element(By.TAG_NAME, 'iframe') # the one you are using
driver.find_elements(By.TAG_NAME, 'iframe')
The first one returns the first iframe found in the html, while the second one returns the list of all the iframe. The page to create a post contains several iframe, moreover the number of iframe and their ids change each time you create a new post. Also, the iframe you want is never the first one in the html, so when in your code you run
driver.switch_to.frame(driver.find_element(By.TAG_NAME, "iframe"))
you are switching to the wrong iframe. The iframe you want has the following unique xpath
xpath = "//c-wiz[contains(@style,'visibility: visible')]/descendant::iframe[contains(@class,'ZW3ZFc')]"
so you can switch to it with
driver.switch_to.frame(driver.find_element(By.XPATH, xpath))
and then write text with
textbox = driver.find_element(By.CSS_SELECTOR, 'body.editable')
textbox.send_keys("Hello")