2

Ok so, as the title says, pretty much i just cant make my python program work, it is a bot to log in to instagram and it wont actually do the logging in part, i've tried both using action chains, and without them, this is my code (python 3.6.1) :

from time import sleep
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains

browser = webdriver.Chrome()
browser.get('https://www.instragram.com')

login_elem = browser.find_element_by_xpath('//*[@id="react-root"]/section/main/article/div[2]/div[2]/p/a')
login_elem.click()

user = browser.find_element_by_name("username")

passw = browser.find_element_by_name('password')

ActionChains(browser)\
    .move_to_element(user).click()\
    .send_keys('test')\
    .move_to_element(passw).click()\
    .send_keys('test')\
    .perform()

login_button = browser.find_element_by_class_name(
'_0mzm- sqdOP  L3NKy       ')


login_button.click()

Pretty simple, right? and at since there are no syntax errors, i truly am confused over what is going wrong, since once I run my code, nothing happens after going to the login page. (Which means, it's not actually actuating on the username and password forms)

This is what the Module says :

Traceback (most recent call last): File "C:\Users\ferna\Desktop\trying browser script.py", line 17, in .send_keys('test')\ File "C:\Users\ferna\AppData\Local\Programs\Python\Python36-32\lib\site-packages\selenium\webdriver\common\action_chains.py", line 83, in perform action() File "C:\Users\ferna\AppData\Local\Programs\Python\Python36-32\lib\site-packages\selenium\webdriver\common\action_chains.py", line 277, in Command.MOVE_TO, {'element': to_element.id})) File "C:\Users\ferna\AppData\Local\Programs\Python\Python36-32\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 321, in execute self.error_handler.check_response(response) File "C:\Users\ferna\AppData\Local\Programs\Python\Python36-32\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 242, in check_response raise exception_class(message, screen, stacktrace) selenium.common.exceptions.StaleElementReferenceException: Message: stale element reference: element is not attached to the page document (Session info: chrome=71.0.3578.98) (Driver info: chromedriver=2.45.615291 (ec3682e3c9061c10f26ea9e5cdcf3c53f3f74387),platform=Windows NT 10.0.17134 x86_64)

Was Selenium not install properly? or is the error inside my code? I would really appreciate any help I can get. Btw: I'm finding the username and password elements by name and not xpath, since Instagram changes the xpath and selector every time the page is opened, making the elements quite hard to find in other ways, at least with my very limited experience.

This image shows what the browser looks like after the script is tested: enter image description here

Andersson
  • 47,234
  • 13
  • 52
  • 101
Alex
  • 21
  • 1
  • 3

4 Answers4

1

Use WebDriver Wait :

    WebDriverWait(browser, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, 
    "input[name='username']"))).send_keys("test")
    WebDriverWait(browser, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, 
    "input[name='password']"))).send_keys("test")

or

    user = browser.find_element_by_xpath("//input[@name='username']")
    user.send_keys('test')
    passw = browser.find_element_by_xpath("//input[@name='password']")
    passw.send_keys('test')'

Hope this will work!

Ranjitha
  • 19
  • 5
1

it works with my code, if it's helpful please accept it.


1 add a expected_conditions wait util the actual login page appear


second_page_flag = wait.until(EC.presence_of_element_located(
    (By.CLASS_NAME, "KPnG0")))  # util login page appear


2 change the xpath selector syntax here

login_button_ = browser.find_element_by_xpath(
    "//form[@class='HmktE']/div[3]/button")


login_button_.click()


the all codes here:

from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait

browser = webdriver.Chrome()
browser.get('https://www.instragram.com')

wait = WebDriverWait(browser, 10)

login_elem = browser.find_element_by_xpath(
   '//*[@id="react-root"]/section/main/article/div[2]/div[2]/p/a')

second_page_flag = wait.until(EC.presence_of_element_located(
    (By.CLASS_NAME, "KPnG0")))  # util login page appear


user = browser.find_element_by_name("username")

passw = browser.find_element_by_name('password')

ActionChains(browser)\
    .move_to_element(user).click()\
    .send_keys('test')\
    .move_to_element(passw).click()\
    .send_keys('test')\
    .perform()

login_button_ = browser.find_element_by_xpath(
    "//form[@class='HmktE']/div[3]/button")

login_button_.click()
jia Jimmy
  • 1,383
  • 7
  • 30
  • 1
    Thank you very much! i simply used the sleep(2) command. Since i had already imported the sleep module and had forgotten to use it. – Alex Jan 10 '19 at 11:44
0

Try this code.It worked for me.No action class required.Hope this will help you.Any issues please reply back.You need to download latest chrome driver ChromeDriver 2.45 from http://chromedriver.chromium.org/downloads

from selenium import webdriver
import time
driver=webdriver.Chrome("Path of the chromdriver location" + "chromedriver.exe" )
driver.get("https://www.instagram.com/accounts/login/?source=auth_switcher")
user=driver.find_element_by_name("username")
user.send_keys("kajal")
passwd=driver.find_element_by_name("password")
passwd.send_keys("1234")
time.sleep(1)
button=driver.find_element_by_xpath(".//*[@id='react-root']/section/main/div/article/div/div[1]/div/form/div[3]/button")
button.click()
KunduK
  • 26,790
  • 2
  • 10
  • 32
  • Thank you!, the problem indeed was that i wasn't giving the page enough time to load. I fixed it with a simple sleep(2) command. – Alex Jan 10 '19 at 11:45
0

I had the same issue. The problem is that python tries to find the element immediately but the webdriver didn't load the element yet. To fix the problem make the program wait for the elements to load and only then call them. You can do this by importing time and adding: time.sleep(4). So that would be:

import time
from selenium import webdriver
browser = webdriver.Chrome("/usr/lib/chromium-browser/chromedriver")
browser.get("https://www.instagram.com/accounts/login/")
time.sleep(4) #so you let the webpage load
browser.find_element_by_name("username").send_keys("blablabla")