Чтение, запись и управление динамически создаваемой HTML-таблицей с использованием Python Selen - PullRequest
0 голосов
/ 02 октября 2019

Предположим, что есть какой-то конкретный поисковик, который ищет некоторые товары, а я ищу с помощью 'Тедди'. Количество итоговых результатов составляет 140, и оно отображается в небольшой таблице, составленной из <div> для каждой строки и столбца (строка для каждого содержимого, столбец для информации о содержимом), в которой имеется полоса прокрутки. Это показывает мне хороший список до 5 на одном экране (каждый контент использует 40px для своей высоты), если мне нужно увидеть больше, мне нужно прокрутить эту таблицу вниз.

HTML выглядит как ниже, еслиЯ вижу товары с 45-го по 49-й (45-й контент находится вверху текущего представления).

<div class="table-body" style="height:200px">            // This contains scrollbar
    <div class="table-panel" style="height:5600px">
        <div class="ag-row" style="height:40px row="42"> // This is each row of goods
            <div class="name">Teddy</div>                // This is each column of good
            <div class="price">200</div>
            <input class="amount">0</input>              // Input text box for put amount of goods to buy
        </div>
        <div class="ag-row" style="height:40px row="43">
            <div class="name">Brown Bess</div>
            <div class="price">230</div>
            <input class="amount">0</input>
        </div>
        <div class="ag-row" style="height:40px row="44"> // <-- This is what I'am seeing at the top. 0 based row attribute
            <div class="name">Blue</div>
            <div class="price">280</div>
            <input class="amount">0</input>
        </div>
        <div class="ag-row" style="height:40px row="45">
            <div class="name">Scientist</div>
            <div class="price">400</div>
            <input class="amount">0</input>
        </div>
        <div class="ag-row" style="height:40px row="46">
            <div class="name">Mouse</div>
            <div class="price">120</div>
            <input class="amount">0</input>
        </div>
        <div class="ag-row" style="height:40px row="47">
            <div class="name">Hangover</div>
            <div class="price">150</div>
            <input class="amount">0</input>
        </div>
        <div class="ag-row" style="height:40px row="48"> // <-- This is what I'am seeing last.
            <div class="name">Building</div>
            <div class="price">420</div>
            <input class="amount">0</input>
        </div>
        <div class="ag-row" style="height:40px row="50">
            <div class="name">Park</div>
            <div class="price">60</div>
            <input class="amount">0</input>
        </div>
        <div class="ag-row" style="height:40px row="51">
            <div class="name">Coffee</div>
            <div class="price">160</div>
            <input class="amount">0</input>
        </div>
        <div class="ag-row" style="height:40px row="49">
            <div class="name">Juice</div>
            <div class="price">100</div>
            <input class="amount">0</input>
        </div>
    </div>
</div>

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

Я проверил поведение этой веб-страницы. Это только делает его HTML рядом с тем, где я вижу. Когда я вижу около 100-го контента, он создает html в промежутке между 92-м и 108-м - сколько его экземпляров является случайным. Когда я прокручиваю вниз или вверх, он удаляет содержимое далеко от текущей позиции и создает новое для текущего экрана.

И мне нужно проанализировать эти данные и создать некоторую структуру, похожую на список, в Python. Потому что он создает частичные данные в зависимости от экрана (точнее говоря, кажется, что он использует полосу прокрутки для проверки того, где я вижу) Я попытался прокрутить полосу прокрутки и обрезать все данные в HTML и удалить дубликаты. Коды ниже

from selenium import webdriver
..blah..

def iterateOptionTable(driver):
    el_viewport = driver.find_element_by_class_name('table-body')
    driver.execute_script('document.getElementsByClassName("{}")[0].scrollTop = 0;'.format('table-body'))
    max_height = int(driver.execute_script('return document.getElementsByClassName("{}")[0].scrollHeight;'.format('table-body')))
    scrolling_amnt = int(40 * 5) # Each row height is 40
    cur_scroll = 0
    table = defaultdict(int) # Don't put into list which is already pushed
    ret = []
    while cur_scroll < max_height:
            el_products = el_viewport.find_elements_by_xpath('./div/*')
            for el_p in el_products:
                rownum = int(el_p.get_attribute("row"))
                if rownum not in table:
                    table[rownum] = True
                    ret.append(el_p)
            yield ret   # List of WebElement of good
            ret.clear()        
            cur_scroll += scrolling_amnt
            driver.execute_script('document.getElementsByClassName("{}")[0].scrollTop = {};'.format('table-body', cur_scroll))

def parseElementToData(elems):
    ret = []
    for el in elems:
        single_data = DO_EXTRACT_DATA_FROM_EL()
        ret.append(single_data)

def parseTable(driver):
    ret = []
    for elems in iterateOptionTable(driver):
        data += parseElementToData(elems)
    return ret

Есть несколько других заданий для страницы, она запрограммирована с использованием yield из-за иерархии веб-страниц.

Она довольно хорошо работает в отладчике, когда я выполняю одно изодин. Но в реальном времени он даже не прокручивает таблицу. Не говоря уже о том, что это неэффективно, я думаю. Также пробовал ту же версию Javascript, выполняя скрипт из селена.

Есть более изощренный способ или я могу получить ответ, почему они не работают в нормальной ситуации. Я довольно новичок в веб-сканировании и селене. Пожалуйста, помогите:)

Ответы [ 2 ]

0 голосов
/ 07 октября 2019

Мне не удалось то, что я намеревался. Прокрутка плохо взаимодействует в таких условиях. Мне удалось решить эту проблему, выбрав одну ячейку в таблице и отправив кнопку «Keys.DOWN» для прокрутки вниз.

0 голосов
/ 02 октября 2019

Тот факт, что вы можете видеть элементы или нет, не означает, что они уже есть в HTML, они должны иметь отображение: скрыто, пока вы не прокрутите их.

Теперь я предполагаю, что здесь вы не указали ссылку на соответствующую веб-страницу, и я постараюсь объяснить с помощью предоставленного вами кода.

Я предлагаю вернуть все строки таблицы 1 на 1:

i = 0
row_list = []

while True:
    try:
        name = driver.find_element_by_xpath(x_path_to_the_row[i]/div).get_attribute('innerHTML'
        price = driver.find_element_by_xpath(x_path_to_the_row[i]/div[2]).get_attribute('innerHTML')
        row_list.append((name, price))
    except NoSuchElementException:
        break
    i += 1

В основном цикле, пока элемент таблицы не существует, получить столбцы этой строки ипостроить кортеж, содержащий оба элемента.

Примечание. Если HTML не находится внутри компонента Shadow DOM, это не должно быть проблемой.

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