Селен пытается перебрать таблицу, но застревает на первой сейчас - PullRequest
0 голосов
/ 21 января 2020

У меня тут немного хедшчера, где я работаю за столом с Python 3 и селеном. Я пытаюсь извлечь некоторые данные из таблицы (tblGuid) и получить информацию из нескольких столбцов.

В то время как данные предположительно извлекаются правильно (len(rows) печатает ожидаемое количество строк), итератор, похоже, застревает на первом элементе, только печатая один и тот же socket несколько раз, с количеством отпечатки, соответствующие len(rows)

vlan = "vlan14"

time.sleep(3)
# Enter filter for vlan
print("Filtered by vlan: " + vlan)
browser.find_element_by_xpath("/html/body/div[1]/div[4]/div[3]/div[4]/div/div[2]/div/div[1]/div[3]/div/table/tfoot/tr/th[13]/input").send_keys(vlan)

# Sort by socket
browser.find_element_by_xpath("/html/body/div[1]/div[4]/div[3]/div[4]/div/div[2]/div/div[1]/div[1]/div/table/thead/tr/th[14]").click()

time.sleep(2)
table = browser.find_element_by_id('tblGuid')
rows = table.find_elements_by_xpath(".//tr")

time.sleep(2)

print("Len: ", len(rows))

for row in rows:
    socket = row.find_element_by_xpath('//td[10]').text
    print("Socket: ", socket)
    # Other stuff of the same natures as the above two lines go here. Get a different column and assign it to a variable.

browser.quit()

Я запускаю этот код с firefox и не включаю режим без заголовка, чтобы подтвердить, что все щелчки, сортировки и фильтры применяются по назначению. Вывод в браузере выглядит так, как ожидалось, и все данные там, а число сокетов варьируется от 1 до 52 в ~ 50 строках. Мне кажется, что for l oop застревает на первом элементе rows.

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

Вероятно, стоит упомянуть, что страница, которую я очищаю, не содержит данных таблицы в HTML, так как она заполнена javascript работает с базой данных. Сначала я подумал, что это проблема, но тот факт, что данные, выводимые в виде сокета, соответствуют первой строке таблицы (как и любые другие столбцы), говорит мне, что данные извлекаются правильно, но я не могу перебрать его.

РЕДАКТИРОВАТЬ - очищенная версия HTML

<table id="tblGuid" class="table table-striped table-hover table-condensed detailedTable table-bordered dataTable" style="width: 99.9%;" role="grid" aria-describedby="tblGuid_info">                    
    <tbody>
        <tr role="row" class="odd">
            <td><button class="tableButton regguid" data-guid="0046ca">Reg.</button></td>
            <td>0046ca</td>
            <td>0110F17754</td>
            <td>A18122</td>
            <td><a href="detail?serial=37530" target="_blank">37530</a></td>
            <td>05929a</td>
            <td>3.0.0</td>
            <td>19-12-21 19:56</td>
            <td>20-01-19 19:53</td>
            <td>20-01-19 19:53</td>
            <td>20526661632</td>
            <td>1</td>
            <td>vlan14</td>
            <td class="sorting_1">1</td>
            <td>0</td>
            <td><a data-node-error="0" data-node-guid="0046ca" href="#">            0</a></td>
            <td><a href="qc?rclId=1279" target="_blank">145811</a></td>
            <td>5554</td>
            <td>152263</td>
            <td>Done</td>
        </tr>
        <tr role="row" class="even">
            <td><button class="tableButton regguid" data-guid="004aa4">Reg.</button></td>
            <td>004aa4</td>
            <td>0110F17D8D</td>
            <td>A19108</td>
            <td><a href="detail?serial=37740" target="_blank">37740</a></td>
            <td>05936c</td>
            <td>3.0.0</td>
            <td>19-12-21 20:15</td>
            <td>20-01-19 19:54</td>
            <td>20-01-19 19:54</td>
            <td>20517699584</td>
            <td>1</td>
            <td>vlan14</td>
            <td class="sorting_1">2</td>
            <td>0</td>
            <td><a data-node-error="0" data-node-guid="004aa4" href="#">            0</a></td>
            <td><a href="qc?rclId=1277" target="_blank">147011</a></td>
            <td>5548</td>
            <td>152311</td>
            <td>Done</td>
        </tr>
    </tbody>
</table>

Примечания к выше HTML:

  • Для удобства чтения удалено около 40 строк таблицы.
  • Удален верхний и нижний колонтитулы таблицы.
  • Некоторые данные в ячейках были изменены для целей данного поста. Структура остается то же самое.
  • это то, как оно выглядит в «элементе проверки» в firefox.
  • xpath, указанный в коде python, основан на «copy -> xpath» в осмотреть элемент.

Ответы [ 2 ]

2 голосов
/ 21 января 2020

без таблицы html это моя лучшая догадка. Похоже, что xpath не совсем делает то, что ожидается. Попробуйте использовать: find_element_by_xpath('.//td[10]').text

for row in rows:
    columns = row.find_elements_by_xpath('.//td')
    for column in range(len(columns)):
        print("column::{}:".format(column), columns[column].text)
    #testsocket = columns[9].text
    socket = row.find_element_by_xpath('.//td[10]').text
    print("Socket: ", socket)
    #print("TestSocket: ", testsocket)
1 голос
/ 21 января 2020

Используйте WebDriverWait для ожидания требуемых условий элемента. Вы можете использовать лучшие практики Google для локаторов, здесь и здесь . Я предлагаю вам изменить локаторы на input для vlan и click.

В коде row.find_element_by_xpath('.//td[10]').text, чтобы получить детей с помощью xpath, вы должны поставить . точка, также можно использовать атрибуты, если они существуют.

Чтобы получить текст в Selenium, элемент должен быть видимым, поэтому необходим видимость всех строк.

from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


options = webdriver.ChromeOptions()
options.headless = True

driver = webdriver.Chrome(options=options)
wait = WebDriverWait(driver, 10)

vlan = "vlan14"
with driver:
    driver.get("url")

    # Enter filter for vlan
    wait.until(EC.element_to_be_clickable((By.XPATH, "/html/body/div[1]/div[4]/div[3]/div[4]/div/div[2]/div/div[1]/div[3]/div/table/tfoot/tr/th[13]/input"))).send_keys(vlan)

    # Sort by socket
    driver.find_element_by_xpath(
        "/html/body/div[1]/div[4]/div[3]/div[4]/div/div[2]/div/div[1]/div[1]/div/table/thead/tr/th[10]").click()

    rows = wait.until(EC.visibility_of_all_elements_located((By.CSS_SELECTOR, '#tblGuid tr[role=row]')))
    for row in rows:
        table_data = row.find_elements_by_css_selector('td')
        socket = table_data[9].text
        print("Socket: ", socket)
...