So I'm trying to find a way to make sure my bot doesn't get confused and click on the Following button again (it uses span to detect text) when it has already followed that particular user. I am trying to detect that if a user is already followed, the bot should skip him through another method, which is if the bot finds the following text on the user's profile "Turn on Tweet notifications" that means the user is already followed because there will be a bell icon/button present on his profile.
The issue is, I fail to detect that text/button. What am I doing wrong?
Here's the code:
def to_follow_delay():
def to_follow_delay_2():
try:
driver.get(next(urls))
if wait.until(EC.visibility_of_element_located((By.XPATH, "//div[contains(@aria-label,'Turn on Tweet notifications')]"))):
i = 1
while True:
skipped_user = "skipped_following" str(i) ".png"
if not os.path.isfile(skipped_user):
break
i = 1
already_following = datetime.datetime.now()
print(already_following, "Already following... skipping")
driver.get_screenshot_as_file(skipped_user)
def skip_user():
driver.get(next(urls))
skiptimer = threading.Timer(10, skip_user)
skiptimer.start
return to_follow_delay()
else:
def follow_user():
sleep(5)
followuser = wait.until(EC.element_to_be_clickable((By.XPATH, '//span[text()="Follow"]')))
followuser.click()
followsuccess = datetime.datetime.now()
print(followsuccess, "Follow successful")
print("--- %s seconds ---" % (time.time() - starting4))
i = 1
while True:
followed_user_success = "followed" str(i) ".png"
if not os.path.isfile(followed_user_success):
break
i = 1
driver.get_screenshot_as_file(followed_user_success)
followedper_runcounter.set(followedper_runcounter.get() 1)
followedcounter.set(followedcounter.get() 1)
return operation_follow()
timer4 = threading.Timer(tofollowdelayvalue_txt.get(), follow_user)
timer4.start()
starting4 = time.time()
except StopIteration:
nourls = datetime.datetime.now()
print(nourls, "No more urls.")
return
timer5 = threading.Timer(5, to_follow_delay_2)
timer5.start()
Twitter code:
<div aria-label="Turn on Tweet notifications" role="button" tabindex="0" ><div dir="auto" ><svg viewBox="0 0 24 24" aria-hidden="true" ><g><path d="M23.24 3.26h-2.425V.832c0-.414-.336-.75-.75-.75s-.75.336-.75.75V3.26H16.89c-.414 0-.75.335-.75.75s.336.75.75.75h2.426v2.424c0 .414.336.75.75.75s.75-.336.75-.75V4.76h2.425c.415 0 .75-.337.75-.75s-.336-.75-.75-.75zm-6.23 7.606c.02-2.434-.782-4.597-2.258-6.09-1.324-1.342-3.116-2.084-5.046-2.093h-.013c-1.93.01-3.722.75-5.046 2.092C3.172 6.27 2.37 8.433 2.39 10.867 2.426 15 .467 16.56.39 16.62c-.26.193-.367.53-.266.838.102.308.39.515.712.515h4.716c.11 2.226 1.94 4.007 4.194 4.007s4.083-1.78 4.194-4.007h4.625c.32 0 .604-.206.707-.51s0-.643-.255-.838c-.082-.064-2.043-1.625-2.008-5.76zM9.745 20.48c-1.426 0-2.586-1.11-2.694-2.508h5.388c-.108 1.4-1.268 2.507-2.694 2.507zm-7.29-4.007c.702-1.095 1.457-2.904 1.434-5.618-.017-2.062.614-3.8 1.825-5.025C6.757 4.774 8.172 4.19 9.7 4.184c1.527.007 2.943.59 3.985 1.646 1.21 1.226 1.84 2.963 1.823 5.025-.022 2.714.732 4.523 1.437 5.618H2.455z"></path></g></svg><span ></span></div></div>
The error stacktrace:
if wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, "button[aria-label='Turn on Tweet notifications'][role='button']"))):
File "C:\Users\Cassano\AppData\Roaming\Python\Python38\site-packages\selenium\webdriver\support\wait.py", line 89, in until
raise TimeoutException(message, screen, stacktrace)
selenium.common.exceptions.TimeoutException: Message:
Stacktrace:
Backtrace:
Ordinal0 [0x00AF6903 2517251]
Ordinal0 [0x00A8F8E1 2095329]
Ordinal0 [0x00992848 1058888]
Ordinal0 [0x009BD448 1233992]
Ordinal0 [0x009BD63B 1234491]
Ordinal0 [0x009E7812 1406994]
Ordinal0 [0x009D650A 1336586]
Ordinal0 [0x009E5BBF 1399743]
Ordinal0 [0x009D639B 1336219]
Ordinal0 [0x009B27A7 1189799]
Ordinal0 [0x009B3609 1193481]
GetHandleVerifier [0x00C85904 1577972]
GetHandleVerifier [0x00D30B97 2279047]
GetHandleVerifier [0x00B86D09 534521]
GetHandleVerifier [0x00B85DB9 530601]
Ordinal0 [0x00A94FF9 2117625]
Ordinal0 [0x00A998A8 2136232]
Ordinal0 [0x00A999E2 2136546]
Ordinal0 [0x00AA3541 2176321]
BaseThreadInitThunk [0x770EFA29 25]
RtlGetAppContainerNamedObjectPath [0x77B47A9E 286]
RtlGetAppContainerNamedObjectPath [0x77B47A6E 238]
CodePudding user response:
To locate the visible element with text as Turn on Tweet notifications you need to induce WebDriverWait for the visibility_of_element_located() and you can use either of the following Locator Strategies:
Using
CSS_SELECTOR
:element = WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.CSS_SELECTOR, "div[aria-label='Turn on Tweet notifications'][role='button']")))
Using
XPATH
:element = WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.XPATH, "//div[@aria-label='Turn on Tweet notifications' and @role='button']")))
Note : You have to add the following imports :
from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.common.by import By from selenium.webdriver.support import expected_conditions as EC