Why exactly do I get an IndexError? - python

I am trying to use this python code from here. I am using firefox geckodriver instead. I get an index error from line 43 which is log_in[0].click(). Here is the code for convenience:
# importing necessary classes
# from different modules
from lib2to3.pgen2 import driver
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.chrome.options import Options
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.common.keys import Keys
import time
browser = webdriver.Firefox()
prefs = {"profile.default_content_setting_values.notifications": 2}
# open facebook.com using get() method
browser.get('https://www.facebook.com/')
# user_name or e-mail id
username = "argleblargle#gmail.com"
# getting password from text file
with open('test.txt', 'r') as myfile:
password = myfile.read().replace('\n', '')
print("Let's Begin")
element = browser.find_elements_by_xpath('//*[#id ="email"]')
element[0].send_keys(username)
print("Username Entered")
element = browser.find_element_by_xpath('//*[#id ="pass"]')
element.send_keys(password)
print("Password Entered")
# logging in
log_in = browser.find_elements_by_id('loginbutton')
log_in[0].click()
print("Login Successful")
browser.get('https://www.facebook.com/events/birthdays/')
feed = 'Hap Borth! Hope you have an amazing day!'
element = browser.find_elements_by_xpath("//*[#class ='enter_submit\
uiTextareaNoResize uiTextareaAutogrow uiStreamInlineTextarea\
inlineReplyTextArea mentionsTextarea textInput']")
cnt = 0
for el in element:
cnt += 1
element_id = str(el.get_attribute('id'))
XPATH = '//*[#id ="' + element_id + '"]'
post_field = browser.find_element_by_xpath(XPATH)
post_field.send_keys(feed)
post_field.send_keys(Keys.RETURN)
print("Birthday Wish posted for friend" + str(cnt))
# Close the browser
browser.close()
As you can see from the code, it prints out when a step is completed. It passed username entered, passed password entered, but did not pass login successful. I get an IndexError: line 43, in <module> log_in[0].click()
Is that because the login button is somewhere different from when the code was first written? Is it 2FA shenanigans? I am doing this for fun, thanks for reading.
EDIT: the original error was because of the s in ind_elements_by_id. There is one element. Oops.
The error is now selenium.common.exceptions.NoSuchElementException: Message: Unable to locate element: [id="loginbutton"]

log_in variable is empty, because many websites including facebook first load the website as such, and only than load the layout and all the elements with javascript.
Your code tries to interact with facebook before it is fully loaded and therefor cannot find login button.
You can do something like this to resolve your problem or just write a while loop that checks if the button is found.

Related

Same strings in python aren't matching in web scraping

Hi I am trying to scrape gujarat rera using selenium python.
main.py:
import csv
import os
import time
import chromedriver_autoinstaller
from selenium import webdriver
from selenium.webdriver import Keys
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.support.select import Select
WORK_DONE = False
chromedriver_autoinstaller.install()
driver = webdriver.Chrome()
driver.maximize_window()
driver.get("https://gujrerar1.gujarat.gov.in/home")
time.sleep(3)
close = driver.find_elements(By.CSS_SELECTOR,".close") # click close on popup.
for i in close:
try:
i.click()
time.sleep(0.5)
except:
pass
close = driver.find_elements(By.CSS_SELECTOR,".close") # click close on popup.
for i in close:
try:
i.click()
time.sleep(0.5)
except:
pass
search_bar = driver.find_element(By.ID,"password")
data=["031218"]
for reg_no in data:
last_thing_of_reg_no = reg_no.split("/")[5]
search_bar.send_keys(Keys.CONTROL + "A")
search_bar.send_keys(last_thing_of_reg_no)
driver.find_element(By.NAME,"btn1").click() # click on search button.
time.sleep(1.5)
driver.find_element(By.TAG_NAME,"body").send_keys(Keys.END) # scroll the page to end
time.sleep(1.5)
total_projects = driver.find_elements(By.CSS_SELECTOR,".search_result_list")
for projects in total_projects:
all_paragraphs = projects.find_elements(By.TAG_NAME,"p")
for i in all_paragraphs:
text = i.text.replace("Reg No. : ","")
print(text)
print(reg_no)
if reg_no == text:
print("yes")
print("done")
time.sleep(100)
print("done")
time.sleep(50)
First, it opens the website, closes the pop-ups, finds a search bar, and sends reg_no. Then it gets all the paragraph tags in the website, iterates through each of them, and the error is there. Both statements are exactly same but it is not going inside if statement, I don't know why it is so.
I want to print yes in this code and iterate inside it, but I don't know why it is not printing yes, even though both the strings are exactly the same.
I don't know what else to write but feel free to ask more questions,
Many thanks for considering my request.

How to click on the first result on a dynamic page using python selenium?

I am trying to click on the first result on this page, but all the options I tried didn't work.
Firstly I just login into the website with email: kocianlukyluk#gmail.com and password: Redfinpython06. Here is the code for it:
driver = webdriver.Chrome("C:\\Users\\kocia\\OneDrive\\Plocha\\Python\\nastaveni\\chromedriver.exe")
driver.get('https://www.redfin.com/myredfin/favorites')
email = 'kocianlukyluk#gmail.com'
password = 'Redfinpython06'
time.sleep(3)
driver.find_element_by_xpath(
'//*[#id="content"]/div[6]/div/div[2]/div/div/form/span[1]/span/div/input').send_keys(email)
time.sleep(3)
driver.find_element_by_xpath(
'//*[#id="content"]/div[6]/div/div[2]/div/div/form/span[2]/span/div/input').send_keys(password)
time.sleep(3)
sing_up = driver.find_element_by_css_selector('button[type=submit]')
sing_up.click()
But the problem is after login i can't click on the first result on the page.
Here is what i tried:
result = driver.find_elements_by_xpath("//*[#id="content"]/div[10]/div/div[5]/div/div[2]/div/div")[0]
result.find_element_by_xpath("//*[#id="content"]/div[10]/div/div[5]/div/div[2]/div/div/div[1]").click()
or
result = driver.find_elements_by_xpath("//*[#id="content"]/div[10]/div/div[5]/div/div[2]/div/div")[0]
result.click()
or
result = driver.find_element_by_xpath("//*[#id="content"]/div[10]/div/div[5]/div/div[2]/div/div/div[1]")
result.click()
Thank you so much for help.
I hope that is a dummy email and password that you are just using for testing purposes :)
Below clicks on the first house picture in the list. I also cleaned up your email and password xpath designations. You can see how much easier it is to grab them by name
Also, you may want to put proper wait methods around these find elements. Using sleep generally is not recommended
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from time import sleep
driver = webdriver.Chrome()
driver.get('https://www.redfin.com/myredfin/favorites')
email = 'kocianlukyluk#gmail.com'
password = 'Redfinpython06'
sleep(3)
driver.find_element_by_name(
'emailInput').send_keys(email)
sleep(3)
driver.find_element_by_name(
'passwordInput').send_keys(password)
sleep(3)
sing_up = driver.find_element_by_css_selector('button[type=submit]')
sing_up.click()
sleep(3)
first_house = driver.find_element_by_xpath("//div[#class='FavoritesHome'][1]//img")
first_house.click()

