【问题标题】:Difference between text and innerHTML using Selenium使用 Selenium 的 text 和 innerHTML 之间的区别
【发布时间】:2017-03-17 21:30:53
【问题描述】:

使用 selenium 时获得 textinnerHTML 有什么区别。即使我们在特定元素下有文本,但当我们执行.text 时,我们会得到空值。但是.get_attribute("innerHTML") 工作正常。

有人能指出两者之间的区别吗?什么时候有人应该使用 '.get_attribute("innerHTML")' 而不是 .text

【问题讨论】:

  • "innerHTML" 将返回此元素的内部 HTML,其中包含其中的所有 HTML 标签,包括文本和标签,如“<p>This is demo</p>"”,而 .text 只会检索其后代的所有文本内容,而没有任何HTML tags.example: "这是演示"
  • 我可以理解这一点....但有时....当您执行以下driver.find_element_by_css_selector("p").text 时将一无所获。但是做 driver.find_element_by_css_selector("p").get_attribute("innerHTML") 会导致提取This is demo....为什么会这样?
  • 问题可能出在您的选择器上...当您使用 driver.find_element_by_css_selector("p").text ....如果您可以分享您正在尝试的网页的网址...我可以更好地解释事情
  • "http://www.costco.com/Weatherproof%C2%AE-Men's-Ultra-Tech-Jacket.product.100106552.html" 尝试使用以下行获取产品标题driver.find_element_by_css_selector("h1[itemprop='name']").text 没有产生任何结果....但是 driver.find_element_by_css_selector("h1[itemprop='name']").get_attribute("innerHTML" ) 得到产品标题"Weatherproof\xae Men's Ultra Tech Jacket"
  • 我用详细信息更新了评论...在添加更多详细信息之前我错误地按下了回车...我的错误

标签: python selenium web-scraping properties attributes


【解决方案1】:

首先,text 是一个属性,而innerHTML 是一个属性propertyattribute 之间从根本上是有一些区别的。


get_attribute("innerHTML")

get_attribute(innerHTML) 获取元素的innerHTML

此方法将首先尝试返回具有给定名称的属性的值。如果不存在具有该名称的属性,则返回具有相同名称的 attribute 的值。如果没有具有该名称的attribute,则返回None

被认为是真实的值,即等于truefalse,将作为布尔值返回。所有其他非None 值都作为字符串返回。对于不存在的属性或属性,返回None

  • 参数:

    innerHTML - Name of the attribute/property to retrieve.
    
  • 例子:

    # Extract the text of an element.
    my_text = target_element.get_attribute("innerHTML") 
    

文字

text 获取元素的文本。

  • 定义:

    def text(self):
    """The text of the element."""
    return self._execute(Command.GET_ELEMENT_TEXT)['value']
    
  • 例子:

    # Extract the text of an element.
    my_text = target_element.text   
    

听起来仍然相似?阅读下文...


Attributes and properties

当浏览器加载页面时,它解析 HTML 并从中生成 DOM 对象。对于元素节点,大多数标准 HTML 属性会自动成为 DOM 对象的属性。

例如,如果标签是:

<body id="page">

那么 DOM 对象有body.id="page"

注意:属性-属性映射不是一对一的!


HTML attributes

在 HTML 中,标签可能具有属性。当浏览器解析 HTML 以创建标签的 DOM 对象时,它会识别标准属性并从中创建 DOM 属性。

所以当一个元素有 id 或另一个标准属性时,相应的属性就会被创建。但如果属性是非标准的,则不会发生这种情况。

注意:一个元素的标准属性对于另一个元素可能是未知的。例如,type&lt;input&gt; 标签的标准属性,但不是 &lt;body&gt; 标签的标准属性。标准属性在相应元素类的规范中进行了描述。

所以,如果一个属性是非标准的,就不会有它的 DOM 属性。在这种情况下,可以使用以下方法访问所有属性:

  • elem.hasAttribute(name):检查是否存在。
  • elem.getAttribute(name):获取值。
  • elem.setAttribute(name, value):设置值。
  • elem.removeAttribute(name):移除属性。

读取非标准属性的示例:

<body something="non-standard">
  <script>
    alert(document.body.getAttribute('something')); // non-standard
  </script>
</body>

Property-attribute synchronization

当标准属性发生变化时,相应的属性会自动更新,并且(有一些例外)反之亦然。但也有例外,例如 input.value 仅从 attribute -> 同步到 property,但不同步。这个特性其实派上用场了,因为用户可以修改值,然后在它之后,如果我们想从HTML中恢复“原始”值,它就在属性中。


根据python中的Attributes and Properties,当我们用someObject.someAttr之类的东西引用对象的属性时,Python使用几种特殊的方法来获取对象的someAttr属性。在最简单的情况下,属性只是实例变量

Python 属性

从更广泛的角度来看:

  • 属性是出现在对象名称之后的名称。这是句法结构。例如,someObj.name
  • 实例变量是对象内部__dict__ 中的一项。
  • 属性引用的默认语义是提供对实例变量的访问。当我们提到someObj.name 时,默认行为实际上是someObj.__dict__['name']

