Как я могу проверить, существует ли элемент на странице, используя Selenium XPath? - PullRequest
0 голосов
/ 31 марта 2019

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

Для этого я использую Selenium и Python.Использование XPath прекрасно работает для поиска ссылок и навигации во всех других частях скрипта, за исключением доступа к элементам в таблице.Сначала я подумал, что мог использовать неправильный Xpath, поэтому скопировал путь прямо из окна проверки Chrome - все равно не повезло.

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

Вот часть кода и часть HTML, которую я пытаюсь разобрать.Куда я иду не так?

# USING WEBDRIVER - ALWAYS TRIGGERS EXCEPTION 
def check_if_user_has_any_data():
try:
    time.sleep(10)
    element = WebDriverWait(driver, 10).until(EC.presence_of_all_elements_located((By.XPATH, '//*[@id="event-table"]/div/div/div[2]/mobile-table/md-whiteframe/div[1]/ga-no-data-table/div')))
    print(type(element))
    if element == True:
        print("found empty state by copying xpath directly - bit risky, but it seems to have worked")
    else:
        print("did'nt find empty state")
except:
    print("could not find the empty state element", EC)


# USING BEAUTIFULSOUP
def check_if_user_has_any_data#2():
    time.sleep(10)
    html = driver.execute_script("return document.documentElement.outerHTML")
    soup = BeautifulSoup(html, 'html.parser')
    print(soup.text[:500])
    print(len(soup.findAll('div', {"class": "table-row-no-data ng-scope"})))


# HTML 
<div class="table-row-no-data ng-scope" ng-if="::config" ng-class="{overlay: config.isBuilderOpen()}">
  <div class="no-data-content layout-align-center-center layout-row" layout="row" layout-align="center center">
    ...
</div>

Первая версия вызывает исключение.Ожидается, что «элемент» будет оценен как True.Фактически, элемент не найден.

Вторая версия печатает первые 500 символов (насколько я могу судить правильно), но возвращает '0'.Ожидается, что после проверки источника страницы будет возвращено '1'.

Ответы [ 4 ]

1 голос
/ 01 апреля 2019

Добро пожаловать на SO.Вот метод, который я обычно использую.

Импорт

from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.common.by import By

Метод

def is_element_present(self, how, what):
    try:
        self.driver.find_element(by=how, value=what)
    except NoSuchElementException as e:
        return False
    return True
1 голос
/ 01 апреля 2019

Использовать следующий код:

elements = driver.find_elements_by_xpath("//*[@id='event-table']/div/div/div[2]/mobile-table/md-whiteframe/div[1]/ga-no-data-table/div")
size = len(elements)
if len(elements) > 0:
    #**element is present** do your action
else:
    #**element is not present** do alternative action 

Примечание : find_elements не будет генерировать или выдавать какие-либо исключения

0 голосов
/ 13 апреля 2019

некоторые вещи загружаются динамически, лучше просто установить таймаут для исключения ожидания

0 голосов
/ 01 апреля 2019

Спасибо!

Я решил это.На странице было множество разных элементов iframe, и я не знал, что в Selenium нужно переключаться между фреймами, чтобы получить доступ к этим элементам.

В исходном коде или предлагаемых решениях не было ничего плохого, что также хорошо работало, когда я их тестировал.

(Извините, я понимаю, что в вопросе не было достаточно информации для выявления этой проблемы).

Вот код, который я использовал для его проверки:

# time for page to laod
    time.sleep(20)
    # Find all iframes
    iframes = driver.find_elements_by_tag_name("iframe")
    # From inspecting page source, it looks like the index for the relevant iframe is [0]
    x = len(iframes)
    print("Found ", x, " iFrames") # should return 5
    driver.switch_to.frame(iframes[0])
    print("switched to frame [0]")
    if WebDriverWait(driver, 10).until(EC.presence_of_all_elements_located((By.XPATH, '//*[@class="no-data-title ng-binding"]'))):
        print("Found it in this frame!")
...