Поиск наибольшего значения в таблице и клик на ссылку

webdriver
python
Теги: #<Tag:0x00007fedbb8af5b0> #<Tag:0x00007fedbb8af470>

(Jeyson X) #1

Всем привет.
С прошедшими праздниками.

Подскажите пожалуйста как можно вытянуть значение элемента, а потом из этих значений выбрать наибольшее?

Есть такая таблица такого вида:

|___Дата____|___Расчет____|
| 28.12.2015 _| Посмотреть __|
| 29.12.2015 _| Посмотреть __|

В исходнике это так выглядит:

<table class="no-margins" cellspacing="0" __gwtcellbasedwidgetimpldispatchingfocus="true" __gwtcellbasedwidgetimpldispatchingblur="true">

    <thead></thead>
    <colgroup></colgroup>
    <tbody style="">
        <tr class="GPBYFDEPC" __gwt_subrow="0" __gwt_row="0">
            <td class="GPBYFDEOC GPBYFDEAD GPBYFDEBD">
                <div __gwt_cell="cell-gwt-uid-450" style="outline-style:none;">28.12.2015
                </div>
            </td>
    <td class="GPBYFDEOC GPBYFDEAD GPBYFDELD clickable">
        <div __gwt_cell="cell-gwt-uid-458" style="outline-style:none;" tabindex="0">Посмотреть
        </div>
    </td>
</tr>
<tr class="GPBYFDEPD" __gwt_subrow="0" __gwt_row="1">
<td class="GPBYFDEOC GPBYFDEAE GPBYFDEBD">
    <div __gwt_cell="cell-gwt-uid-450" style="outline-style:none;">29.12.2015
    </div>
</td>
        <td class="GPBYFDEOC GPBYFDEAE GPBYFDELD clickable">
            <div __gwt_cell="cell-gwt-uid-458" style="outline-style:none;">Посмотреть
            </div>
        </td>
    </tr>
</tbody>
<tbody style="display: none;"></tbody>
<tfoot style="display: none;" aria-hidden="true"></tfoot>
</table>

Т.е. суть задачи в том, чтобы найти наибольшую дату и кликнуть потом по ссылке "Посмотреть"

Я понимаю, что надо как то вытащить значения элементов div там где дата, засунуть их в список и потом выбрать оттуда наибольшее значение, а вот как потом кликнуть на ссылку возле этой даты вообще нет идей..

