I have made a program that clicks on various Instagram prompts, and I've used CSS_SELECTOR to recognize these buttons and to click on them. The problem is, it only works sometimes. In these cases
wait.until(ec.element_to_be_clickable((By.CSS_SELECTOR, ".aOOlW.bIiDR"))).click()
wait.until(ec.element_to_be_clickable((By.CSS_SELECTOR, ".aOOlW.HoLwm"))).click()
CSS_SELECTOR works fine, but in this case
wait.until(ec.element_to_be_clickable((By.CSS_SELECTOR, "sqdOP.L3NKy.y3zKF"))).click()
It doesn't work and returns this error:
Traceback (most recent call last):
File "C:/Users/~/PycharmProjects/InstagramBot1/main.py", line 40, in <module>
wait.until(ec.element_to_be_clickable((By.CSS_SELECTOR, "sqdOP.L3NKy.y3zKF"))).click()
File "C:\Users\~\PycharmProjects\InstagramBot1\venv\lib\site-packages\selenium\webdriver\support\wait.py", line 89, in until
raise TimeoutException(message, screen, stacktrace)
selenium.common.exceptions.TimeoutException: Message:
Stacktrace:
Backtrace:
Ordinal0 [0x00B63AB3 2505395]
Ordinal0 [0x00AFAE41 2076225]
Ordinal0 [0x00A02498 1057944]
Ordinal0 [0x00A2CB74 1231732]
Ordinal0 [0x00A56D92 1404306]
Ordinal0 [0x00A45A2A 1333802]
Ordinal0 [0x00A55168 1397096]
Ordinal0 [0x00A458BB 1333435]
Ordinal0 [0x00A223E4 1188836]
Ordinal0 [0x00A2323F 1192511]
GetHandleVerifier [0x00CECB36 1554566]
GetHandleVerifier [0x00D94A0C 2242396]
GetHandleVerifier [0x00BF0E0B 523099]
GetHandleVerifier [0x00BEFEB0 519168]
Ordinal0 [0x00B002FD 2097917]
Ordinal0 [0x00B04388 2114440]
Ordinal0 [0x00B044C2 2114754]
Ordinal0 [0x00B0E041 2154561]
BaseThreadInitThunk [0x76BA6359 25]
RtlGetAppContainerNamedObjectPath [0x775987A4 228]
RtlGetAppContainerNamedObjectPath [0x77598774 180]
Process finished with exit code 1
What am I doing wrong, and how can I make selenium recognize every button, not just some?
(Here is my full code:)
# Importing
import requests
from bs4 import BeautifulSoup
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support import expected_conditions as ec
from selenium.webdriver.support import ui
from selenium.webdriver.support.ui import WebDriverWait
# Setting everything up
service = Service("\Program Files (x86)\chromedriver.exe")
# Asking Questions
RandTimeInvalid = True
while RandTimeInvalid:
try:
RandomnessTime = int(input("Select Randomness Time:"))
RandTimeInvalid = False
except ValueError:
print("'Randomness Time' must be a number!")
RandTimeInvalid = True
InstagramUsername = input("Enter Username:")
InstagramPassword = input("Enter Password:")
# Logging In
driver = webdriver.Chrome(service=service)
driver.get('https://www.instagram.com/')
wait = ui.WebDriverWait(driver, 10)
driver.maximize_window()
wait.until(ec.element_to_be_clickable((By.CSS_SELECTOR, ".aOOlW.bIiDR"))).click()
RandomnessTime = WebDriverWait(driver, (1 - RandomnessTime))
LoginUsername = ui.WebDriverWait(driver, 10).until(ec.element_to_be_clickable((By.NAME, "username"))).send_keys(InstagramUsername)
LoginPassword = ui.WebDriverWait(driver, 10).until(ec.element_to_be_clickable((By.NAME, "password"))).send_keys(InstagramPassword, Keys.ENTER)
wait.until(ec.element_to_be_clickable((By.CSS_SELECTOR, "sqdOP.L3NKy.y3zKF"))).click()
wait.until(ec.element_to_be_clickable((By.CSS_SELECTOR, ".aOOlW.HoLwm"))).click()
page = requests.get('https://www.instagram.com')
soup = BeautifulSoup(page.content, 'html.parser')
links = soup.select("span")
print(links)P[
CodePudding user response:
There is nothing wrong in your code but within the locator strategies.
By.CSS_SELECTOR, ".aOOlW.bIiDR"
indicates you are using classnames to locate element and these classnames are dynamically generated. So each time you access the AUT (Application Under Test), you won't find the classnames of previous executions as they are generated randomly afresh on each access.
Hence the desired elements aren't found and due to the wait
wrapper you see the TimeoutException
error.