2

I am using temporary emails for my selenium project but I've been stuck on this issue for some time. The information always seems to be changing and I cannot figure out how I'm supposed to write it. This is the HTML:

<a href="https://temp-mail.org/en/view/cd89ea25d93a2fed0d182d9d8225b5b" title="" class="viewLink title-subject" data-mail-id="cd89ea25d93a2fed0d182d9d82425b5b">812479 is your Instagram code</a>

I've tried to find the mail-id using various methods that I've read about.

execute = browser.find_element_by_xpath('.//span[@class = "data-mail-id"]') #Attempt 1
execute = browser.find_element_by_xpath('//span[text()="Instagram"]')

I've even copied the full xpath but it always returns Unable to Locate Element However, the data-mail-id and the code changes every time you send an email to your inbox. What do I need to change?

I want the string ("812479") that's followed by " is your Instagram code".

kjhughes
  • 106,133
  • 27
  • 181
  • 240
prxvidxnce
  • 369
  • 1
  • 10
  • The only things that change are the id and the code – prxvidxnce Nov 10 '20 at 16:04
  • Note that the class is not `data-mail-id` but `viewLink title-subject` and the text() is not `Instagram` but `812479 is your Instagram code`. Maybe you need `contains()`? – choroba Nov 10 '20 at 16:14
  • 1
    So would it be something like `//*[contains(text(), "is your Instagram code")]` ? – prxvidxnce Nov 10 '20 at 16:16
  • What if I found the best answer to my question ? – prxvidxnce Nov 28 '20 at 08:08
  • If it differs substantially from the answers received, then you should post and accept it. If it's substantially similar to one of the posted answer, then accept the posted answer and optionally comment on how you adjusted it to fit your needs. The goal is to help future readers while crediting those who've helped you via accepts and upvotes as you feel reflect contributions and helpfulness. – kjhughes Nov 28 '20 at 15:35

2 Answers2

3

Straight XPath 1.0

This XPath expression,

substring-before(//a[contains(.,' is your Instagram code')][1], 
                 ' is your Instagram code')

will return the substring before ' is your Instagram code' in the first a element that contains that string, or the empty string if no such element exists.


XPath in Selenium

You can select the a element via XPath in Selenium,

a = browser.find_element_by_xpath("//a[contains(.,' is your Instagram code')][1]")

Then access the element's text via a.text and use split() to implement substring-before() (link shows after, but technique is easily adapted to before).

kjhughes
  • 106,133
  • 27
  • 181
  • 240
  • Forgive my ignorance because I don't really use selenium but was this the format you were talking about? `browser.find_element_by_xpath("//a[contains(.,' is your Instagram code')][1], ' is your Instagram code'")` – prxvidxnce Nov 10 '20 at 16:37
  • Answer updated to address Selenium follow-up comment. – kjhughes Nov 10 '20 at 17:59
  • I think I'm doing something wrong? When I get the confirmation email, I `sleep(60)` just to make sure the element is fully loaded in. I then run `a = browser.find_element_by_xpath("//a[contains(.,' is your Instagram code')][1]")` but it still says element is Unable to be Located – prxvidxnce Nov 10 '20 at 21:13
  • Back off the complexity of the XPath until you prove that something's working. See, for example, if you can get any `a` via `//a`. Then add back simple filters until you build up to working code. – kjhughes Nov 10 '20 at 23:43
1

I'm a big fan of using exepected_conditions to avoid timing issues between the page loading and the script execution.

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

myec = EC.visibility_of_element_located(
    (By.XPATH, '//a[contains(text(), "is your Instagram code")]'))

# search for the element on the page until found or TimeoutException is raised
wait = WebDriverWait(driver, timeout)
myelement = wait.until(myec, "Could not find Instagram Code") 
Marcel Wilson
  • 3,842
  • 1
  • 26
  • 55