Как в Selenium найти элемент по атрибуту name, игнорируя различия в регистре символов?

Я использую локатор <code class="html">find_element_by_partial_link_text</code> для поиска элемента, но на разных страницах текст ссылки отображается в разном регистре — иногда весь в верхнем, иногда в нижнем, иногда смешанный — и в таких случаях локатор ничего не находит. Как выполнить поиск, игнорируя регистр символов?
  • 17 марта 2026 г. 9:07
Ответы на вопрос 3
Коротко — через XPath + функция translate(), либо получить элементы и отфильтровать в Python/JS. В XPath нет lower() (в 1.0), поэтому нужно вручную сопоставить верхний/нижний регистр символов.

1) Пример для поиска по тексту ссылки (partial link text), нечувствительно к регистру:

Python / Selenium 4:
from selenium.webdriver.common.by import By

target = "искать"  # строка в любом регистре, лучше привести к lower() заранее
# переводим текст узла в нижний регистр через translate()
xpath = (
    "//a[contains(translate(normalize-space(.), "
    "'ABCDEFGHIJKLMNOPQRSTUVWXYZАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ',"
    "'abcdefghijklmnopqrstuvwxyzабвгдеёжзийклмнопрстуфхцчшщъыьэюя'), "
    f"'{target.lower()}')]"
)
elem = driver.find_element(By.XPATH, xpath)

Обратите внимание: в translate() нужно перечислить все символы, которые вы хотите "понизить" — в примере включены латиница и русская кириллица (вместе с Ё/ё).

2) По атрибуту name (точное или частичное совпадение), нечувствительно к регистру:

# точное совпадение
name_val = "MyName"
xpath_exact = (
    f"//*[@name and translate(@name, "
    "'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz') = '{name_val.lower()}']"
)
elem = driver.find_element(By.XPATH, xpath_exact)

# частичное совпадение
partial = "часть"
xpath_contains = (
    f"//*[@name and contains(translate(@name, "
    "'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), '{partial.lower()}')]"
)
elem = driver.find_element(By.XPATH, xpath_contains)

3) Альтернативы:
- Если хочется проще (и не хочется писать длинную translate для кириллицы), можно взять все элементы и отфильтровать в Python:

elems = driver.find_elements(By.TAG_NAME, "a")
elem = next((e for e in elems if partial.lower() in e.text.strip().lower()), None)

- Или отфильтровать в браузере через JS (быстро и гибко для Unicode):

js = """
return Array.from(document.querySelectorAll('a'))
  .find(a => a.textContent && a.textContent.trim().toLowerCase().includes(arguments[0].toLowerCase()));
"""
elem = driver.execute_script(js, partial)

Замечания:
- XPath-translate работает посимвольно — если ваша страница содержит другие алфавиты (греческий, турецкий и т.д.), их тоже надо добавить в mapping.
- При использовании строк с одиночными кавычками в XPath аккуратно экранируйте/меняйте кавычки (либо используйте concat()).

Если скажете, для какого языка/алфавита у вас реальные варианты ссылок (например только латиница или русская кириллица), могу дать готовую точную строку translate().
Придется, видимо, получить список всех ссылок, пропустить их через regex, и затем обратиться к нужному элементу, повторно.
<a href="http://qna.habr.com/user/rkfddf">rkfddf</a> написать xpath локатор который преобразует регистр : <br/> <pre><code>[
  '//a[contains(@href,"{}")]'.format(url_fragment.lower()),
   '//a[contains(translate(@href, "abcdefghijklmnopqrstuvwxyz", "ABCDEFGHIJKLMNOPQRSTUVWXYZ"), "{}")]'.format(url_fragment.upper())
]
length = len(xpaths)
for cnt in range(length):
  xpath = xpaths[cnt]

  print('# try {}'.format(cnt))
  element = None
  try:
    element = driver.find_element_by_xpath(xpath)
  except InvalidSelectorException, e:
    print('Exception (ignored): {}'.format(e))
    pass
  except NoSuchElementException, e:
    print('Exception (ignored): {0}'.format(e))
    pass
  if element != None:
    print('Found via {}'.format(xpath))
    print(element.get_attribute('outerHTML'))
  else:
    print('Failed via {}'.format(xpath))</code></pre>
Похожие вопросы