Проблема в том, что я в программировании не силен ((
Пробовал сначала вытянуть значения дат вот так:

dt = driver.find_element_by_xpath("//td[@class='GPBYFDEOC GPBYFDEAD GPBYFDEBD']/div[@__gwt_cell='cell-gwt-uid-450']").__getattribute__("value")

но видать, что то не делаю, потому, что ругается, что не может найти этот элемент.
На этом и завис ((


(You Rooock) #2

Привет.
Могу предложить следущее:
У тебя есть дата, которую ты достал из спика своего. Потом найди по XPath колонку.
//td[preceding-sibling::tbody[descendant::div[text()='28.12.2015']]]

Удачи


(Jeyson X) #3

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


(You Rooock) #4

Да, поэтому туда нужно подставлять ту дату, которую вы найдете.
Или с этим тоже проблемы?


(Jeyson X) #5

да вот как раз с поиском этой даты проблема ..

и так как вы показали, тоже не работает ..((


(Stan) #6

а что такое .getattribute("value") ? где вы видите аттрибут такой? дата это просто текст внутри дива


(Jeyson X) #7

ну да, а как его достать?
просто я пока даже не могу сообразить как правильно гуглу этот вопрос задать ..


(Stan) #8

elements = browser.find_element_by_css_selector("td.clickable div")
print elements[0].text
print elements[1].text
...

(Jeyson X) #9

не совсем понял как его изменить, потому, что напрямую так не работает ((


(Stan) #10

ну видимо у вас там аналогичные элементы есть, я же не видел полного html, написал по тому что вы показали в первом посте. Посмотрите в хроме-мозиле руками.


(Андрей Бахтиозин) #11

Я тут навоял, проверил, работает. Единственное что на Java и с библиотекой Selenide. Ну конкретно это решение не подойдет если на странице AJAX и в таблицу эту динамически добавляются строки, а если всё статическое то ок. Можешь по аналогии на свой язык переписать.

Вся логика в принципе в findRowWithTheBiggestData(), а видимый метод только один openLatestReport(). Конечно же не обязательно лепить под эту задачу целый класс, абсолютно всё тоже самое можно сделать в одном методе, но как-то не по феншую, да и навряд выйдет так чтобы ты через месяц понял как он работает.

В трех словах как тебе надо реализовать:
1) у тебя есть таблица, в таблице есть строки, получить список строк можно по xpath = //table/tbody[@style!="display: none;"]/tr
2) в одной строке 2 значение, по первой колонке это дата, получить можем xpath-строки + ./td[not(contains(@class,'clickable'))] , а по второй колонке у тебя собственно ссылка Посмотреть, получить можно xpath-строки + ./td[contains(@class,'clickable')]. Так вот, тебя надо пробежать по всем строкам с первой колонки, узнать где больше дата и записать в какой же ты строке нашел саму большую дату см как это делается в методе findRowWithTheBiggestData() там в принципе используется стандартный алгоритм "поиск максимального элемента в массиве"
3) Зная номер строки с самой большой датой просто взять кликнуть на Посмотреть.

Обращайся если нужны будут подробности

import com.codeborne.selenide.SelenideElement;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import org.openqa.selenium.By;

import java.util.List;

import static com.codeborne.selenide.Selenide.$$;

public class ReportTable {

    /**
    * получаем список строк таблицы
    * */
    private List<SelenideElement> getTableRows() {
        return $$(By.xpath("//table/tbody[@style!=\"display: none;\"]/tr"));
    }

    /**
     * по номеру строки таблицы выбираем SelenideElement колонки с датой
     * */
    private SelenideElement getDataColumnSelenideElement(int rowIndex) {
        return getTableRows().get(rowIndex).$(By.xpath("./td[not(contains(@class,'clickable'))]"));
    }

    /**
     * по номеру строки таблицы выбираем SelenideElement колонки с ссылкой
     * */
    private SelenideElement getLinkColumnSelenideElement(int rowIndex) {
        return getTableRows().get(rowIndex).$(By.xpath("./td[contains(@class,'clickable')]"));
    }

    /**
     * забираем дату из SelenideElement колонки с датой
    * */
    private DateTime getDataFromSelenideElementRow(SelenideElement rowWithDate) {
        DateTimeFormatter dtf = DateTimeFormat.forPattern("dd.MM.yyyy");
        return dtf.parseDateTime(rowWithDate.getText());
    }

    private int findRowWithTheBiggestData() {
        int rowWithMaxDate = 0;
        DateTime maxDate = getDataFromSelenideElementRow(getDataColumnSelenideElement(0));
        for (int i = 0; i < getTableRows().size(); i++) {
            DateTime currentDateInRow = getDataFromSelenideElementRow(getDataColumnSelenideElement(i));
            if (maxDate.getMillis() < currentDateInRow.getMillis()) {
                rowWithMaxDate = i;
                maxDate = currentDateInRow;
            }
        }
        return rowWithMaxDate;
    }

    /**
     * собственно клик на "Посмотреть"
    * */
    public void openLatestReport() {
        int rowIndex = findRowWithTheBiggestData();
        getLinkColumnSelenideElement(rowIndex).$("div").click();
    }
}

(Jeyson X) #12

Спасибо огромное ))
колоссальный конечно кусок работы ))
сейчас буду пробовать переводить его на пайтон ))


(Андрей Бахтиозин) #13

не за что, скажем так "Дело было вечером, делать было нечего". Иногда пробивает порешать задачки.