Selenium не находит настраиваемый атрибут «data-target-section-id»

Я пытаюсь очистить некоторые профили людей в LinkedIn с определенной работы. Для этого я пытался найти кнопку «Люди» и щелкнуть ее, чтобы посмотреть на нужных людей.

Путь следующий:

Выйдя из домашней страницы Linkedin -> я вхожу в систему и перехожу на домашнюю страницу LinkedIn -> я пишу в строке поиска «hr» и нажимаю «Ввод».

На странице результатов hr в левой части страницы есть список навигации с надписью «На этой странице». Один из вариантов включает «Люди», и это то, на что я хочу ориентироваться.

HTML-код кнопки «Люди» в списке навигации:

<li>
   <button aria-current = "false" class = "search-navigation-panel_button" data-target-section-id = "PTFmMNSPSz2LQRzwynhRBQ= = " role = "link" type = "button"> People

Я пытался найти эту кнопку через By.Link_text и нашел ключевое слово People, но не сработало. Я тоже пытался сделать By.XPATH "//button[@data-target-section-id='RIK0XK7NRnS21bVSiNaicw==']")"" но тоже не находит.

Как я могу заставить селен найти этот настраиваемый атрибут, чтобы я мог найти эту кнопку через data-target-section-id="PTFmMNSPSz2LQRzwynhRBQ=="?

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

Например, если первым человеком является Ян, а вторым — Брайан, я получаю ссылку на профиль Яна, даже если «пользователи» — это Брайан.

Отлаживая цикл, я вижу правильный список людей в all_users, но он получает только href первого человека в списке и никогда не обновляется.

Вот код этого:

all_users = driver.find_elements(By.XPATH, "//*[contains(@class, 'entity-result__title-line entity-result__title-line--2-lines')]")

for users in all_users:
    print(users)
    get_links = users.find_element(By.XPATH, "//*[contains(@href, 'miniProfileUrn')]")
    print(get_links.get_attribute('href'))

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

Brandon Johnson 18.02.2023 20:53

Список отображается на странице без необходимости нажимать раскрывающийся список или наводить курсор мыши на что-либо.

Jesper Ezra 18.02.2023 21:29

Я пытаюсь найти этот HTML-код на разных страницах linkedin.com, но не могу найти страницу, о которой вы говорите. Пожалуйста, дайте ссылку на фактическую страницу и четко укажите, по какой ссылке вы пытаетесь щелкнуть. У меня есть решение второй проблемы, но я не хочу начинать ответ, пока не получу всю необходимую мне информацию.

JeffC 19.02.2023 07:06

@JeffC Я обновил вопрос, указав ссылку на фактические страницы и, надеюсь, лучшее объяснение того, что я хочу щелкнуть.

Jesper Ezra 19.02.2023 19:12
Как подобрать выигрышные акции с помощью анализа и визуализации на Python
Как подобрать выигрышные акции с помощью анализа и визуализации на Python
Отказ от ответственности: Эта статья предназначена только для демонстрации и не должна использоваться в качестве инвестиционного совета.
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
Потяните за рычаг выброса энергососущих проектов
Потяните за рычаг выброса энергососущих проектов
На этой неделе моя команда отменила проект, над которым я работал. Неделя усилий пошла насмарку.
Инструменты для веб-скрапинга с открытым исходным кодом: Python Developer Toolkit
Инструменты для веб-скрапинга с открытым исходным кодом: Python Developer Toolkit
Веб-скрейпинг, как мы все знаем, это дисциплина, которая развивается с течением времени. Появляются все более сложные средства борьбы с ботами, а...
Библиотека для работы с мороженым
Библиотека для работы с мороженым
Лично я попрощался с операторами print() в python. Без шуток.
Эмиссия счетов-фактур с помощью Telegram - Python RPA (BotCity)
Эмиссия счетов-фактур с помощью Telegram - Python RPA (BotCity)
Привет, люди RPA, это снова я и я несу подарки! В очередном моем приключении о том, как создавать ботов для облегчения рутины. Вот, думаю, стоит...
0
4
67
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Если вы хотите найти несколько элементов с одинаковым атрибутом, замените find_element на find_elements. Посмотрите, работает ли это, чтобы найти не только первый элемент, соответствующий вашему запросу, но и все элементы с этим атрибутом.

Просмотрите документацию Selenium: поиск элементов и посмотрите, сможете ли вы попробовать все варианты поиска элементов, которые у них есть.

Что-то еще, чтобы попробовать:

button_element = driver.find_element(By.XPATH, "//button[@data-target-section-id='RIK0XK7NRnS21bVSiNaicw==']")
list_element.find_element(By.TAG_NAME, "button").click()

Я не могу использовать имя класса, потому что оно не уникально для кнопки, которую я хочу использовать, и может нажать неправильную кнопку.

Jesper Ezra 18.02.2023 21:29

Хотите поделиться используемой веб-страницей?

Python16367225 19.02.2023 01:17

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

Jesper Ezra 19.02.2023 05:57
Я также пытался сделать By.XPATH "//button[@data-target-section-id='RIK0XK7NRnS21bVSiNaicw==']")"" но тоже не находит.

Упомянутый вами идентификатор целевого раздела данных не совпадает с тем, который имеет кнопка (PTFmMNSPSz2LQRzwynhRBQ==). Убедитесь, что это не является динамическим, прежде чем нацеливаться на него.

Ваш xPath неплох, но, как я уже говорил, исправьте target-id:

driver.findElement(By.xpath("//button[@data-target-section-id='PTFmMNSPSz2LQRzwynhRBQ==']")).click()

