Selenium Python: Unable to select combo value - python

I am accessing this page and I have to pick one of Combo value that shows existing resume. I am getting error:
selenium.common.exceptions.ElementNotVisibleException: Message:
Element is not currently visible and so may not be interacted with
Code I am trying is:
from selenium import webdriver
from selenium.webdriver.support.select import Select
from time import sleep
from bs4 import BeautifulSoup
driver = webdriver.Firefox()
driver.get('https://www.glassdoor.com/job-listing/developer-one-north-interactive-JV_IC1128808_KO0,9_KE10,31.htm?jl=1584069572')
select_box = driver.find_element_by_id('ExistingResume')
select_box.click();
select_box = Select(select_box)
sleep(5)
select_box.select_by_value(RESUME_TEXT_VALUE)
Updated The required element is right there
Update #2: Checked that element is not visible in static html. Guess via JS being loaded.
Update #3: OK I made following changes which prints tag name that is select:
select_box = driver.find_element_by_id('ExistingResume')
print(select_box.tag_name)
Now mission is to select the value from that combo

You can use Keys.ARROW_DOWN to get the option and Keys.RETURN to select. See below:
>>> from selenium.webdriver.common.keys import Keys
>>> driver.find_element_by_id("ExistingResumeSelectBoxIt").click()
>>> d = driver.find_element_by_id("ExistingResumeSelectBoxIt")
>>> d.send_keys(Keys.ARROW_DOWN)
>>> d.send_keys(Keys.RETURN)
>>> driver.find_element_by_id("ExistingResumeSelectBoxIt").text
u'mesut gunes resume eng.pdf'
You must be logged in and have a resume too.

The error message is clean enough. The problems is that there is no element with id "ExistingResume" on the website.
If you open the console in your browser and type $("#ExistingResume"); jQuery cannot find that element on the website neither.
Make sure you didn't make a typo in the id or you have all the necessary permissions to access that element. (Maybe it's visible only for logged in users.)

First of all, you have to be logged in and have at least one existing uploaded resume.
You cannot directly control the select element with the resumes - it is invisible. Control the wrapping combo element that is visible.
Complete working code (including logging in):
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
driver = webdriver.Firefox()
driver.get('https://www.glassdoor.com/job-listing/developer-one-north-interactive-JV_IC1128808_KO0,9_KE10,31.htm?jl=1584069572')
# log in
driver.find_element_by_css_selector("div.actions span.signin").click()
driver.find_element_by_css_selector("form.signInForm input.signin-email").send_keys("login")
driver.find_element_by_css_selector("form.signInForm input.signin-password").send_keys("password")
driver.find_element_by_css_selector("form.signInForm button.loginDlgSignInBtn").click()
# wait for the combo to appear
resume_name = "myResume.pdf"
# open up combo
combo = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "ExistingResumeSelectBoxIt")))
combo.click()
# select resume
resume_item = combo.find_element_by_xpath("//li[#data-val = '%s']" % resume_name)
resume_item.click()

Related

How can I get this SPECIFIC element in selenium in python

UPDATE:
So thanks to the voted answer it displayed some information not the right information, it shows 0kb out of 100 and when in the inspect element console if doing console.log($0) then the item would be displayed in console how do I fetch this
I want to create a python 3.x programme that gets my stats off of netlify and easybase using selenium. The issue I have come across already is that the element does not have a specific class name and the text widget isn't just a tag nor a tag. Here is a screenshot of the html of netlify the screenshot, and this is the code that I used
element = driver.find_element_by_name("github")
element.click()
login = driver.find_element_by_name("login")
login.send_keys(email)
password = driver.find_element_by_name("password")
password.send_keys(passwordstr)
loginbtn = driver.find_element_by_name("commit")
loginbtn.click()
getbandwidth = driver.find_element_by_xpath('//*[#id="main"]/div/div[1]/div/section/div/div/div/dl/div/dd')
print(getbandwidth.text)
getbandwidth = driver.find_element_by_xpath("//dd[#class='tw-text-xl tw-mt-4px tw-leading-none']")
You can use this to grab the first xpath with that class. Below does the same but if you want to index other elements with similar classes.
(//dd[#class='tw-text-xl tw-mt-4px tw-leading-none'])[1]
Normally we use webdriver waits to allow for the element to become visible.
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
getbandwidth = WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.XPATH,"//dd[#class='tw-text-xl tw-mt-4px tw-leading-none']")))

Why does sometimes selenium locate objects and sometimes no?

