在python selenium中使用get_attribute()查找xpath

s3fp2yjn  于 2023-01-13  发布在  Python
关注(0)|答案(3)|浏览(276)

这是一种有点落后的Web抓取方法。我需要在使用text()= identifier找到Web元素之后定位它的xpath
因为xpath值根据显示的信息而不同,所以我需要在行中使用可预测标签来定位find元素旁边的span文本,我发现一个简单可靠的方法是定位关键字标签,然后在xpath中将td整数加1。

def x_label(self, contains):
         mls_data_xpath = f"//span[text()='{contains}']"
         string = self.driver.find_element_by_xpath(mls_data_xpath).get_attribute("xpath")
         digits = string.split("td[")[1]
         num = int(re.findall(r'(\d+)', digits)[0]) + 1
         labeled_data = f'{string.split("td[")[0]}td[{num}]/span'
         print(labeled_data)
         labeled_text = self.driver.find_element_by_xpath(labeled_data).text
         return labeled_text

我找不到太多关于.get_attribute()和get_property()的信息,所以我希望有类似.get_attribute(“xpath”)的东西,但我一直无法找到它。
基本上,我接受了一个字符串,比如“ApprxTotalLivArea”,然后将td[0]后面的整数加1,以查找来自隔壁单元格的span数据。我希望有一个类似get_attributes(“xpath”)的函数,可以从我通过text()='{contains}'搜索找到的元素中找到xpath字符串。

xqk2d5yq

xqk2d5yq1#

远程WebElement包含以下方法:

  • 获取属性()
  • 获取dom属性()
  • 获取属性()

但是**xpath不是WebElement的有效属性。因此 get_attribute("xpath") 将始终返回*NULL***

li9yvcax

li9yvcax2#

我在另一个论坛找到了一个python版本的execute脚本from this post,它是基于JavaScript答案的。我不得不对这个函数创建的字符串进行大量的.replace()调用,但我能够普遍地找到我需要的标签字符串,并将td/span xpath增加+1来找到列数据并检索它,而不管不同页面列表上xpath值的差异。

def x_label(self, contains):
    label_contains = f"//span[contains(text(), '{contains}')]"
    print(label_contains)
    labeled_element = self.driver.find_element_by_xpath(label_contains)
    print(labeled_element)
    element_label = labeled_element.text
    print(element_label)

    self.driver.execute_script("""
    window.getPathTo = function (element) {
        if (element.id!=='')
            return 'id("'+element.id+'")';
        if (element===document.body)
            return element.tagName;

        var ix= 0;
        var siblings= element.parentNode.childNodes;
        for (var i= 0; i<siblings.length; i++) {
            var sibling= siblings[i];
            if (sibling===element)
                return window.getPathTo(element.parentNode)+'/'+element.tagName+'['+(ix+1)+']';
            if (sibling.nodeType===1 && sibling.tagName===element.tagName)
                ix++;
        }
    }
    """)

    generated_xpath = self.driver.execute_script("return window.getPathTo(arguments[0]);", labeled_element)
    generated_xpath = f'//*[@{generated_xpath}'.lower().replace('tbody[1]', 'tbody')

    print(f'generated_xpath = {generated_xpath}')

    expected_path = r'//*[@id="wrapperTable"]/tbody/tr/td/table/tbody/tr[26]/td[6]/span'

    generated_xpath = generated_xpath.replace('[@id("wrappertable")', '[@id="wrapperTable"]').replace('tr[1]', 'tr')
    clean_path = generated_xpath.replace('td[1]', 'td').replace('table[1]', 'table').replace('span[1]', 'span')
    print(f'clean_path = {clean_path}')
    print(f'expected_path = {expected_path}')
    digits = generated_xpath.split("]/td[")[1]
    print(digits)
    num = int(re.findall(r'(\d+)', digits)[0]) + 1
    print(f'Number = {num}')
    labeled_data = f'{clean_path.split("td[")[0]}td[{num}]/span'
    print(f'labeled_data = {labeled_data}')
    print(f'expected_path = {expected_path}')

    if labeled_data == expected_path:
        print('Congrats')
    else:
        print('Rats')

    labeled_text = self.driver.find_element_by_xpath(labeled_data).text
    print(labeled_text)
    return labeled_text
py49o6xq

py49o6xq3#

此函数迭代地获取的父元素,直到找到顶部的html元素

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

def get_xpath(elm):
    e = elm
    xpath = elm.tag_name
    while e.tag_name != "html":
        e = e.find_element(By.XPATH, "..")
        neighbours = e.find_elements(By.XPATH, "../" + e.tag_name)
        level = e.tag_name
        if len(neighbours) > 1:
            level += "[" + str(neighbours.index(e) + 1) + "]"
        xpath = level + "/" + xpath
    return "/" + xpath

driver = webdriver.Chrome()
driver.get("https://www.stackoverflow.com")
login = driver.find_element(By.XPATH, "//a[text() ='Log in']")
xpath = get_xpath(login)
print(xpath)

assert login == driver.find_element(By.XPATH, xpath)

希望这有帮助!

相关问题