Итерации по таблице сайта (элемент не прикреплен к документу страницы) - PullRequest
0 голосов
/ 04 августа 2020

У меня есть код, который проходит через таблицу веб-сайта. Таблица - это динамический c, и элементы загружаются в нее при прокрутке пользователя.

У меня есть параметры:

public class UserTableRow
{
    private readonly IWebElement row;

    public string Username => row.FindElement(By.XPath(".//div[contains(@class, 'slick-cell l0 r0')]")).Text;
    public string Firstname => row.FindElement(By.XPath(".//div[contains(@class, 'slick-cell l1 r1')]")).Text;
    public string Lastname => row.FindElement(By.XPath(".//div[contains(@class, 'slick-cell l2 r2')]")).Text;
    public string Type => row.FindElement(By.XPath(".//div[contains(@class, 'slick-cell l3 r3')]")).Text;
    public string Crew => row.FindElement(By.XPath(".//div[contains(@class, 'slick-cell l4 r4')]")).Text;
    public string JobTitle => row.FindElement(By.XPath(".//div[contains(@class, 'slick-cell l5 r5')]")).Text;
    public string DefaultPrice => row.FindElement(By.XPath(".//div[contains(@class, 'slick-cell l6 r6')]")).Text;
    public string Future => row.FindElement(By.XPath(".//div[contains(@class, 'slick-cell l7 r7')]")).Text;
    public string Language => row.FindElement(By.XPath(".//div[contains(@class, 'slick-cell l8 r8')]")).Text;

    public override string ToString()
    {
        return "SharePrice: " + Username.ToString() + ": " + Firstname.ToString();
    }

    public UserTableRow(IWebElement row)
    {
        try
        {
            this.row = row;
        }
        catch (Exception)
        {

            throw;
        }
    }
}

Вот сам метод добавления данных в список.

    public static IEnumerable<UserTableRow> AddItemsToList(IWebDriver driver)
    {

        IReadOnlyCollection<IWebElement> rows = new List<IWebElement>();

        List<UserTableRow> DataHere = new List<UserTableRow>();

        driver.FindElement(By.XPath("//*[@id=\"disabled_users_show_label\"]")).Click();

        Thread.Sleep(7000);

        driver.FindElement(By.XPath("//*[@id=\"users_table\"]/div[5]/div/div[1]")).Click();

        for (int i = 0; i < 11; i++)
        {
            rows = driver.FindElements(By.CssSelector("#users_table .slick-viewport .slick-row"));

            // Now we will iterate through cells in table and compare to what we already have in the list
            foreach (IWebElement cell in rows)
            {
                rows = driver.FindElements(By.CssSelector("#users_table .slick-viewport .slick-row"));

                // Add data to our object
                DataHere.Add(new UserTableRow(cell));

                //We need to select table first to be able to scroll down. We do it directly here
                Actions actions = new Actions(driver);
                actions.SendKeys(Keys.ArrowDown).Build().Perform();

            }

        }

        List<UserTableRow> noDupes = DataHere.Distinct().ToList();

        return noDupes;
    }

Все идет нормально, но в какой-то момент (я не знаю почему) выявляется ошибка:

OpenQA.Selenium.StaleElementReferenceException: 'ссылка на устаревший элемент: элемент не прикреплен в документ страницы (Информация о сеансе: chrome = 84.0.4147.105) '

Указывая на row.FindElement(By.XPath(".//div[contains(@class, 'slick-cell l0 r0')]")).Text;

Любые идеи, как добавить try catch в Параметры, чтобы код продолжал выполнение до добавление в список завершено?

Причина, по которой я звоню

rows = driver.FindElements(By.CssSelector("#users_table .slick-viewport .slick-row"));

Внутри l oop, заключается в том, что я пытаюсь обновить значения таблицы, чтобы выполнить итерацию после прокрутки вниз. Это сложная таблица, которая выгружает элементы и загружает другие элементы из базы данных при прокрутке. Итак, я пытаюсь использовать c пользовательскую прокрутку с помощью клавиатуры и перехватить элементы таблицы в List.

