无法使用Selenium send_keys()到WYSWYG编辑器

时间:2019-09-24 23:31:40

标签: python html selenium

我正在尝试自动将文章发布到我的博客,该博客由Naver与Selenium提供服务。

问题是我无法将文本输入编辑器。 我尝试使用send_keys(),但是它不起作用。 这是我尝试过的Python Selenium代码。

driver = webdriver.Chrome('./chromedriver')    

driver.get('https://section.blog.naver.com')
driver.find_element_by_xpath("//a[@class = 'login_button']").click()
time.sleep(1)

driver.execute_script("document.getElementsByName('id')[0].value=\'" + user_id + "\'")
driver.execute_script("document.getElementsByName('pw')[0].value=\'" + password + "\'")
driver.find_element_by_xpath("//input[@title = 'Sign in']").click()
time.sleep(1)

driver.find_element_by_xpath("//a[@bg-nclick = 'hmp*s.write']").click()
time.sleep(1)

driver.switch_to.window(driver.window_handles[-1])
driver.switch_to.frame('mainFrame')

driver.find_element_by_xpath("/html/body/div[1]/div/div[2]/div[2]/div/div/div/div[1]/article/div/header/button").click()
driver.find_element_by_xpath("/html/body/div[1]/div/div[2]/div[2]/div/div/div/div[1]/div[2]/section/article/div[1]/div").click()

#This line is being a problem.
driver.find_element_by_xpath("/html/body/div[1]/div/div[2]/div[2]/div/div/div/div[1]/div[2]/section/article/div[1]/div[1]/div/div/p/span").send_keys('Heading1')

它引发如下异常。

---------------------------------------------------------------------------
ElementNotInteractableException           Traceback (most recent call last)
<ipython-input-50-e483e0f23c79> in <module>
     25 driver.find_element_by_xpath("/html/body/div[1]/div/div[2]/div[2]/div/div/div/div[1]/article/div/header/button").click()
     26 driver.find_element_by_xpath("/html/body/div[1]/div/div[2]/div[2]/div/div/div/div[1]/div[2]/section/article/div[1]/div").click()
---> 27 driver.find_element_by_xpath("/html/body/div[1]/div/div[2]/div[2]/div/div/div/div[1]/div[2]/section/article/div[1]/div[1]/div/div/p/span").send_keys('Heading1')
     28 #driver.execute_script("document.getElementByXpath('/html/body/div[1]/div/div[2]/div[2]/div/div/div/div[1]/div[2]/section/article/div[1]/div[1]/div/div/p/span').value='Heading1'")

~/anaconda3/lib/python3.7/site-packages/selenium/webdriver/remote/webelement.py in send_keys(self, *value)
    477         self._execute(Command.SEND_KEYS_TO_ELEMENT,
    478                       {'text': "".join(keys_to_typing(value)),
--> 479                        'value': keys_to_typing(value)})
    480 
    481     # RenderedWebElement Items

~/anaconda3/lib/python3.7/site-packages/selenium/webdriver/remote/webelement.py in _execute(self, command, params)
    631             params = {}
    632         params['id'] = self._id
--> 633         return self._parent.execute(command, params)
    634 
    635     def find_element(self, by=By.ID, value=None):

~/anaconda3/lib/python3.7/site-packages/selenium/webdriver/remote/webdriver.py in execute(self, driver_command, params)
    319         response = self.command_executor.execute(driver_command, params)
    320         if response:
--> 321             self.error_handler.check_response(response)
    322             response['value'] = self._unwrap_value(
    323                 response.get('value', None))

~/anaconda3/lib/python3.7/site-packages/selenium/webdriver/remote/errorhandler.py in check_response(self, response)
    240                 alert_text = value['alert'].get('text')
    241             raise exception_class(message, screen, stacktrace, alert_text)
--> 242         raise exception_class(message, screen, stacktrace)
    243 
    244     def _value_or_default(self, obj, key, default):

ElementNotInteractableException: Message: element not interactable

我确实知道“ ElementNotInteractableException:消息:元素不可交互”的含义。 尽管我尝试了所有可能的Xpath来查找可以使用send_keys()的元素,但还是失败了。随后是相同的例外。

因此,我研究了Web编辑器的源代码。通过使用iframe和带有自动生成的ID的许多元素,它以不熟悉的方式工作。这就是编辑器的样子。

enter image description here

这是一段简短的视频,可能会让您更加了解编辑器的工作原理。

https://youtu.be/os2ruSV4jBU

如果您有任何想法我应该尝试什么,请告诉我。

*编辑

您可以在python代码中看到,我正在考虑将javascript用于网络自动化。但是,问题是我怀疑是span元素的input元素具有自动生成的随机ID。唯一可能的选择是使用Xpath,但是不幸的是,Javascript没有getElementByXpath()

enter image description here

1 个答案:

答案 0 :(得分:2)

编辑1-Javascript方法

您可以尝试使用JavaScript将文本发送到span元素。

以下是示例:

driver.executeScript("document.getElementById('elementID').setAttribute('value', 'yourTextHere')");

您可以将“ elementId”替换为span元素的ID。

编辑2-具有XPath的Javascript方法

我知道您的span包含动态ID,并且无法通过XPath以外的任何其他方法进行定位。对于此解决方案,我们可以使用XPath来获取span,然后获取ID来传递给Javascript方法。

IWebElement textAreaElement = driver.findElement(By.XPath("//article//span"));
string textAreaElementId = textAreaElement.GetAttribute("id");
driver.executeScript("document.getElementById('" + textAreaElementId + "').setAttribute('value', 'yourTextHere')");

在此示例中,使用XPath查找span元素,然后获取其ID属性。您将ID属性传递给JS函数,以正确定位span元素。

或者,您也可以尝试以下操作:

IWebElement textAreaElement = driver.findElement(By.XPath("//article//span"));
driver.executeScript("arguments[0].setAttribute('value', 'yourTextHere')", textAreaElement);

在这种情况下,您是将元素本身直接传递到JS函数中。

附加编辑

我注意到您对某些定位器使用绝对XPath。如果您想完全简化它们,可以使用相对的XPath表示法,如我上面使用的://。我将为您提供一些可以简化的XPath的示例:

绝对XPath#1

driver.find_element_by_xpath("/html/body/div[1]/div/div[2]/div[2]/div/div/div/div[1]/article/div/header/button").click()

相对XPath#1

driver.find_element_by_xpath("//article/div/header/button").click()

绝对XPath#2

driver.find_element_by_xpath("/html/body/div[1]/div/div[2]/div[2]/div/div/div/div[1]/div[2]/section/article/div[1]/div").click()

相对XPath#2

driver.find_element_by_xpath("//article/div[1]/div").click()

使用XPath无需完全从文档html节点的顶部开始。您可以使用//表示法从页面上的任何位置启动XPath。