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

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

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

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

|Дата_|Расчет_|
| 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")

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

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

Удачи

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

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

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

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

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

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

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

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

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

Я тут навоял, проверил, работает. Единственное что на 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();
    }
}
1 лайк

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

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

1 лайк