Python и Selenium - использовать XPath text () вместо myElement.text? - PullRequest
0 голосов
/ 25 марта 2019

Используя Python и Selenium, я хочу сделать что-то вроде этого:

myList = elementList[0].find_elements_by_xpath("/some/xpath")
textValue = myList[0].find_elements_by_xpath("text()[1]")

(В конце оба шага будут во вложенных циклах for)

Но вторая строка вылетает:

Expected an element or WindowProxy, got: [object Text] {}

Очевидным предложением было бы использовать встроенную функцию Selenium .text (например, myList[0].text), но в моем случае это неприемлемо, поскольку первый (но только этот) элемент в myList имеетдва текстовых значения и .text объединяет их в одну строку.

Итак, как мне "применить" функцию XPath text()[1] к элементу в myList, чтобы получить текстовое значение этого элемента?

Обновление: у меня есть идея.Если я добавлю text() к первой строке кода в моем вопросе, это сработает.Я так понимаю, что text() должен быть в конце правильного XPath?Я прав?

Разве нельзя было бы использовать какой-либо универсальный XPath-шаблон в моей второй строке, так как в любом случае там только один элемент и нет риска для двусмысленности?Что-то вроде textValue = myList[0].find_elements_by_xpath("*/text()[1]")?

Ответы [ 2 ]

0 голосов
/ 27 марта 2019

Хорошо, в конце концов я пишу два метода на python. Один для извлечения только родительского текстового содержимого (дочерний текст не включен), а другой для извлечения содержимого на основе позиции текстового узла.

Примечание. Если вы хотите использовать эти методы на других языках, обязательно обновите driver.execute_script и 'strip () `в соответствии с вашим языком. (использовал strip () для обрезки возвращаемого значения).

Метод 1: get_text_exclude_children (элемент)

# параметр - элемент

# return - только текст элемента (дочерний текст будет исключен)

def get_text_exclude_children(element):
    return driver.execute_script(
        """
        var parent = arguments[0];
        var child = parent.firstChild;
        var textValue = "";
        while(child) {
            if (child.nodeType === Node.TEXT_NODE)
                textValue += child.textContent;
                child = child.nextSibling;
        }
        return textValue;""",
        element).strip()

Метод 2: get_text_from_parent_by_position (element, textPostion)

# параметр - элемент

# параметр - textPostion (начинается с 1, укажите индекс возвращаемого текстового узла)

# return - родительский текст, указанный в позиции

def get_text_from_parent_by_position(element,textPosition=1):
    return driver.execute_script(
        """ var parent = arguments[0];
            var textPosition = arguments[1];
            var txtPosition = 0;
            var child = parent.firstChild;
            var textValue="";
            while(child) {
              if (child.nodeType === 3){                        
                if (txtPosition===(textPosition-1)){
                  textValue = child.textContent;                
                  break;
                }}else{txtPosition+=1;}
              child = child.nextSibling;
            }
        return textValue;""",
        element,textPosition).strip()

Как использовать эти методы

myList = elementList[0].find_elements_by_xpath("/some/xpath")
listElement = myList[0]
onlyParentText = get_text_exclude_children(listElement)
onlyFirstTextNode = get_text_from_parent_by_position(listElement,1)
print("only parent text: " + onlyParentText)
print("First TextNode text: " + onlyFirstTextNode)
0 голосов
/ 26 марта 2019

myList[0].find_elements_by_xpath("text()[1]") вернет массив WebElement, если что-нибудь, а не строку текста.Вы пробовали одно из следующего?Я думаю, что они должны работать ...

myList[0].get_attribute(‘text’)

Или

myList[0].get_attribute(‘innerHTML’)

Дайте мне знать, если вы можете попробовать это и посмотреть, как это происходит.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...