[python] Selenium Webdriver (Python)에서 특정 텍스트가 포함 된 요소를 찾으려면 어떻게합니까?

Selenium (Python 인터페이스 사용 및 여러 브라우저에서)으로 복잡한 Javascript 인터페이스를 테스트하려고합니다. 양식의 여러 버튼이 있습니다.

<div>My Button</div>

“My Button”(또는 “my button”또는 “button”과 같이 대소 문자를 구분하지 않는 부분 일치)을 기반으로 버튼을 검색하고 싶습니다.

나는 명백한 것을 놓치고 있다고 느끼는 정도로 놀랍도록 어려운 것을 발견하고 있습니다. 내가 지금까지 가장 좋은 것은 :

driver.find_elements_by_xpath('//div[contains(text(), "' + text + '")]')

그러나 이것은 대소 문자를 구분합니다. 내가 시도한 또 다른 것은 페이지의 모든 div를 반복하고 element.text 속성을 확인하는 것입니다. 그러나 다음과 같은 상황이 발생할 때마다 :

<div class="outer"><div class="inner">My Button</div></div>

div.outer에는 “My Button”도 텍스트로 사용됩니다. 그 문제를 해결하기 위해 div.outer가 div.inner의 부모인지 확인하려고했지만 그 방법을 알 수 없었습니다 (element.get_element_by_xpath ( ‘..’)는 요소의 부모를 반환하지만 div.outer와 같지 않은 테스트). 또한 적어도 Chrome 웹 드라이버를 사용하면 페이지의 모든 요소를 ​​반복하는 것이 실제로 느린 것 같습니다.

아이디어?

편집 :이 질문은 약간 모호하게 나왔습니다. 더 구체적인 버전을 여기 에서 묻고 대답했습니다 : 자식 요소 텍스트를 포함하지 않고 Selenium WebDriver에서 요소를 텍스트로 얻는 방법 (파이썬 API를 통해)?



답변

다음을 시도하십시오 :

driver.find_elements_by_xpath("//*[contains(text(), 'My Button')]")


답변

다음과 같은 xpath를 시도 할 수 있습니다.

'//div[contains(text(), "{0}") and @class="inner"]'.format(text)


답변

페이지 객체 패턴과 함께 사용할 수도 있습니다. 예 :

이 코드를 사용해보십시오 :

@FindBy(xpath = "//*[contains(text(), 'Best Choice')]")
WebElement buttonBestChoice;


답변

// *는 HTML 태그를 찾습니다. Button 및 div 태그에 공통적 인 텍스트가 있고 // *가 범주 인 경우 예상대로 작동하지 않습니다. 특정을 선택해야하는 경우 HTML 요소 태그를 선언하여 가져올 수 있습니다. 처럼:

driver.find_element_by_xpath("//div[contains(text(),'Add User')]")
driver.find_element_by_xpath("//button[contains(text(),'Add User')]")


답변

흥미롭게도 거의 모든 답변은 xpath의 기능 과 관련이 있으며 OP의 요청과 달리 contains()대소 문자를 구분 한다는 사실을 무시합니다 .
대소 문자를 구분하지 않으면 xpath 1.0 (현대 브라우저가 지원하는 버전) 에서 달성 할 수 있지만 translate()기능 을 사용하는 것은 좋지 않습니다 . 변환 표를 사용하여 소스 문자를 원하는 형식으로 대체합니다.

모든 대문자 문자의 테이블을 구성하면 노드의 텍스트를 효과적으로 더 낮은 () 형식으로 변환하여 대소 문자를 구분하지 않는 일치를 허용합니다 (여기서는 특권이 있습니다) .

[
  contains(
    translate(text(), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'),
    'my button'
  )
]
# will match a source text like "mY bUTTon"

전체 파이썬 호출 :

driver.find_elements_by_xpath("//*[contains(translate(text(), 'ABCDEFGHIJKLMNOPQRSTUVWXYZЙ', 'abcdefghijklmnopqrstuvwxyzй'), 'my button')]")

당연히이 방법에는 단점이 있습니다. 주어진 바와 같이 라틴어 텍스트에 대해서만 작동합니다. 유니 코드 문자를 다루려면 번역 테이블에 해당 문자를 추가해야합니다. 위 샘플에서 마지막 문자는 키릴 문자입니다 "Й".


그리고 브라우저가 xpath 2.0 이상을 지원하는 세계에 살았다면 (곧 올 수는 없지만) , lower-case()(로케일을 완전히 인식하지는 못함) 기능을 사용할 수 있었으며 matches(정규 검색을 위해 경우에 따라) -둔감 한 ( 'i') 플래그).


답변

제공 한 HTML에서 :

<div>My Button</div>

텍스트 My ButtoninnerHTML주위에 공백이 없으므로 text()다음과 같이 쉽게 사용할 수 있습니다 .

my_element = driver.find_element_by_xpath("//div[text()='My Button']")

참고 : text()컨텍스트 노드의 모든 텍스트 노드 자식을 선택합니다


선행 / 후행 공백이있는 텍스트

시작 부분에 공백이 포함 된 관련 텍스트를 넣으십시오 .

<div>   My Button</div>

또는 끝에 :

<div>My Button   </div>

또는 양쪽 끝에서 :

<div> My Button </div>  

이 경우 두 가지 옵션이 있습니다.

  • contains()첫 번째 인수 문자열에 두 번째 인수 문자열이 포함되어 있는지 여부를 판별하고 다음과 같이 부울 true 또는 false를 리턴 하는 함수를 사용할 수 있습니다 .

    my_element = driver.find_element_by_xpath("//div[contains(., 'My Button')]")
  • normalize-space()문자열에서 선행 및 후행 공백을 제거하고 공백 문자 시퀀스를 단일 공백으로 바꾸고 결과 문자열을 다음과 같이 반환하는 함수를 사용할 수 있습니다 .

    driver.find_element_by_xpath("//div[normalize-space()='My Button']]")

변수 텍스트에 대한 xpath

텍스트가 변수 인 경우 다음을 사용할 수 있습니다.

foo= "foo_bar"
my_element = driver.find_element_by_xpath("//div[.='" + foo + "']")


답변

wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//*[contains(text(), 'YourTextHere')]")));
    assertNotNull(driver.findElement(By.xpath("//*[contains(text(), 'YourTextHere')]")));
    String yourButtonName=driver.findElement(By.xpath("//*[contains(text(), 'YourTextHere')]")).getAttribute("innerText");
    assertTrue(yourButtonName.equalsIgnoreCase("YourTextHere"));