I'm trying to locate the button element "Follow" because it contains the text of the user that you're going to follow.
Element:
<div aria-label="Follow @Visiongeo" role="button" tabindex="0" data-testid="1676648952-follow" style="background-color: rgb(239, 243, 244);"><div dir="auto" style="color: rgb(15, 20, 25);"><span ><span >Follow</span></span></div></div>
But the thing is, the text after Follow, which is @Visiongeo changes, so I don't want to particularly locate the element with specific text.
Instead, I want to locate this element, and then get the text that starts with "@" and write it to a text file.
My code:
for followers in wait.until(EC.element_to_be_clickable((By.XPATH, "//div[starts-with(@aria-label, 'Follow')]"))):
file = open("testfile.txt", "a")
file.write(followers)
file.write("\n")
file.close()
I get TimeoutException message when I use the above code. I think I'm way off from what I intend to do.
CodePudding user response:
To locate the element with aria-label
as Follow @Visiongeo you can use either of the following Locator Strategies:
xpath 1:
//div[starts-with(@aria-label, 'Follow') and contains(@data-testid, 'follow')]
xpath 2:
//div[starts-with(@aria-label, 'Follow') and contains(@data-testid, 'follow')][//span[text()='Follow']]
xpath 3:
//div[starts-with(@aria-label, 'Follow') and contains(@data-testid, 'follow')]//span[text()='Follow']//ancestor::div[1]//ancestor::div[1]
Inducing WebDriverWait for the visibility_of_all_elements_located() you can use:
for followers in wait.until(EC.visibility_of_all_elements_located((By.XPATH, "//div[starts-with(@aria-label, 'Follow') and contains(@data-testid, 'follow')]"))):
To parse the names of the followers you can use:
for followers in [my_elem.get_attribute("aria-label").split("@")[1] for my_elem in WebDriverWait(driver, 20).until(EC.visibility_of_all_elements_located((By.XPATH, "//div[starts-with(@aria-label, 'Follow') and contains(@data-testid, 'follow')]")))]: