I am using selenium webdriver in a Django (Python) app. My question is xpath however.
For some reason, schools have not standardized a central source to lookup transcript information, and thoroughly enjoy charging former students for the wonderful service of clicking a button, while requiring the paying party to do the work of ordering them. I am automating ordering them and came across this recent pattern which a function I wrote can't handle:
<a href="HTTPS://hccadvisor.hccfl.edu:443/WebAdvisor/WebAdvisor?TOKENIDX=4932326730&type=P&pid=UT-LGRQ"
onmouseover="window.status=''; return true;">
<span class="label">Log In </span>
</a>
It must be grabbed each time, as the token is being tacked on in the middle.
My function was calling
def access_link_by_text(text, driver):
block = driver.find_element_by_xpath("//a[text()='{text}']".format(text=text))
link = block.get_attribute('href')
driver.get(link)
but at 2 of my other schools sites I see wrapping the text within spans:
login_block = hcc_driver.find_element_by_xpath("//a/span[text()='Log In ']")
login_link = login_block.get_attribute('href')
Where login_link does not exist, as login_block is not grabbing the <a href... that I want it to. It grabs the span, since I said "any a's with span children whose text is Log In ". I want to grab the a using the child span as a test, so I tried:
login_block = hcc_driver.find_element_by_xpath("//a/child::span[text()='Log In ']")
which also failed.
How do you use children/parents/siblings as qualifying tests, without trying to pick them so I can get this link?
Thank you
Where login_link does not exist, as login_block is not grabbing the
<a href...that I want it to. It grabs the span, since I said "any a's with span children whose text is Log In ". I want to grab the a using the child span as a test, so I tried:
You are close. You can nest predicates. The solution should be:
//a[child::span[text()='Log In ']]
Which will select every <a> in the document that has a span that has a text node with the text "Log In ". You may want to be careful about possible added whitespace, this is a bit safer:
//a[child::span[normalize-space(text())='Log In']]
And for the fun of it, you can also revert your expression, if you find that more readable:
span[normalize-space(text())='Log In']/parent::a
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With