Было бы идеально сравнить элементы списка в полете. Однако я думал добавить все в список (даже дубликаты), а затем составить другой список, в котором я удалю дубликаты, например:

    List<UserTableRow> noDupes = DataHere.Distinct().ToList();

HTML:

<div id="users_table" class="security_slick_container slickgrid_300610 ui-widget" style="overflow: hidden; outline: 0px; position: relative;">
    <div tabindex="0" hidefocus="" style="position:fixed;width:0;height:0;top:0;left:0;outline:0;"></div>
    <div class="slick-header ui-state-default" style="overflow:hidden;position:relative;">
        <div class="slick-header-columns" style="left: -1000px; width: 2132px;" unselectable="on">
            <div class="ui-state-default slick-header-column slick-header-sortable slick-header-column-sorted" id="slickgrid_300610userName" title="" style="width: 94px;"><span class="slick-column-name"><strong>Username:</strong></span><span class="slick-sort-indicator slick-sort-indicator-asc"></span>
                <div class="slick-resizable-handle"></div>
            </div>
            <div class="ui-state-default slick-header-column slick-header-sortable" id="slickgrid_300610firstName" title="" style="width: 89px;"><span class="slick-column-name"><strong>Firstname:</strong></span><span class="slick-sort-indicator"></span>
                <div class="slick-resizable-handle"></div>
            </div>
            <div class="ui-state-default slick-header-column slick-header-sortable" id="slickgrid_300610lastName" title="" style="width: 109px;"><span class="slick-column-name"><strong>Lastname:</strong></span><span class="slick-sort-indicator"></span>
                <div class="slick-resizable-handle"></div>
            </div>
            <div class="ui-state-default slick-header-column slick-header-sortable" id="slickgrid_300610type" title="" style="width: 124px;"><span class="slick-column-name"><strong>Type:</strong></span><span class="slick-sort-indicator"></span>
                <div class="slick-resizable-handle"></div>
            </div>
            <div class="ui-state-default slick-header-column slick-header-sortable" id="slickgrid_300610crew" title="" style="width: 109px;"><span class="slick-column-name"><strong>Crew:</strong></span><span class="slick-sort-indicator"></span>
                <div class="slick-resizable-handle"></div>
            </div>
            <div class="ui-state-default slick-header-column slick-header-sortable" id="slickgrid_300610jobTitle" title="" style="width: 109px;"><span class="slick-column-name"><strong>Job title:</strong></span><span class="slick-sort-indicator"></span>
                <div class="slick-resizable-handle"></div>
            </div>
            <div class="ui-state-default slick-header-column slick-header-sortable" id="slickgrid_300610defaultPriceClass" title="" style="width: 124px;"><span class="slick-column-name"><strong>Defaultprice class:</strong></span><span class="slick-sort-indicator"></span>
                <div class="slick-resizable-handle"></div>
            </div>
            <div class="ui-state-default slick-header-column" id="slickgrid_300610description" title="" style="width: 129px;"><span class="slick-column-name"><strong>Description:</strong></span>
                <div class="slick-resizable-handle"></div>
            </div>
            <div class="ui-state-default slick-header-column" id="slickgrid_300610language" title="" style="width: 39px;"><span class="slick-column-name"><strong>Language:</strong></span>
                <div class="slick-resizable-handle"></div>
            </div>
        </div>
    </div>
    <div class="slick-headerrow ui-state-default" style="overflow: hidden; position: relative; display: none;">
        <div class="slick-headerrow-columns" style="width: 1115px;"></div>
        <div style="display: block; height: 1px; position: absolute; top: 0px; left: 0px; width: 1132px;"></div>
    </div>
    <div class="slick-top-panel-scroller ui-state-default" style="overflow: hidden; position: relative; display: none;">
        <div class="slick-top-panel" style="width:10000px"></div>
    </div>
    <div class="slick-viewport" style="width: 100%; overflow: auto; outline: 0px; position: relative; height: 567px;">
        <div class="grid-canvas" style="height: 16550px; width: 1115px;">
            <div class="ui-widget-content slick-row even" style="top:0px">
                <div class="slick-cell l0 r0">john.smith</div>
                <div class="slick-cell l1 r1">John</div>
                <div class="slick-cell l2 r2">Smith</div>
                <div class="slick-cell l3 r3">Contractor</div>
                <div class="slick-cell l4 r4">Microsoft</div>
                <div class="slick-cell l5 r5">Sales manager</div>
                <div class="slick-cell l6 r6">A</div>
                <div class="slick-cell l7 r7"></div>
                <div class="slick-cell l8 r8">en</div>
            </div>
            <div class="ui-widget-content slick-row odd" style="top:25px">
                <div class="slick-cell l0 r0">robert.geits</div>
                <div class="slick-cell l1 r1">Robert</div>
                <div class="slick-cell l2 r2">Geits</div>
                <div class="slick-cell l3 r3">Staff</div>
                <div class="slick-cell l4 r4">Google</div>
                <div class="slick-cell l5 r5">Project manager</div>
                <div class="slick-cell l6 r6">B</div>
                <div class="slick-cell l7 r7"></div>
                <div class="slick-cell l8 r8">de</div>
            </div>
            <div class="ui-widget-content slick-row even" style="top:50px">
                <div class="slick-cell l0 r0">amir.rooney</div>
                <div class="slick-cell l1 r1">Amir</div>
                <div class="slick-cell l2 r2">Rooney</div>
                <div class="slick-cell l3 r3">Staff</div>
                <div class="slick-cell l4 r4">Microsoft</div>
                <div class="slick-cell l5 r5">Sales manager</div>
                <div class="slick-cell l6 r6">A</div>
                <div class="slick-cell l7 r7"></div>
                <div class="slick-cell l8 r8">en</div>
            </div>
            # ETC # ETC # ETC # ETC # ETC # ETC # ETC # ETC # ETC # ETC 
        </div>
    </div>
    <div tabindex="0" hidefocus="" style="position:fixed;width:0;height:0;top:0;left:0;outline:0;"></div>
