【问题标题】:Selenium WebDriver get_attribute returns truncated value of href attribute when value has entities当值具有实体时,Selenium WebDriver get_attribute 返回 href 属性的截断值
【发布时间】:2018-08-02 01:35:27
【问题描述】:

我正在尝试使用 selenium Webdriver (Python) 从我的应用程序页面上的锚选项卡中获取 href 属性值,并且返回的结果已被部分剥离。

这里是 HTML sn-p -

<a class="nla-row-text" href="/shopping/brands?search=kamera&nm=Canon&page=0" data-reactid="790">

这是我正在使用的代码 -

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains

driver = webdriver.Firefox()
driver.get("xxxx")

url_from_attr = driver.find_element(By.XPATH,"(//div[@class='nla-children mfr']/div/div/a)[1]").get_attribute("href")

url_from_attr_raw = "%r"%url_from_attr

print(" URL from attribute -->> " + url_from_attr)
print(" Raw string -->> " + url_from_attr_raw)

我得到的输出是 -

/shopping/brands?search=kamera&page=0

而不是-

/shopping/brands?search=kamera&nm=Canon&page=0 OR
/shopping/brands?search=kamera&nm=Canon&page=0

这是因为 URL 中的实体表示,我看到实体之间的部分被剥离了吗?任何帮助或指针都会很棒

【问题讨论】:

  • 在幕后会调用 webdriver likeso resp = self._execute(Command.GET_ELEMENT_ATTRIBUTE, {'name': name})。您可以尝试使用其他浏览器来查看是否遇到相同的问题吗?例如。 driver = webdriver.Chrome() 可能是壁虎驱动的问题。
  • 好吧,chromedriver也不行
  • 如果没有任何效果,那么总是使用 JS。您可以参考这个 -> link 并使用 JS 获取 href,参考这个 link

标签: python python-3.x selenium selenium-webdriver html-entities


【解决方案1】:

根据给定的 HTML,您尝试过的 Locator Strategy 存在问题。您使用了索引[1] 以及容易出错的find_element。索引例如当通过find_elements 返回List 时,可以应用[1]。在这个用例中,一个优化的表达式是:

url_from_attr = driver.find_element(By.XPATH,"//div[@class='nla-children mfr']/div/div/a[@class='nla-row-text']").get_attribute("href")

定位策略可以进一步优化如下:

url_from_attr = driver.find_element(By.XPATH,"//div[@class='nla-children mfr']//a[@class='nla-row-text']").get_attribute("href")

更新 A

根据您的评论,您仍然需要使用索引优化的 Locator Strategy 可以是:

url_from_attr = driver.find_elements(By.XPATH,"//div[@class='nla-children mfr']//a[@class='nla-row-text'][1]").get_attribute("href")

get_attribute(attribute_name)

根据Python-API Source

    def get_attribute(self, name):
    """Gets the given attribute or property of the element.

    This method will first try to return the value of a property with the
    given name. If a property with that name doesn't exist, it returns the
    value of the attribute with the same name. If there's no attribute with
    that name, ``None`` is returned.

    Values which are considered truthy, that is equals "true" or "false",
    are returned as booleans.  All other non-``None`` values are returned
    as strings.  For attributes or properties which do not exist, ``None``
    is returned.

    :Args:
        - name - Name of the attribute/property to retrieve.

    Example::

        # Check if the "active" CSS class is applied to an element.
        is_active = "active" in target_element.get_attribute("class")

    """

    attributeValue = ''
    if self._w3c:
        attributeValue = self.parent.execute_script(
        "return (%s).apply(null, arguments);" % getAttribute_js,
        self, name)
    else:
        resp = self._execute(Command.GET_ELEMENT_ATTRIBUTE, {'name': name})
        attributeValue = resp.get('value')
        if attributeValue is not None:
        if name != 'value' and attributeValue.lower() in ('true', 'false'):
            attributeValue = attributeValue.lower()
    return attributeValue   

更新 B

正如您在评论中提到的 该方法返回的 url 值不存在于页面上的任何位置,这意味着您也在尝试访问 href 属性早期的。所以可以有如下两种解决方案:

  • 遍历 DOM 树 并构造一个 Locator,该定位器将唯一标识元素并通过 expected_conditionsWebDriverwait 诱导为 @ 987654324@,然后提取href属性。

  • 出于调试目的,您可以添加 time.sleep(10) 以使元素在 HTML DOM 中正确呈现,然后尝试提取 href 属性。

【讨论】:

  • 定位器可能没有经过优化,但它可以工作。在同一个 div 下还有其他锚标记,我需要使用索引来访问第一个。它将是我当前正在使用的那个,或者使用 find_elements 然后使用您建议的定位器访问第一个(从列表中),这将返回所有。关键是,它返回的值不存在于页面上,这排除了 loc 不正确并且正在获取其他元素的 href 的点。采取的观点,将尝试修改 loc,但我认为这与 get_attribute 的工作方式有关
  • 我确信您的定位器可能已经过优化,但是正如我所说,该方法返回的 url 值不会出现在页面上的任何位置。因此,它正在到达正确的元素,但可能是因为编码解码,它正在剥离某些部分。另外当你说 - url_from_attr = driver.find_elements(By.XPATH,"//div[@class='nla-children mfr']//a[@class='nla-row-text'][1]") .get_attribute("href"),其实你的意思是 url_from_attr = driver.find_elements(By.XPATH,"//div[@class='nla-children mfr']//a[@class='nla-row-text' ]")[1] 然后遍历列表获取 get_attribute("href")
  • 更新了我的答案,让我知道状态。
  • 感谢@DebanjanB。虽然与元素加载需要时间的意义不完全相同,但在我的完整脚本中,浏览器正在远离页面,因此元素正在定位不同的元素。我在代码的前面移动了 find_element 并且它起作用了
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-09-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-28
相关资源
最近更新 更多