Good morning,
I am trying to automatize simple online procedure: go to this site http://nvidia-research-mingyuliu.com/gaugan/
Check the little box, update a picture, render it and download it clicking the download button.
I have written my code, which is extremely intuitive and very short, but for some reasons sometimes it works and sometimes it doesn't.
Sure enough, sometimes python returns the following error:
no such element: Unable to locate element: {"method":"css selector","selector":"[id="myCheck"]"}
My code is:
import selenium
import time
from selenium import webdriver
# Using Chrome to access web
driver = webdriver.Chrome(executable_path='/Users/Marco/Downloads/chromedriver')
# Open the website
driver.get('http://nvidia-research-mingyuliu.com/gaugan/')
# Select the checkbox
time.sleep(5)
check_box = driver.find_element_by_id('myCheck')
check_box.click()
# Upload File button
element = driver.find_element_by_id("myCheck")
driver.execute_script("arguments[0].click();", element)
choose_file = driver.find_element_by_id('segmapfile')
# Send the file location to the button
choose_file.send_keys('/Users/Marco/Desktop/Foto upload/Schermata 2020-10-31 alle 00.07.03.png')
#Locate submit button and click
submit_assignment = driver.find_element_by_id('btnSegmapLoad')
submit_assignment.click()
#render
render_button = driver.find_element_by_id('render')
render_button.click()
#download
save_box = driver.find_element_by_id('save_render')
time.sleep(5)
save_box.click()
Why is this happening? How should i solve it?
Thank you
Use explicit waits which wait for something to happen, as opposed to 'time.sleep(5)' which just waits for 5 seconds:
import selenium
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
# Using Chrome to access web
driver = webdriver.Chrome(executable_path='/Users/Marco/Downloads/chromedriver')
# Open the website
driver.get('http://nvidia-research-mingyuliu.com/gaugan/')
# Wait for checkbox to be located
check_box_wait = EC.presence_of_element_located((By.ID, 'myCheck'))
WebDriverWait(driver, 10).until(check_box_wait)
# Select the checkbox
check_box = driver.find_element_by_id('myCheck')
check_box.click()

Select from dropdown Selenium

New to Selenium. I'm trying to get it so that I can enter a name into a search box and then click on the correct name.
I have managed to write some code to go to a website and then enter what I want and press the search button. The problem is that it then shows a list of items so I'd have to click again.
from selenium import webdriver
from selenium.webdriver.support.ui import Select
from webdriver_manager.chrome import ChromeDriverManager
from time import sleep
index = 'AMZN'
driver = webdriver.Chrome(ChromeDriverManager().install())
driver.get('https://www.marketscreener.com')
sleep(6)
text_box = driver.find_element_by_css_selector('#autocomplete')
text_box.send_keys(index)
#select.select_by_index(1)
driver.find_element_by_xpath("//*[#id='recherche_menu']/table/tbody/tr[1]/td/button/img").click()
When I enter the name and don't click It presents a dropdown list so I am trying to select the first item from the dropdown as that is usually what I will want.
I attempted this by using the commented out select.select_by_index code line. But it doesn't quite work.
I just tried also using text_box.send_keys(Keys.DOWN, Keys.RETURN) to move down into the dropdown field, but this doesn't work and just returns the same as what I currently get from clicking.
To be clear what I mean is that currently the code will return this:
But I want it to go straight to the Amazon page so it will return this:
Any help appreciated.
Thanks
This page use many JavaScript to listen the action of the mouse and the key.If you didn't focus on the searchbox,the dropdown will be disappeared.(and you couldn't find it in the source code).
Try to use ActionChains,this works fine on my PC:
from selenium import webdriver
from selenium.webdriver.support.ui import Select
from selenium.webdriver.common.action_chains import ActionChains
from time import sleep
index = 'AMZN'
driver = webdriver.Chrome()
driver.get('https://www.marketscreener.com')
action = ActionChains(driver)
sleep(4)
text_box = driver.find_element_by_css_selector('#autocomplete')
action.move_to_element(text_box)
action.click(text_box)
action.send_keys(index)
action.perform()
sleep(1)
driver.find_element_by_xpath('//*[#id="AC_tRes"]/li[1]').click()
If the result couldn't show you,maybe you need to increase the time of sleep().

Selenium - dropdown choise shows new fields. how can I update driver, so it could see them?