</div>

1 Ответ

1 голос
/ 04 августа 2020

Вы обновляете строки внутри foreach, но строки - это итерируемый объект foreach. Это, я думаю, не является незаконным (в конце концов, оно скомпилировано), но, похоже, вызывает проблемы. Я считаю, что ссылка на устаревший элемент каким-то образом связана с переназначением строк внутри его собственного foreach l oop.

Однако после того, как вы назначаете строки во второй раз, вы никогда не используете его внутри foreach. Похоже, что это непреднамеренное утверждение, которое можно удалить. В конце концов, зачем вообще присваивать строки внутри foreach, а затем никогда не использовать внутри foreach?

Если вы назначаете строки второй раз, потому что сравниваете с тем, что уже было обработано, я присваивает второй строке другое имя переменной (скажем, rows_B). Но, как я уже сказал, я не думаю, что здесь это происходит. Вы просто назначаете строки внутри foreach и никогда не используете его.

Или, если причина назначения 2-х строк в том, что таблица динамически изменяется во время обработки таблицы? Если так, я думаю, лучшее, что вы можете сделать, - это поймать ошибку и попытаться исправить все, что изменилось на вашем пути. Я знаю, это звучит расплывчато, но на самом деле, если ваши входные данные меняются, пока вы пытаетесь их обработать, лучшее, на что вы могли когда-либо надеяться, - это лучшее усилие.

Например, вы можете создать переменная 2-й строки (скажем, rows_b) для refre sh в foreach l oop. Затем сравните rows_b с исходными строками. Если они идентичны - круто, просто продолжайте обработку.

Если они отличаются, я бы отслеживал, какие строки вы обработали до этого момента, вырывался из l oop и начинал заново. Во время foreach вы должны проверить, обрабатывалась ли строка ранее, и если да, то переходите к следующему итератону.

Если это то, что вы пытаетесь сделать - и хотите увидеть пример кода - позвольте мне знать. Я не хотел писать код, если это даже не то, что вы пытаетесь выполнить sh; -)

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