मुझे ऐसा तत्व कैसे मिलेगा जिसमें सेलेनियम वेबड्राइवर (पायथन) में विशिष्ट पाठ हो?


259

मैं सेलेनियम के साथ एक जटिल जावास्क्रिप्ट इंटरफ़ेस का परीक्षण करने की कोशिश कर रहा हूं (पायथन इंटरफ़ेस का उपयोग करके, और कई ब्राउज़रों में)। मेरे पास फॉर्म के कई बटन हैं:

<div>My Button</div>

मैं "मेरा बटन" (या गैर-केस-संवेदी, आंशिक मिलान जैसे "मेरा बटन" या "बटन") के आधार पर बटन खोजना चाहूंगा

मुझे यह आश्चर्यजनक रूप से मुश्किल लग रहा है, जिस हद तक मुझे लगता है कि मुझे कुछ स्पष्ट याद आ रहा है। मेरे पास अब तक की सबसे अच्छी चीज़ है:

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

हालांकि यह मामला संवेदनशील है। दूसरी चीज़ जो मैंने कोशिश की है, वह पृष्ठ के सभी divs के माध्यम से पुनरावृत्त कर रही है, और element.text संपत्ति की जाँच कर रही है। हालाँकि, हर बार आपको फॉर्म की एक स्थिति मिलती है:

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

div.outer में टेक्स्ट के रूप में "My Button" भी है। THAT को ठीक करने के लिए, मैंने यह देखने की कोशिश की है कि div.outer div.inner का माता-पिता है, लेकिन यह पता नहीं लगा सका कि वह कैसे (element.get_element_by_xpath ('..') एक तत्व के माता-पिता को लौटाता है, लेकिन यह div.outer के बराबर परीक्षण नहीं)। साथ ही, पृष्ठ पर सभी तत्वों के माध्यम से पुनरावृत्ति वास्तव में धीमी प्रतीत होती है, कम से कम क्रोम वेबड्राइवर का उपयोग करते हुए।

विचार?

संपादित करें: यह सवाल थोड़ा अस्पष्ट है। यहां एक और अधिक विशिष्ट संस्करण पूछा (और उत्तर दिया गया): बाल तत्व पाठ को शामिल किए बिना सेलेनियम वेबड्राइवर (पायथन एपी के माध्यम से) में एक तत्व का पाठ कैसे प्राप्त करें?


वर्तमान उत्तर मेरे काम नहीं आए। यह एक किया: sqa.stackexchange.com/a/2486
alejandro

जवाबों:


328

निम्नलिखित आज़माएँ:

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

3
उत्तर के लिए धन्यवाद, यह 50% था जो मुझे चाहिए था (मुझे मिल गया)। मैं जिस रूप में आया वह यह है "" (// * [[(पाठ (), '' + पाठ + "')): // // * @ @ मूल्य ='" + पाठ + ""]) "यह खोज करेगा दिए गए पाठ को न केवल तत्व नोड्स के अंदर, बल्कि उन इनपुट तत्वों के अंदर भी दिया जाता है जिनके पाठ को 'मूल्य' विशेषता अर्थात <बटन मूल्य = "मेरा बटन" /> के माध्यम से सेट किया गया था। हालांकि ध्यान दें, मूल्य का मिलान सख्त होना चाहिए, न कि केवल पाठ को शामिल करना।
इवान कोशेलेव

9
अन्य खोज इंजन आगंतुकों के लिए भी उल्लेख के लायक: यदि आप एक लिंक की तलाश कर रहे हैं, तो तरीके find_element(s)_by_link_textऔर find_element(s)_by_partial_link_textतरीके हैं
Dan Passaro

3
यदि पाठ गतिशील है तो क्या होगा? अर्थात्, उद्धरण शामिल हो सकते हैं। क्या यह समाधान नहीं टूटेगा?
इडेडांटे

3
कुछ नामों की खोज से ऐसा लगता है। एक उदाहरण के लिए निम्नलिखित लें: "// * [(पाठ ()," "+ उपयोगकर्ता नाम +")] "" यदि उपयोगकर्ता नाम = "O'Reilly"; तब xpath अमान्य हो जाएगा। क्या इसके चारों ओर एक रास्ता है?
सकामोटो कज़ुमा

जब लक्ष्य पाठ में कई लाइनें हों, तो यह काम नहीं करता है।
शॉन

29

आप एक xpath की कोशिश कर सकते हैं जैसे:

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

धन्यवाद ... इतना है कि बाहरी से आंतरिक भेद में मदद करता है, लेकिन यह वास्तव में xpath के साथ ठीक काम करता है, मैं केवल सभी divs के माध्यम से iterating कि समस्या हो रही थी। Xpath के साथ मेरी समस्या यह है कि मैं इसे केस-असंवेदनशील कैसे बना सकता हूं?
josh

2
xpath 2.0 में एक लोअर-केस फंक्शन है, इसलिए यह काम करना चाहिए: '// div [(लोअर-केस (टेक्स्ट)), "{0}")]' 'फॉर्मेट (टेक्स्ट)
andrean

