Hi I've been stuck for awhile on automating login for apple appstore as I am trying to make it headless without seeing the browser on execution.The problem is on execution with headless option and other options overall it doesn't find the field for appleid saying:
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"css selector","selector":"[id="account_name_text_field"]"}
This is the code I tried so far:
options = selenium_chrome()
options.add_argument("--enable-javascript")
options.add_argument('headless')
options.add_argument('--window-size=1920x1080')
options.add_argument('--start-maximized')
options.add_argument("--disable-notifications")
options.add_argument('--no-sandbox')
options.add_argument('--verbose')
options.add_experimental_option("prefs", {
"download.default_directory": DOWNLOAD_DIR,
"download.prompt_for_download": False,
"download.directory_upgrade": True,
"safebrowsing_for_trusted_sources_enabled": False,
"safebrowsing.enabled": False
})
options.add_argument('--disable-gpu')
options.add_argument('--disable-software-rasterizer')
driver = webdriver.Chrome('/path/to/chromedriver', chrome_options=options)
driver.get('https://appstoreconnect.apple.com/login')
cookies = pickle.load(open("cookies.pkl", "rb"))
for cookie in cookies:
driver.add_cookie(cookie)
time.sleep(10)
f = driver.find_element_by_id("aid-auth-widget-iFrame")
driver.switch_to.frame(f)
# driver.implicitly_wait(15)
time.sleep(20)
driver.find_element_by_id('account_name_text_field').send_keys('appleid')
driver.find_element_by_id("sign-in").click()
time.sleep(5)
driver.find_element_by_id('remember-me').click()
time.sleep(3)
driver.find_element_by_id('password_text_field').send_keys('password')
driver.find_element_by_id("sign-in").click()
Notes:
I have tried getting the XPATH and CSS selectors instead of the ID and the result was the same.
Instead of time.sleep()
I tried:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//input[@id='account_name_text_field']"))).send_keys('appleid')
and the result was TimeoutException
So I am out of ideas what causes this behavior,the field is being found without the options for selenium and it logins fine visually, but whenever options are being added it doesn't find the input text field for appleid
anymore... Might be an Apple thing that I don't know.
The <input>
element with the placeholder as Apple ID is within an iframe so you have to:
Induce WebDriverWait for the desired frame to be available and switch to it.
Induce WebDriverWait for the desired element to be clickable.
You can use either of the following Locator Strategies:
Using CSS_SELECTOR:
driver.get("https://appstoreconnect.apple.com/login")
WebDriverWait(driver, 20).until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR,"iframe#aid-auth-widget-iFrame")))
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "input#account_name_text_field"))).send_keys("mastaofthepasta")
Using XPATH:
driver.get("https://appstoreconnect.apple.com/login")
WebDriverWait(driver, 20).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH,"//iframe[@id='aid-auth-widget-iFrame']")))
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//input[@id='account_name_text_field']"))).send_keys("mastaofthepasta")
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
Browser Snapshot:
You can find a couple of relevant discussions in:
When you use google-chrome-headless and print the page_source the output on the console is:
<html><head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
<hr><center>Apple</center>
<!-- a padding to disable MSIE and Chrome friendly error page -->
<!-- a padding to disable MSIE and Chrome friendly error page -->
<!-- a padding to disable MSIE and Chrome friendly error page -->
<!-- a padding to disable MSIE and Chrome friendly error page -->
<!-- a padding to disable MSIE and Chrome friendly error page -->
<!-- a padding to disable MSIE and Chrome friendly error page -->
</body></html>
The HTTP 403 Forbidden
response status code indicates that the server understands the request but refuses to authorize it.
This status is similar to 401
, but for the 403 Forbidden status code re-authenticating makes no difference. The access is permanently forbidden and tied to the application logic, such as insufficient rights to a resource.
ChromeDriver initiated Chrome Browser gets detected as a bot and further navigation is blocked.
You can find a couple of relevant detailed discussions in: