Ray M
Ray M

Reputation: 90

Selenium Python script not executing some lines

I am trying to make a script using python that checks attendance checkboxes according to the names recorded in an excel sheet, so I'm using both selenium and pandas. I wrote a similar script in the past using geckodriver (because I use Firefox mainly), this time however I'm required to use chromedriver. The thing is using Chrome, the script goes to great lengths so that it will never work as intended, here are some of the errors I get just by executing the script.

[file]
[file]:8: DeprecationWarning: executable_path has been deprecated, please pass in a Service object
  driver = webdriver.Chrome(executable_path=driver_path,options=options)

DevTools listening on ws://127.0.0.1:53053/devtools/browser/28e3a28f-d7df-4a34-8f22-ed4aeffebca6
id: [10224:9828:0522/111925.401:ERROR:device_event_log_impl.cc(214)] [11:19:25.401] Bluetooth: bluetooth_adapter_winrt.cc:1075 
Getting Default Adapter failed.
[user input]
password: [user input]
[file]:12: DeprecationWarning: find_element_by_* commands are deprecated. Please use find_element() instead
  driver.find_element_by_id('loginid').send_keys(loginid)
[file]:13: DeprecationWarning: find_element_by_* commands are deprecated. Please use find_element() instead
  driver.find_element_by_id('loginpass').send_keys(loginpass)
Enter the name of the sheet: [user input]
Which week is it? [user input]
[file]:22: DeprecationWarning: find_element_by_class_name is deprecated. Please use find_element(by=By.CLASS_NAME, value=name) instead
  if df.iloc[i]['name']==driver.find_element_by_class_name('name').get_attribute('value'):
PS [path]> [10224:12100:0522/112023.321:ERROR:util.cc(126)] Can't create base directory: C:\Program Files\Google\GoogleUpdater

When I copied the syntax from the warnings they don't get recognized and throw more errors, also logging in with that script doesn't go smoothly, I have to login twice because every time the first login throws a 400 and 404 errors from the database side at the same time.

Pandas works fine, when I ask it to print the info it reads things properly, the problem is in Selenium mainly. Here's the script code:

import pandas as pd
from selenium import webdriver
from selenium.webdriver.chrome.options import Options

driver_path = './chromedriver'
url = [URL]
options = Options()
driver = webdriver.Chrome(executable_path=driver_path,options=options)
loginid=input("id: ")
loginpass=input("password: ")
driver.get(url)
driver.find_element_by_id('loginid').send_keys(loginid)
driver.find_element_by_id('loginpass').send_keys(loginpass)
sheet=input("Enter the name of the sheet: ")
if sheet.endswith('.xls'):
    df = pd.read_excel(sheet)
else:
    df = pd.read_csv(sheet)
w=input("Which week is it? ")
week='w'+w
for i in range(len(df)):
    if df.iloc[i]['name']==driver.find_element_by_class_name('name').get_attribute('value'):
        driver.find_element_by_class_name(week).click()
        print(driver.find_element_by_class_name('name').get_attribute('value'))
        break

Update: the code is modernized but now there's the same for loop issue persists, it used to do nothing and just closes but when I ran the script on debug mode, it keeps saying the variable result i is a float even though when I print it says the type is string which is what it should be. I tried str() but this makes it come out as NaN. That's the loop I rewrote which gives the same result.

for i in range(len(df)):
    name=df.iloc[i]['name']
    print(type(name))
    # find the p containing the name
    p=driver.find_element_by_xpath("//p[contains(@class, 'name') and contains(text(), '"+str(name)+"')]")
    print(p)

Upvotes: 0

Views: 895

Answers (1)

Akzy
Akzy

Reputation: 1928

First issue: DeprecationWarning: executable_path has been deprecated, please pass in a Service object

With selenium4 as the key executable_path is deprecated you have to use an instance of the Service() class along with ChromeDriverManager().install() command as mentioned below

Solution

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager

options = Options()
options.add_argument("start-maximized")
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()), options=options)

driver.get("https://www.google.com")

Other Issues Solutions

find_element_by_* commands are deprecated in the latest Selenium Python libraries.

Instead you have to use find_element(). As an example:

You have to include the following imports

from selenium.webdriver.common.by import By

Using class_name:

driver.find_element_by_class_name("className")

Needs be replaced with:

button = driver.find_element(By.CLASS_NAME, "className")

In similar lines you also have to change the following:

Using id:

driver.find_element_by_id("element_id")

Needs be replaced with:

driver.find_element(By.ID, "element_id")

Using name:

driver.find_element_by_name("element_name")

Needs be replaced with:

driver.find_element(By.NAME, "element_name")

Using link_text:

find_element_by_link_text("element_link_text")

Needs be replaced with:

driver.find_element(By.LINK_TEXT, "element_link_text")

Using partial_link_text:

driver.find_element_by_partial_link_text("element_partial_link_text")

Needs be replaced with:

driver.find_element(By.PARTIAL_LINK_TEXT, "element_partial_link_text")

Using tag_name:

driver.find_element_by_tag_name("element_tag_name")

Needs be replaced with:

driver.find_element(By.TAG_NAME, "element_tag_name")

Using css_selector:

driver.find_element_by_css_selector("element_css_selector")

Needs be replaced with:

driver.find_element(By.CSS_SELECTOR, "element_css_selector")

Using xpath:

   driver.find_element_by_xpath("element_xpath")

Needs be replaced with:

driver.find_element(By.XPATH, "element_xpath")

Note: If you are searching and replacing to implement the above changes, you will need to do the same thing for find_elements_*, i.e. the plural forms of find_element_*.

You may also find this upgrade guide useful as it covers some other unrelated changes you may need to make when upgrading:

Upvotes: 1

Related Questions