Где «драйвер» — это ваш экземпляр WebDriver.

Что значит не то же самое? Не могли бы вы еще пояснить, что вы имеете в виду под этим?

Jesper Ezra 18.02.2023 21:28

Ваш xPath нацелен на data-target-section-id='RIK0XK7NRnS21bVSiNaicw==', а в вашем коде xPath имеет вид data-target-section-id = "PTFmMNSPSz2LQRzwynhRBQ= = "

Juan Melnechuk 18.02.2023 21:30

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

Jesper Ezra 18.02.2023 22:21

Используйте xPath Finder и захватывайте xPath независимо от значений кнопок.

Juan Melnechuk 18.02.2023 22:24

XPath Finder тоже не помог найти xPath

Jesper Ezra 19.02.2023 00:19

Пожалуйста, предоставьте HTML-код. Мы не можем дать вам какое-либо решение любым другим способом. Другое решение — взять нединамический родительский элемент и искать кнопки внутри этого элемента.

Juan Melnechuk 19.02.2023 00:32

Учитывая HTML:

<li>
   <button aria-current = "false" class = "search-navigation-panel_button" data-target-section-id = "PTFmMNSPSz2LQRzwynhRBQ= = " role = "link" type = "button"> People </button>
</li>

Значения атрибута data-target-section-id, такие как PTFmMNSPSz2LQRzwynhRBQ==, генерируются динамически и рано или поздно должны измениться. Они могут измениться при следующем повторном доступе к приложению или даже при следующем запуске приложения. Поэтому нельзя использовать в локаторах.


Решение

Желаемый элемент является динамическим элементом, чтобы щелкнуть по кликабельному элементу, который вам нужен, чтобы вызвать WebDriverWait для element_to_be_clickable() , и вы можете использовать любую из следующих стратегий локатора:

  • Использование CSS_SELECTOR:

    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button.search-navigation-panel_button[data-target-section-id]"))).click()
    
  • Использование XPATH:

    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//button[@class='search-navigation-panel_button' and @data-target-section-id][contains(., 'People')]"))).click()
    
  • Примечание. Вы должны добавить следующие импорты:

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

Время истекло. Я попытался увеличить время ожидания до полной минуты, но время ожидания продолжает истекать с параметрами CSS_SELECTOR и XPATH.

Jesper Ezra 18.02.2023 22:19

Соответствует ли HTML в моем ответе фактическому HTML на вашем конце?

undetected Selenium 18.02.2023 22:20

При более внимательном рассмотрении кажется, что класс не соответствует правильно, однако я не знаю, как сделать так, чтобы он соответствовал из-за формата. Класс выглядит следующим образом: class = "search-navigation-panel__button search-navigation-panel__button--active" Как я могу учитывать 2-ю строку в классе?

Jesper Ezra 19.02.2023 00:18

Комментарий неправильно отражает пробел. Это class = "search-navigation-panel__button \n search-navigation-panel__button--active"

Jesper Ezra 19.02.2023 00:22
Ответ принят как подходящий

Похоже, причина, по которой ваш локатор кнопки «Люди» не работает, заключается в том, что data-target-section-id является динамическим. Мой отображается как hopW8RkwTN2R9dPgL6Fm/w==. Мы можем обойти это, используя XPath для поиска элемента на основе содержащегося текста, «Люди», например.

//button[text()='People']

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

//button[text()='People'][@data-target-section-id]

Сказав это, эта ссылка только прокручивает страницу, поэтому вам не нужно нажимать на нее.

Оттуда вы хотите получить ссылки на каждого человека, указанного под заголовком «Люди». Сначала нам нужен DIV, который содержит раздел «Люди». Это немного запутанно, потому что идентификаторы этих элементов также являются динамическими, поэтому нам нужно найти H2, который содержит «People», а затем вернуться к DOM в DIV, который содержит только этот раздел. Мы можем получить это, используя XPath ниже

//div[@class='search-results-container']/div[.//h2[text()='People']]

Оттуда нам нужны все теги A, которые однозначно ссылаются на человека... и в этом разделе много тегов A, но большинство из них не те, которые нам нужны, поэтому нам нужно больше фильтровать. Я обнаружил, что приведенный ниже XPath находит каждый уникальный URL-адрес в этом разделе.

//a[contains(@href,'miniProfileUrn')][contains(@class,'scale-down')]

Комбинируя два XPath, мы получаем

//div[@class='search-results-container']/div[.//h2[text()='People']]//a[contains(@href,'miniProfileUrn')][contains(@class,'scale-down')]

Который находит все уникальные URL-адреса, принадлежащие человеку, в разделе «Люди» на странице.

Используя это, ваш код будет выглядеть так

all_users = driver.find_elements(By.XPATH, "//div[@class='search-results-container']/div[.//h2[text()='People']]//a[contains(@href,'miniProfileUrn')][contains(@class,'scale-down')]")

for user in all_users:
    print(user.get_attribute('href'))

ПРИМЕЧАНИЕ. Причина, по которой ваш код неоднократно возвращал только первый href, заключается в том, что вы выполняете поиск в существующем элементе с помощью XPath, поэтому вам нужно добавить «.». в начале XPath, чтобы указать, что поиск нужно начинать с указанного элемента.

get_links = users.find_element(By.XPATH, ".//*[contains(@href, 'miniProfileUrn')]")
                                          ^ add period here

Я исключил этот шаг в своем коде, поэтому он вам там не понадобится.

Другие вопросы по теме