get() missing 1 required positional argument: 'url' - python

i keep getting error of "get() missing 1 required positional argument: 'url'" when running following code
import selenium.webdriver as webdriver
def get_results(search_term):
url = "https://www.google.com"
browser = webdriver.Chrome
browser.get(url)
search_box = browser.find_element_by_class_name('gLFyf gsfi')
search_box.send_keys(search_term)
search_box.submit()
try:
links = browser.find_element_by_xpath('//ol[#class="web_regular_results"]//h3//a')
except:
links = browser.find_element_by_xpath('//h3//a')
results = []
for link in links :
href = link.get_attribute('href')
print(href)
results.append(href)
browser.close()
return results
get_results('dog')
the code is supposed to return search results of 'dog' from google, but gets stuck on
browser.get(url)
all help is appreciated

This issue is in the assignment of browser, browser = webdriver.Chrome. It needs to be browser = webdriver.Chrome().
In your code you are not assigning an instance of the chrome webdriver to browser, but the class itself. Thus when you call def get(self, url), your url parameter gets assigned to self and the argument url is not supplied, hence the positional argument error.

You should modify a bit of your code.
Change the import statement:
from selenium import webdriver
Also, you need to create chrome driver instance and provide the path of chromedriver jar file.
driver = webdriver.Chrome(executable_path="C:\\chromedriver.exe")

Related

Avoid opening an new browser for every instance in Selenium Python

I got a Python Selenium project that does what I want (yay!) but for every instance it opens a new browser window. Is there any way to prevent that?
I've went through the documentation of Selenium but they refer to driver.get(url). It's most likely because it's in the for...loop but I can't seem to get the URL to change with the queries and params if it's outside of the for...loop.
So, for example, I want to open these URLs:
https://www.google.com/search?q=site%3AParameter1+%22Query1%22
https://www.google.com/search?q=site%3AParameter2+%22Query1%22
https://www.google.com/search?q=site%3AParameter3+%22Query1%22
etc..
from selenium import webdriver
import time
from itertools import product
params = ['Parameter1', 'Parameter2', 'Parameter3', 'Parameter4']
queries = ['Query1', 'Query2', 'Query3', 'Query4',]
for (param, query) in product(params,queries):
url = f'https://www.google.com/search?q=site%3A{param}+%22{query}%22' # google as an example
driver = webdriver.Chrome('G:/Python Projects/venv/Lib/site-packages/chromedriver.exe')
driver.get(url)
#does stuff
You are declaring your path to Chrome in the loop. Declare it once and reuse:
from itertools import product
from selenium import webdriver
params = ['Parameter1', 'Parameter2', 'Parameter3', 'Parameter4']
queries = ['Query1', 'Query2', 'Query3', 'Query4',]
driver = webdriver.Chrome(executable_path='/snap/bin/chromium.chromedriver')
for (param, query) in product(params,queries):
url = f'https://www.google.com/search?q=site%3A{param}+%22{query}%22'
driver.get(url)
# driver.close()

selenium webdriver actionchains not working as expected

I am using action chain to drop down in selenium webdriver, here is my code, can anyone help me to figure out what's wrong. I'm not using the page object pattern this time, so there is no "self" argument here.
from selenium import webdriver
from behave import given, when, then
from selenium.webdriver.common.by import By
from selenium.webdriver import ActionChains
#given('Open RF page')
def open_website(context):
context.driver.get('https://www.raymourflanigan.com/')
#when('Select Living Room')
def select_living_room(context):
driver = webdriver.Chrome()
actions = ActionChains(driver)
menu = context.driver.find_element(By.XPATH, "//*[#id='Container']/div[1]/div[3]/div[1]/a")
sofa = context.driver.find_element(By.XPATH, "//*[#id='Container']/div[1]/div[3]/div[1]/div/div[1]/ul/li[2]/a")
actions.move_to_element(menu).move_to_element(sofa).click()
#then("Verify {product} are available")
def verify(context, product):
result = context.driver.find_element(By.CSS_SELECTOR, "h1.Category_Bnr_Title").text
assert 'Sofas & Couches' in result, f"Expected text is: {result}."
Also, I removed perform(), because for some reason the second function isn't working with perform() in it. Seems like it does not work properly without it either, so if anyone knows why and can help me, it'll be great! I am just learning) Thank you in advance!
There are a few problems, but nothing too big. Seems all changes need to be done in select_living_room.
select_living_room is taking a context object in it's arguments, but then the first thing it does is create a whole new webDriver. But then it accesses a completely different webDriver that is a member of context. I am guessing you are trying to do one of these:
accept context, which has a driver already included. If that is the case, get rid of this: driver = webdriver.Chrome()
create a new driver as an attribute of context. In that case, change to this: context.driver = webdriver.Chrome()
In either case, I don't see anywhere where get is being called on the driver to open the page. In select_living_room it is necesary to call open_website.
The ActionChain is not running. Need to add a perform() call on the end.
I change select_living_room to work like this (assumes that the webDriver is already set up inside of context):
#when('Select Living Room')
def select_living_room(context):
open_website(context)
menu = context.driver.find_element(By.XPATH, "//*[#id='Container']/div[1]/div[3]/div[1]/a")
sofa = context.driver.find_element(By.XPATH, "//*[#id='Container']/div[1]/div[3]/div[1]/div/div[1]/ul/li[2]/a")
actions = ActionChains(context.driver)
actions.move_to_element(menu).move_to_element(sofa).click().perform()
Then running like this works:
opts = webdriver.ChromeOptions()
ctx = Context(webdriver.Chrome('path/to/chromedriver', options=opts))
select_living_room(ctx)
verify(ctx, None)
Note that you don't mention what Context is. I stubbed it out:
class Context:
def __init__(self, ctx):
self.driver = ctx