धन्यवाद! हालाँकि, मेरी समझ यह है कि xpath 2.0 प्रमुख ब्राउज़रों में समर्थित नहीं है ...
josh

सेलेनियम, ब्राउज़र के स्वयं के तरीकों से सीधे xpath अभिव्यक्तियों का मूल्यांकन करता है, इसलिए यह निर्भर करता है कि आप सेलेनियम के साथ किस ब्राउज़र का उपयोग कर रहे हैं। आम तौर पर केवल 6,7 और 8 को xpath 2.0 का समर्थन नहीं करना चाहिए।
andrean

.formatमेरे ग्रहण में मान्यता नहीं है। यह देता है और त्रुटि। किसी भी विचार, क्यों?
अनुज

16

आप इसका उपयोग पेज ऑब्जेक्ट पैटर्न के साथ भी कर सकते हैं, जैसे:

इस कोड को आज़माएं:

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

13

// * किसी भी HTML टैग की तलाश में होगा। यदि बटन और div टैग के लिए कुछ पाठ सामान्य है और यदि // * श्रेणियां हैं तो यह अपेक्षित रूप से काम नहीं करेगा। अगर आपको किसी विशिष्ट का चयन करने की आवश्यकता है तो आप HTML एलिमेंट टैग घोषित करके प्राप्त कर सकते हैं। पसंद:

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

5

दिलचस्प रूप से लगभग सभी उत्तर xpath के फ़ंक्शन के चारों ओर घूमते हैं 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 और ऊपर (but, लेकिन जल्द ही could नहीं होने पर) का समर्थन करते थे , तो हम फ़ंक्शंस का उपयोग कर सकते थे lower-case()(फिर भी, पूरी तरह से स्थानीय-जागरूक नहीं), और matchesregex खोजों के लिए, केस के साथ -insensitive ( 'i') ध्वज)।


3

HTML में जो आपने प्रदान किया है:

<div>My Button</div>

पाठ My Buttonएक है innerHTMLऔर इसके आसपास कोई व्हाट्सएप नहीं है ताकि आप आसानी से 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>  

इन मामलों में आपके पास 2 विकल्प हैं:

  • आप contains()फ़ंक्शन का उपयोग कर सकते हैं जो यह निर्धारित करता है कि पहले तर्क स्ट्रिंग में दूसरा तर्क स्ट्रिंग है या बूलियन सही है या गलत इस प्रकार है:

    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 + "']")

1
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"));

1

इसी तरह की समस्या: ढूँढें <button>Advanced...</button>

शायद यह आपको कुछ विचार देगा (कृपया अवधारणा को जावा से पायथन में स्थानांतरित करें):

wait.until(ExpectedConditions.elementToBeClickable(//
    driver.findElements(By.tagName("button")).stream().filter(i -> i.getText().equals("Advanced...")).findFirst().get())).click();

0

अपने पाठ द्वारा तत्व की असंवेदनशील खोज के लिए ड्राइवर.find_elements_by_xpath का उपयोग करें और regex मिलान फ़ंक्शन से मेल खाता है

driver.find_elements_by_xpath("//*[matches(.,'My Button', 'i')]")

matches()एक xpath 2.0 फ़ंक्शन है, और ब्राउज़र को अफसोस केवल 1.0 के लिए समर्थन है।
टोडर मिनाकोव

-19

इसे इस्तेमाल करे। यह बहुत आसान है:

driver.getPageSource().contains("text to search");

यह सच में मेरे लिए सेलेनियम वेब ड्राइवर में काम किया।


9
जावास्क्रिप्ट द्वारा पाठ उत्पन्न होने पर यह काम नहीं करता है।
पैलसिंट

2
यह जाँचने का एक बहुत ही तरीका है, क्योंकि आप पृष्ठ की पूरी सामग्री को तार के ऊपर स्थानांतरित कर रहे हैं। बहुत छोटे पृष्ठों के लिए यह स्वीकार्य है लेकिन बहुत बड़े पृष्ठों के लिए आप फ़ाइल की सभी सामग्रियों को स्थानांतरित कर रहे हैं और सर्वर की तरफ जाँच रहे हैं। एक बेहतर तरीका यह होगा कि वह क्लाइंट की तरफ xpath, javascript या css के साथ करे।
thomas.han

मुझे लगता है कि इसे रेंडर करने के लिए पूरे पृष्ठ स्रोत को पहले ही ब्राउज़र के लिए तार पर स्थानांतरित करने की आवश्यकता होगी?
रेने

3
जोश पूछ रहा है कि पाठ द्वारा तत्व को कैसे खोजना है, यह जांचने के लिए नहीं कि पाठ पृष्ठ के स्रोत में मौजूद है या नहीं।
सेड्रिक

1
ऐसे उदाहरणों के लिए जहां सभी की जरूरत होती है, एक पृष्ठ पर एक स्थिर पाठ खोजना है, यह समाधान काफी अच्छा है। (इसने मेरे मामले में मदद की)।
कार्लथ 23
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.