I Got this code:
from selenium import webdriver
from selenium.webdriver.support.ui import Select
myurl = "https://foobar.pl"
driver = webdriver.Chrome()
driver.get(myurl)
select = Select(driver.find_element_by_xpath('/html/body/div/select'))
select.select_by_visible_text('foobar')
time.sleep(5)
after selecting "foobar" an input field appears.
but after I try:
driver.find_element_by_xpath('/html/body/div/div[2]/input').click()
I get
ElementNotVisibleException: element not visible
How can I update driver, so it would see input, without refreshing page (I would loose my selection)?
Can you please try the code snippet below. You might be needing to wait between clicking and getting the field that you would like to retrieve.
select = Select(driver.find_element_by_xpath('/html/body/div/select'))
select.select_by_visible_text('foobar')
time.sleep(5)
driver.find_element_by_xpath('/html/body/div/div[2]/input').click()
You first need to click to the field, then wait, then click again.
This commonly occurs when JavaScript modifies the page after you interact with it. The solution is to use WebDriverWait:
from selenium.webdriver.support import ExpectedConditions as EC
wait = WebDriverWait(driver, 5)
input = wait.until(EC.element_to_be_clickable(By.xpath('/html/body/div/div[2]/input'))
input.click()

Python with selenium webscraping unable to find elements

I am trying to write a webscraping in python that will activate the "onclick" functionality of certain buttons on a webpage because the tables with the data I want are converted to csv, which makes it much easier to access. But the problem is that I am unable to locate elements by xpath at all when using PhantomJs. How can I click the element and access the csv content that I want?
This is my code:
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.common.by import By
from selenium.webdriver.common.proxy import *
url = "http://www.pro-football-reference.com/boxscores/201609180nwe.htm"
xpath = "//*[#id='all_player_offense']/div[1]/div/ul/li[1]/div/ul/li[3]/button"
path_to_phantomjs = 'browser/phantomjs'
browser = webdriver.PhantomJS(executable_path = path_to_phantomjs)
browser.get(url)
delay=3
element_present = EC.presence_of_element_located((By.ID, 'all_player_offense'))
WebDriverWait(browser, delay).until(element_present)
browser.find_element_by_xpath(xpath).click()
And I get this error:
selenium.common.exceptions.NoSuchElementException: Message: {"errorMessage":"Unable to find element with xpath '//*[#id='all_player_offense']/div[1]/div/ul/li[1]/div/ul/li[3]/button'","request":{"headers":{"Accept":"application/json","Accept-Encoding":"identity","Connection":"close","Content-Length":"153","Content-Type":"application/json;charset=UTF-8","Host":"127.0.0.1:50989","User-Agent":"Python-urllib/2.7"},"httpVersion":"1.1","method":"POST","post":"{\"using\": \"xpath\", \"sessionId\": \"93ff24f0-9cbe-11e6-8711-bdfa3ff9cfb1\", \"value\": \"//*[#id='all_player_offense']/div[1]/div/ul/li[1]/div/ul/li[3]/button\"}","url":"/element","urlParsed":{"anchor":"","query":"","file":"element","directory":"/","path":"/element","relative":"/element","port":"","host":"","password":"","user":"","userInfo":"","authority":"","protocol":"","source":"/element","queryKey":{},"chunks":["element"]},"urlOriginal":"/session/93ff24f0-9cbe-11e6-8711-bdfa3ff9cfb1/element"}}
Screenshot: available via screen
IMPORTANT THING I FORGOT TO MENTION: As described in this this issue on GitHub, try putting set_window_size(width, height) or maximize_window()after setting the webdriver. You should also consider telling the webdriver to implicitly_wait(10) for the element to appear.
So there's a special maneuver you have to perform in order for the Selenium Webdriver to properly emulate what you're doing. In essence, to get the desired data, you'd have to:
A: Hover over the "Share & More" dropdown menu. Then
B: Click "Get table as CSV (Excel)".
For A, this involves having to place the emulated cursor on the element without clicking it. This idea of "mouse over" can be done with the move_to_element() function provided in the ActionChains class. So at the top you'd insert this:
from selenium.webdriver.common.action_chains import ActionChains
You want Selenium to find the specific element and move to it. You can achieve this with 2 lines of code:
dropdown = browser.find_element_by_xpath('//*[#id="all_player_offense"]/div[1]/div/ul/li[1]')
ActionChains(browser).move_to_element(dropdown).perform()
If you omit the above, you'll get an ElementNotVisibleException.
Now for B, you should be able to do browser.find_element_by_xpath(xpath).click().

Categories