Python Selenium. How to use driver.set_page_load_timeout() properly?

from selenium import webdriver
driver = webdriver.Chrome()
driver.set_page_load_timeout(7)
def urlOpen(url):
try:
driver.get(url)
print driver.current_url
except:
return
Then I have URL lists and call above methods.
if __name__ == "__main__":
urls = ['http://motahari.ir/', 'http://facebook.com', 'http://google.com']
# It doesn't print anything
# urls = ['http://facebook.com', 'http://google.com', 'http://motahari.ir/']
# This prints https://www.facebook.com/ https://www.google.co.kr/?gfe_rd=cr&dcr=0&ei=3bfdWdzWAYvR8geelrqQAw&gws_rd=ssl
for url in urls:
urlOpen(url)
The problem is when website 'http://motahari.ir/' throws Timeout Exception, websites 'http://facebook.com' and 'http://google.com' always throw Timeout Exception.
Browser keeps waiting for 'motahari.ir/' to load. But the loop just goes on (It doesn't open 'facebook.com' but wait for 'motahari.ir/') and keep throwing timeout exception
Initializing a webdriver instance takes long, so I pulled that out of the method and I think that caused the problem. Then, should I always reinitialize webdriver instance whenever there's a timeout exception? And How? (Since I initialized driver outside of the function, I can't reinitialize it in except)
You will just need to clear the browser's cookies before continuing. (Sorry, I missed seeing this in your previous code)
from selenium import webdriver
driver = webdriver.Chrome()
driver.set_page_load_timeout(7)
def urlOpen(url):
try:
driver.get(url)
print(driver.current_url)
except:
driver.delete_all_cookies()
print("Failed")
return
urls = ['http://motahari.ir/', 'https://facebook.com', 'https://google.com']
for url in urls:
urlOpen(url)
Output:
Failed
https://www.facebook.com/
https://www.google.com/?gfe_rd=cr&dcr=0&ei=o73dWfnsO-vs8wfc5pZI
P.S. It is not very wise to do try...except... without a clear Exception type, is this might mask different unexpected errors.

Getting error while running firefox browser in headless mode using python 3

I am just trying to run this using headless browser i don't understand why it keeps throwing me the error even if i have provided argument. Here i have read that it requires argument to pass in options.add_argument() :- https://seleniumhq.github.io/selenium/docs/api/py/webdriver_firefox/selenium.webdriver.firefox.options.html#module-selenium.webdriver.firefox.options
Error :- TypeError: add_argument() missing 1 required positional argument: 'argument'
from selenium import webdriver
from selenium.webdriver.firefox.options import Options
options = Options.add_argument('-headless')
browser = webdriver.Firefox(options)
browser.get('https://intoli.com/blog/email-spy/')
browser.implicitly_wait(50)
heading = browser.find_element_by_xpath('//*[#id="heading-breadcrumb"]/div/div/div/h1').text
print(heading)
browser.close()
You should create an object Options before calling the property on it.
For more informations about how #property works, see this answer.
# create a new object
options = Options()
# calling the property (setter)
options.add_argument('-headless')
Update :
Furthermore, it seems that there are other problems with your code sample.
If you want to provide only firefox_options, you should do it as a keyword argument, so you must provide it explicitly:
browser = webdriver.Firefox(firefox_options=options)

Changing Selenium driver for new URL

I used Selenium to navigate to a URL (i.e. URL_1) with a login/password and provided the login credentials. I'm logged in and the URL (i.e. URL_2) has changed as expected. I don't know how to navigate URL_2 because the driver still refers to URL_1.
Thanks in advance.
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
user_name = 'xyz'
password = 'xyz'
def login_process():
driver = webdriver.Firefox()
driver.get("URL_1")
#successfully navigated to URL_1
elem = driver.find_element_by_name("username")
elem.clear()
elem.send_keys(user_name)
elem = driver.find_element_by_name("password")
elem.clear()
elem.send_keys(password)
driver.find_element_by_id("submit").click()
#successfully entered URL_2
def query():
HOW DO I CHANGE THE DRIVER TO URL_2?
#elem = driver.find_element_by_class_name(ticker_box) #this doesn't work, references URL_1 driver
#elem.clear()
#elem.send_keys('xyz')
Instead of having independent functions, create a class with driver instance as an instance variable. Then, use self.driver.get() to navigate to a different URL:
class MyTest(object):
def __init__(self):
self.driver = webdriver.Firefox()
def login_process(self):
self.driver.get("URL_1")
#successfully navigated to URL_1
elem = self.driver.find_element_by_name("username")
elem.clear()
elem.send_keys(user_name)
elem = self.driver.find_element_by_name("password")
elem.clear()
elem.send_keys(password)
self.driver.find_element_by_id("submit").click()
#successfully entered URL_2
def query(self):
self.driver.get("URL2")
# do smth
test = MyTest()
test.login_process()
test.query()
After navigating to the new page if you want to do something on that new page
newURl = driver.window_handles[0]
driver.switch_to.window(newURl)
After doing this you can do something in the new url without getting "no such element exceptions"
First you can assign the url variable as a global:
global url;
url = "firstURL"
At the end of your first function you can change the value of the variable to the new URL:
url = driver.current_url
And then you can get the new url at the beginning of your second function:
driver.get(url)

Categories

Resources