Python 属性

在 Python 中,我们可以使用内置的property() 函数或@property 装饰器将gettersetter(和deleter)函数与属性名称绑定。当我们这样做时,对属性的每个引用都具有直接访问实例变量的语法,但它调用给定的方法函数。

【讨论】:

    【解决方案2】:

    .text 将检索视口中不存在的文本的空字符串,因此您可以将对象滚动到视口并尝试 .text 它应该检索值。

    相反,innerhtml 可以获取值,即使它存在于视口之外

    【讨论】:

      【解决方案3】:

      例如,&lt;div&gt;&lt;span&gt;Example Text&lt;/span&gt;&lt;/div&gt;

      .get_attribute("innerHTML") 为您提供当前元素内的实际 HTML。所以theDivElement.get_attribute("innerHTML") 返回“&lt;span&gt;Example Text&lt;/span&gt;

      .text 只给你文本,不包括 HTML 节点。所以theDivElement.text 返回“Example Text

      请注意,.text算法取决于每个浏览器的 webdriver。在某些情况下,例如元素被隐藏,当您使用不同的 webdriver 时,您可能会得到不同的文本。

      我通常从.get_attribute("innerText") 而不是.text 获取文本,因此我可以处理所有情况。

      【讨论】:

        【解决方案4】:

        Chrome(我不确定其他浏览器)会忽略 HTML 代码中的额外空格并显示为单个空格。

        <div><span>Example  Text</span></div> # notice the two spaces
        

        .get_attribute('innerHTML') 将返回双倍行距文本,这是您在检查元素时会看到的内容),而.text 将返回只有 1 个空格的字符串。

        >>> print(element.get_attribute('innerHTML'))
        'Example  Text'
        >>> print(element.text)
        'Example Text'
        

        这种差异并非微不足道,因为以下将导致 NoSuchElementException。

        >>> arg = '//div[contains(text(),"Example Text")]'    
        >>> driver.find_element_by_xpath(arg)
        

        类似地,.get_attribute('innerHTML') 对于以下返回 Example&amp;nbsp;Text,而 .text 返回 Example Text

        <div><span>Example&nbsp;Text</span></div>
        

        【讨论】:

          【解决方案5】:

          我刚刚选择了css选择器并使用了以下代码:

          from selenium import webdriver
          
          
          driver = webdriver.Chrome()
          driver.maximize_window()
          driver.get("http://www.costco.com/Weatherproof%C2%AE-Men's-Ultra-Tech-Jacket.product.100106552.html")
          print driver.find_element_by_css_selector(".product-h1-container.visible-xl-block>h1").text
          

          然后打印出来:

          Weatherproof® Men's Ultra Tech Jacket
          

          问题是 chrome 或 firefox 上的 h1[itemprop='name'] 选择器返回 2 个匹配节点,而 .product-h1-container.visible-xl-block&gt;h1 只返回一个匹配节点,这就是为什么它打印预期的结果

          为了证明我的观点,运行以下代码:

          from selenium import webdriver
          
          
          driver = webdriver.Chrome()
          driver.maximize_window()
          driver.get("http://www.costco.com/Weatherproof%C2%AE-Men's-Ultra-Tech-Jacket.product.100106552.html")
          x= driver.find_elements_by_css_selector("h1[itemprop='name'] ")
          
          for i in x:
              print "This is line " , i.text
          

          它会打印出来

          This is line  
          This is line  Weatherproof® Men's Ultra Tech Jacket
          

          因为 select_element_by_css_selector 选择了第一个具有匹配选择器的元素并且不包含任何文本,所以它不会打印。希望你现在明白了

          【讨论】:

          • 那太棒了......但在上面的选择和这个driver.find_element_by_css_selector("h1[itemprop='name']").t‌​ext之间没有发现区别......都选择了相同的元素,对吗?......为什么在.text的情况下有效
          • 您的选择器返回 2 个匹配节点,其中一个不包含文本,第二个包含它,而我的只有 1 个包含文本,所以它会打印出来
          • 感谢清晰的解释!!!!我们真的在页面中有两个元素吗...就像一个可见的和一个不可见的...当我们检查元素时无法捕捉到它...这与浏览器有关...还是再次错过了任何琐碎的东西?
          • reviewsCount = driver.find_elements_by_css_selector("li[itemprop='review']") reviewTitle = reviewsCount[0].find_elements_by_css_selector(".bv-content-title") reviewTitle[0].get_attribute("innerHTML") 在这种情况下 reviewTitle 只有一个元素。但在这种情况下 .text 没有工作....
          • @VivekSrinivasan,你能解释一下你要通过这个序列实现什么
          猜你喜欢
          • 2013-10-02
          • 2016-05-31
          • 1970-01-01
          • 2018-04-22
          • 1970-01-01
          • 2016-09-17
          • 2014-10-09
          相关资源
          最近更新 更多