how can i print instagram reply message in python using selenium

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.chrome.options import Options
import time
import schedule
browser = webdriver.Chrome('/Users/badernm/Desktop/chromedriver')
browser.get('https://www.instagram.com/accounts/password/reset/')
usrname_bar = browser.find_element_by_name('cppEmailOrUsername')
username = '17pii_'
usrname_bar.send_keys(username + Keys.ENTER
i need to print the result that is ("thanks! check your email for reset link ")
or ("no account with this email")
I re-created your program and added 4 extra lines that grab that text from the pop-up you want. Then it prints the text to your terminal. I also took out the 'schedule' library because I saw that you weren't using it in your code, but you can add it back in if you're just showing us a snippet of your program.
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.chrome.options import Options
import time
browser = webdriver.Chrome('/Users/badernm/Desktop/chromedriver')
browser.get('https://www.instagram.com/accounts/password/reset/')
usrname_bar = browser.find_element_by_name('cppEmailOrUsername')
username = '17pii_'
usrname_bar.send_keys(username + Keys.ENTER)
time.sleep(1) # Wait for pop-up message
result = browser.find_element_by_xpath("html/body/div/div/div/div/p") # Path to pop-up
print(result.text) # Get pop-up text
browser.quit() # Quit browser process
You can get the element by class name. It will look something like this:
reply = browser.find_element_by_class_name("CgFia")
print(reply.text)

Using python and selenium how can i get the value of placeholder where the value is not utf-8?

I was trying to get the email address and click on the refresh button from the following screenshot. But I am getting errors.
My code for this is like the following:
from selenium import webdriver
url = 'http://od.obagg.com/ '
driver = webdriver.Chrome(executable_path='chromedriver')
driver.get(url)
s = driver.find_element_by_id('//*[#id="shortid"]').get_attribute('placeholder')
print(s)
Based on the inspect, i was trying to do and tried many ways to get that email field value and click on refresh button. But still no luck.
Do anybody know any tricks to share?
It may be due to the fact the element is disabled, also, find_element_by_id('//*[#id="shortid"]') is incorrect. It can be either:
find_element_by_xpath('//*[#id="shortid"]')
find_element_by_id("shortid") ?
The following works for me:
from selenium import webdriver
from selenium.webdriver.support import expected_conditions as ec
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
driver = webdriver.Chrome(executable_path='chromedriver')
driver.maximize_window()
driver.get('http://od.obagg.com/')
wait = WebDriverWait(driver, 10)
el = wait.until(ec.visibility_of_element_located((By.ID, "shortid")))
placeholder = el.get_attribute("placeholder")
email = el.get_attribute('value')
print(placeholder, email)
# 请等待分配临时邮箱 -_ylp06tc#xxx.xxx
If you need 10 different emails, you can use:
from time import sleep
for x in range(10):
driver.find_element_by_id("refreshShortid").click()
sleep(0.15) # you may have to increase this value to give enough time to generate the new email
new_email = driver.find_element_by_id("shortid").get_attribute('value')
print(new_email)

StaleElementReferenceException Using Selenium in Python

Yes i know that this type of question has been answered many times before, but none of them helped me. Actually i didn't know much about it so need your help!
My problem:
I am scraping through a website and it needs a CAPTCHA to search for every input. So i use FireFox as my browser as it asks for the captcha one time and doesn't change it. My code asks the user for CAPTCHA one time and then click on search button and tries to scrape the data, but when it clicks on the search button again (as it is in a loop) then it raises this error:
selenium.common.exceptions.StaleElementReferenceException:
Message: The element reference of <input id="txt_ALPHA_NUMERIC" class="ui-inputfield ui-inputtext ui-widget ui-state-default ui-corner-all" name="txt_ALPHA_NUMERIC" type="text"> is stale;
either the element is no longer attached to the DOM, it is not in the current frame context, or the document has been refreshed
My old code:
from selenium import webdriver # Import module
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys # For keyboard keys
import time
import pandas as pd
URL = 'https://vahan.nic.in/nrservices/faces/user/searchstatus.xhtml' # Define URL
browser = webdriver.Firefox(executable_path=r'C:\Users\intel\Downloads\Setups\geckodriver.exe')
browser.get(URL)
vehicle_no = browser.find_element_by_xpath("""//*[#id="regn_no1_exact"]""")
vehicle_no.send_keys('RJ14CX3238')
captcha_input = input("enter your captcha ")
captcha = browser.find_element_by_xpath("""//*[#id="txt_ALPHA_NUMERIC"]""")
captcha.send_keys(captcha_input)
button_click = browser.find_element_by_xpath("/html/body/form/div[1]/div[3]/div/div[2]/div/div/div[2]/div[5]/div/button/span").click()
i = 111
attempt = 1
max_attempts = 2
while True:
i = i + 1
time.sleep(4)
reg_no = browser.find_element_by_xpath("/html/body/form/div[1]/div[3]/div/div[2]/div/div/div[2]/div[6]/div/div/div/table/tbody/tr[2]/td[2]/span").text
date = browser.find_element_by_xpath("/html/body/form/div[1]/div[3]/div/div[2]/div/div/div[2]/div[6]/div/div/div/table/tbody/tr[2]/td[4]").text
vehicle_no = browser.find_element_by_xpath("""//*[#id="regn_no1_exact"]""")
vehicle_no.send_keys('RJ14CX3' + str(i))
captcha.send_keys(captcha_input)
button_click = browser.find_element_by_xpath("/html/body/form/div[1]/div[3]/div/div[2]/div/div/div[2]/div[5]/div/button/span").click()
browser.execute_script("return arguments[0].scrollIntoView(true);", button_click)
Updated new code now:
from selenium import webdriver # Import module
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys # For keyboard keys
import time
import pandas as pd
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
URL = 'https://vahan.nic.in/nrservices/faces/user/searchstatus.xhtml' # Define URL
browser = webdriver.Firefox(executable_path=r'C:\Users\intel\Downloads\Setups\geckodriver.exe')
browser.get(URL)
vehicle_no = browser.find_element_by_xpath("""//*[#id="regn_no1_exact"]""")
vehicle_no.send_keys('RJ14CX3238')
captcha_input = input("enter your captcha ")
captcha = browser.find_element_by_xpath("""//*[#id="txt_ALPHA_NUMERIC"]""")
captcha.send_keys(captcha_input)
button_click = browser.find_element_by_xpath("/html/body/form/div[1]/div[3]/div/div[2]/div/div/div[2]/div[5]/div/button/span").click()
i = 111
while True:
button_click = browser.find_element_by_xpath("/html/body/form/div[1]/div[3]/div/div[2]/div/div/div[2]/div[5]/div/button/span")
WebDriverWait(browser, 10).until_not(EC.visibility_of_element_located((By.ID, "overley")))
browser.execute_script("return arguments[0].scrollIntoView(true);", button_click)
i = i + 1
#reg_no = browser.find_element_by_xpath("/html/body/form/div[1]/div[3]/div/div[2]/div/div/div[2]/div[6]/div/div/div/table/tbody/tr[2]/td[2]/span").text
#date = browser.find_element_by_xpath("/html/body/form/div[1]/div[3]/div/div[2]/div/div/div[2]/div[6]/div/div/div/table/tbody/tr[2]/td[4]").text
time.sleep(5)
vehicle_no.send_keys('RJ14CX3' + str(i))
WebDriverWait(browser, 10).until_not(EC.visibility_of_element_located((By.ID, "overley")))
captcha.send_keys(captcha_input)
Also fix any other problems if is in my code. Any help would be appreciated!!
Thanks in advance.
Simply re-find the button element in the loop, each time, rather than before the loop starts. Any time the DOM mutates, previous references are marked as stale, and will require a new instance. Interacting with Captcha's mutate the DOM, and mark the page as dirty (having changed/modified), which Selenium uses to flag "staleness".

Categories