'Can't login to Target.com with Selenium
I'm working on a online purchase bot for target.com and I've run into a blocker. Upon providing correct username and password combination on the login page and clicking "login", I get the following error message on the target login page: "Sorry, something went wrong. Please try again.". This only occurs when running through browser automation. Just wondering if there's a workaround for this issue. Here is my code thus far:
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
import time
PATH="C:\Program Files (x86)\chromedriver.exe"
driver = webdriver.Chrome(PATH)
btn_sign_in_nav = "//span[text()='Sign in']"
btn_sign_in_drop_down = "//div[@id='accountMenu']//div[text()='Sign in']"
input_username_login = "//input[@id='username']"
input_password_login = "//input[@id='password']"
btn_submit_login = "//button[@id='login']"
def xpath_explicit_wait(xpath_val, time_sec):
if type(time_sec) != int or type(xpath_val) != str:
print("NUMERICAL VALUES ONLY!")
driver.quit()
try:
element = WebDriverWait(driver, time_sec).until(
EC.presence_of_element_located((By.XPATH, xpath_val))
)
except NoSuchElementException:
driver.quit()
def login_user(url, username, password):
driver.get(url)
driver.implicitly_wait(3)
driver.find_element_by_xpath(btn_sign_in_nav).click()
xpath_explicit_wait(btn_sign_in_drop_down, 5)
driver.find_element_by_xpath(btn_sign_in_drop_down).click()
driver.implicitly_wait(3)
driver.find_element_by_xpath(input_username_login).send_keys(username)
driver.find_element_by_xpath(input_password_login).send_keys(password)
xpath_explicit_wait(btn_submit_login, 5)
driver.find_element_by_xpath(btn_submit_login).click()
Solution 1:[1]
There are detection mechanisms on sites like target that detect when you're using selenium and prevent the site from working.
More details can be found in the answer here: Can a website detect when you are using Selenium with chromedriver?
PhoenixBot implements a mechanism that changes the contents of the driver so that it's undetectable. Use this same mechanism and your problems will vanish, as mine did! :-D
Solution 2:[2]
There is a bot Phoenixbot, I can't speak for the functionality 100% but the auto login portion definitely works and is python. https://github.com/Strip3s/PhoenixBot/blob/master/sites/target.py
I've been attempting to figure out how exactly it's accomplishing that but no success replicating successfully in my own code. Maybe take a look.... If you figure it out I'd love to know.
Solution 3:[3]
IF you have the ability to use Safari webdriver, then see the below code.
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as ec
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.keys import Keys
driver = webdriver.Safari(executable_path='/usr/bin/safaridriver')
driver.get('https://www.target.com/')
action = ActionChains(driver)
driver.find_element(By.XPATH, '//*[@id="account"]').click()
WebDriverWait(driver, 30).until(ec.presence_of_element_located((By.XPATH, '//*[@id="accountNav-signIn"]')))
action.send_keys(Keys.ENTER)
action.perform()
WebDriverWait(driver, 10).until(ec.presence_of_element_located((By.XPATH, '//h2[@class="sc-hMqMXs sc-esjQYD eXTUDl"]')))
driver.find_element(By.ID, 'username').click()
driver.find_element(By.ID, 'username').send_keys('foo')
time.sleep(5)
driver.find_element(By.ID, 'password').click()
driver.find_element(By.ID, 'password').send_keys('bar')
time.sleep(5)
driver.find_element(By.XPATH, "//button[@id=\'login\']").send_keys(Keys.ENTER)
time.sleep(10)
driver.quit()
As @Decian Shanaghy mentioned, Target seems to be bot protected, but Safari webdriver still works.
The time.waits are not needed, you can remove them if you would like.
Solution 4:[4]
For anyone still seeking a solution to this, see this answer at Can a website detect when you are using Selenium with chromedriver?. I did a search through the chromedriver
binary executable (MacOS in my case) and changed instances of $cdc_
to $abc_
.
I originally suspected Target employs a JavaScript solution to hunting selenium users. I confirmed this suspicion by using selenium to open a browser at https://www.target.com
without any automation. I attempted to manually login and obtained a 401
response with the well known "Sorry, something went wrong. Please try again." That didn't rule out a UI-based bot hunting solution but it pointed to a JavaScript hunter.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Declan Shanaghy |
Solution 2 | John Barnes |
Solution 3 | Ryan Burch |
Solution 4 | Dr.Ransom |