I would like to do automated script. I define an array in start of the program.
Later program is opening browser and search in google some specific word (for example apple), next program is clicking in first of string from array and close browser. Later is doing the same but it will click in second of word from array.
My code:
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
driver = webdriver.Chrome("C:/Users/Daniel/Desktop/chromedriver.exe")
driver.implicitly_wait(30)
driver.maximize_window()
hasla = ["ispot","myapple"]
for slogan in hasla:
driver.get("http://www.google.com")
search_field = driver.find_element_by_id("lst-ib")
search_field.clear()
search_field.send_keys("apple")
search_field.submit()
name = driver.find_element_by_link_text(slogan)
name.click()
driver.quit()
driver.implicitly_wait(10)
When Im starting this program from console in windows.
Program is opening browser, looking for apple click in ispot and clsoe browser but its not opening new browser and it not doing the same for next string in array. Any solution ?
In console i have this:
screen
You're exiting the browser in your for loop, so the second iteration can't do anything because there's not a browser open. You could try opening a new tab and closing the old one if you need to start fresh each time. Try this:
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
driver = webdriver.Chrome("C:/Users/Daniel/Desktop/chromedriver.exe")
driver.implicitly_wait(30)
driver.maximize_window()
hasla = ["ispot","myapple"]
for slogan in hasla:
driver.get("http://www.google.com")
search_field = driver.find_element_by_id("lst-ib")
search_field.clear()
search_field.send_keys("apple")
search_field.submit()
name = driver.find_element_by_link_text(slogan)
name.click()
# Save the current tab id
old_handle = driver.current_window_handle
# Execute JavaScript to open a new tab and save its id
driver.execute_script("window.open('');")
new_handle = driver.window_handles[-1]
# Switch to the old tab and close it
driver.switch_to.window(old_handle)
driver.close()
# Switch focus to the new tab
driver.switch_to.window(new_handle)
If you are closing the tab you won't be able to see the results. You might want to keep it open and just go to the new tab. In which case, just remove driver.close().
Alternatively, if you really want to completely close out the browser each time and reopen it, you just need to include the first three lines in your for-loop.
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
hasla = ["ispot","myapple"]
for slogan in hasla:
driver = webdriver.Chrome("C:/Users/Daniel/Desktop/chromedriver.exe")
driver.implicitly_wait(30)
driver.maximize_window()
driver.get("http://www.google.com")
search_field = driver.find_element_by_id("lst-ib")
search_field.clear()
search_field.send_keys("apple")
search_field.submit()
name = driver.find_element_by_link_text(slogan)
name.click()
driver.quit()
To answer your second question:
First, import NoSuchElementException:
from selenium.common.exceptions import NoSuchElementException
Then replace your try/except with this:
try:
name = driver.find_element_by_link_text(slogan)
name.click()
except NoSuchElementException:
print('No such element')
driver.quit()
It's still going to close the browser and go to the next iteration if the element is found or not.
Related
I am currently scraping website https://glasschain.org (to be precise let's focus on example - https://glasschain.org/btc/wallet/100478015). There is a tab named 'Addresses', when I want to go to the X-th page (in this example equals 5 000) from available over 12 000 (to parallel some operations and not do it iteratively). To do it manually, I need to click on ... button and write a number and click ENTER. I use Python and selenium library to do it automatically and I have managed with clicking the button but I can't send a value to a field which appears after my click (in source code of website after clicking to button there is no new input field where I can send that value so I have tried to send it to the only existing element - earlier clicked button). Can anyone help me with that ? :)
My code:
chrome_options = Options()
chrome_options.add_argument("--start-maximized")
driver = webdriver.Chrome(path, options=chrome_options)
driver.get('https://glasschain.org/btc/wallet/100478015')
time.sleep(5)
adr_button = driver.find_elements_by_id('tab-Addresses')[1]
driver.execute_script("arguments[0].click();", adr_button)
time.sleep(5)
dots_button = driver.find_elements_by_class_name('ellipse')[0]
driver.execute_script("arguments[0].click();", dots_button)
dots_button.send_keys(5000)
My error:
selenium.common.exceptions.ElementNotInteractableException: Message: element not interactable (Session info: chrome=110.0.5481.77)
Version of selenium I am working with: 3.141.0
I don't have your specific version of selenium, but here's a solution that works with a more recent version, selenium 4.7.2:
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as ec
from selenium.webdriver.common.by import By
from selenium.common.exceptions import TimeoutException
from time import sleep
s = Service('bin/chromedriver.exe')
chrome_options = Options()
chrome_options.add_argument("--start-maximized")
driver = webdriver.Chrome(service=s, options=chrome_options)
driver.get('https://glasschain.org/btc/wallet/100478015')
delay = 3 # seconds
try:
adr_button = WebDriverWait(driver, delay).until(ec.presence_of_element_located((By.ID, 'tab-Addresses')))
except TimeoutException:
print("Loading timed out, exiting...")
exit()
# click the GDPR cookies accept button, if that hasn't happened yet
gdpr_button = driver.find_element(by='id', value='gdpr')
if gdpr_button:
driver.execute_script("gdpr('accept');")
driver.execute_script("arguments[0].click();", adr_button)
try:
dots_button = WebDriverWait(driver, delay).until(ec.presence_of_element_located((By.CLASS_NAME, 'ellipse')))
except TimeoutException:
print("Loading timed out, exiting...")
exit()
# click the dots button, to make the input appear
driver.execute_script("arguments[0].click();", dots_button)
# select the input, modify the value and then make it lose focus
dots_input = dots_button.find_element('xpath', "//span[#class='ellipse clickable']/input")
print(dots_input)
driver.execute_script("arguments[0].setAttribute('value','5000');", dots_input)
driver.execute_script("arguments[0].blur();", dots_input)
# just so you can see before the driver closes the browser again
sleep(10)
Note that, instead of waiting a number of seconds, the script simply waits until a specific element is loaded and then continues. There's still a delay defined, but this is now the maximum amount of time the script will wait for the element to load, instead of just waiting a fixed amount of time.
Once the button is clicked, a nested input element appears, which is selected and then JavaScript is executed to change its value and cause it to lose focus (blur), so that the new value gets applied.
(note that I have the Chrome driver in a subfolder next to the script, called bin)
How would I make webdriver selenium open another tab, and copy something from that another tab, close it and paste it in the first tab?
How would I do this?
driver = webdriver.Chrome()
wait = WebDriverWait(driver, 30)
Here's an example that opens a page, opens a new tab, copies something, closes the tab, and pastes the text into an input field on the new tab:
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("https://seleniumbase.io/demo_page")
driver.switch_to.new_window("tab")
driver.get("data:text/html,<h1>Page B</h1>")
text = driver.find_element("css selector", "h1").text
driver.close()
window_handle = driver.window_handles[0]
driver.switch_to.window(window_handle)
driver.find_element("css selector", "input").send_keys(text)
driver.quit()
Objective:
Need to open a webpage, find urls by class and then open each url in a new tab in chrome
What I tried:
from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.common.keys import Keys
driver = webdriver.Chrome(executable_path="C:\\Users\xxx\Downloads\chromedriver_win32\chromedriver.exe")
driver.maximize_window()
driver.get("https://xxxxxxxx.com")
elements = driver.find_elements_by_class_name("post-comments")
for e in elements:
e.click()
driver.quit()
current output:
It's just opening the first url in the same parent window then stop there.. focus is not going to base url so it is not able to open second and other urls in new tab.
Please let me know your suggestions.
Update1: when I search for relative xpath, I came to know that I need to use regexp so that I can find all links containing "respond" in it.
For that I tried to use
driver.find_element_by_css_selector("a[href*='respond']]")
but it errored there is no find_element.
Update 2:
After some trials, I am able to achieve to the most output that I require with below code. But below code is working on first page only, when below code completes for first page, then there will be 'NextPage' button , I need to click on that to open that page, that will become new main page and I need to run the below piece of code again on that page. How to tell below piece of code once elements on this page done, click on 'NextPage' button and run below logic for that page. Please suggest
from selenium import webdriver
import time
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
driver = webdriver.Chrome(executable_path="C:\\Users\xxx\Downloads\chromedriver_win32\chromedriver.exe")
driver.maximize_window()
driver.get("https://xxxxxxxx.com")
current_windows_handle = driver.current_window_handle
elements = driver.find_elements_by_css_selector('h2.post-title.entry-title>a')
for ele in (elements):
url = [ele.get_attribute("href")]
for x in url:
time.sleep(2)
driver.execute_script("window.open('');")
handles = driver.window_handles
driver.switch_to.window(handles[1])
driver.get(x)
driver.find_element_by_xpath("//span[#class='mb-text'][contains(.,'Posts')]").click()
time.sleep(2)
driver.close()
driver.switch_to.window(driver.window_handles[1])
time.sleep(5)
actualurl = driver.current_url
with open(r'c:\test\new.txt', 'a') as text_file:
text_file.write(actualurl + '\n')
driver.close()
time.sleep(5)
driver.switch_to.window(current_windows_handle)
driver.close()
driver.quit()
The error is valid, cause
driver.find_element_by_css_selector("a[href*='respond']]")
this is syntax error, but since it is wrapped inside "", compiler won't show it.
try this instead :
elements = driver.find_elements_by_css_selector("a[href*='respond']")
and then print the length like this :-
print(len(elements))
I am assuming that it will have some elements in it. and you can iterate it as well. Pleas see below, it should help you figure out how to simulate those actions.
current_windows_handle = driver.current_window_handle
elements = driver.find_elements_by_css_selector("a[href*='respond']")
for ele in elements:
time.sleep(2)
driver.execute_script("window.open('');") # open a new tab.
handles = driver.window_handles
driver.switch_to.window(handles[1])
driver.get(ele.get_attribute('href'))
time.sleep(2)
# Now it would have loaded a new url in new tab.
# do whatever you wanna do.
# Now close the new tab
driver.close()
time.sleep(2)
driver.switch_to.window(current_windows_handle)
updated 1 :
current_windows_handle = driver.current_window_handle
elements = driver.find_elements_by_css_selector("a[href*='respond']")
j = 0
for ele in range(len(elements)):
time.sleep(2)
elements = driver.find_elements_by_css_selector("a[href*='respond']")
driver.execute_script("window.open('');") # open a new tab.
handles = driver.window_handles
driver.switch_to.window(handles[1])
driver.get(elements[j].get_attribute('href'))
time.sleep(2)
j = j + 1
# Now it would have loaded a new url in new tab.
# do whatever you wanna do.
# Now close the new tab
driver.close()
time.sleep(2)
driver.switch_to.window(current_windows_handle)
I have tried all the methods in similar questions and only one of them worked which was to use javascript.
driver.execute_script("window.open('')")
#this works
ActionChains(driver).key_down(Keys.CONTROL).send_keys('t').key_up(Keys.CONTROL).perform()
#this doesn't
driver.find_element_by_tag_name('body').send_keys(Keys.CONTROL + 't')
#this doesn't work either
I'd like to get the second way to work, since it seems the most readable and sensible, am I doing something wrong in my code? Or is there any option I need to change in Selenium to enable opening tabs like this?
Edit: The 2nd and 3rd method don't produce any result at all. Not even an exception.
Below code works for me for opening and closing tabs:
import time
from selenium import webdriver
driver = webdriver.Firefox()
driver.get("http://www.python.org")
time.sleep(2)
# open new tab
driver.execute_script("window.open('');")
# switch to the new tab and open new URL there
driver.switch_to.window(driver.window_handles[1])
driver.get("http://www.python.org")
time.sleep(2)
chld = driver.window_handles[1]
driver.switch_to.window(chld)
driver.close()
The second way didn't work for me as well.
import the selenium module
from selenium import webdriver
creates selenium object
driver = webdriver.Chrome()
gets the url needed for the driver object
url = "https://www.google.com/"
Open a new window
driver.execute_script("window.open('');")
Close the tab
driver.close()
I'm trying to automate the search process in this website: https://www.bcbsga.com/health-insurance/provider-directory/searchcriteria
The process involves clicking on the "Continue" button to search under the 'guest' mode. The next page has got a list of drop-down items to refine the search criteria. My code either produces the "Element not visible" exception (which I corrected by using a wait) or times out. Please help.
Here's my code:
# navigate to the desired page
driver.get("https://www.bcbsga.com/health-insurance/provider-directory/searchcriteria")
# get the guest button
btnGuest = driver.find_element_by_id("btnGuestContinue")
#click the guest button
btnGuest.click()
wait = WebDriverWait(driver,10)
#Find a Doctor Search Criteria page
element = wait.until(EC.visibility_of_element_located((By.ID,"ctl00_MainContent_maincontent_PFPlanQuestionnaire_ddlQuestionnaireInsurance")))
lstGetInsurance = Select(element)
lstGetInsurance.select_by_value("BuyMyself$14States")
# close the browser window
#driver.quit()
you can use input search and key.return:
import time
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
divID = 'ctl00_MainContent_maincontent_PFPlanQuestionnaire_ddlQuestionnaireInsurance_chosen'
inputID = 'ctl00_MainContent_maincontent_PFPlanQuestionnaire_ddlQuestionnaireInsurance_chosen_input'
inputValue = 'I buy it myself (or plan to buy it myself)'
driver = webdriver.Chrome()
driver.get("https://www.bcbsga.com/health-insurance/provider-directory/searchcriteria")
driver.find_element_by_id("btnGuestContinue").click()
driver.implicitly_wait(10)
driver.find_element_by_id(divID).click()
driver.find_element_by_id(inputID).send_keys(inputValue)
driver.find_element_by_id(inputID).send_keys(Keys.RETURN)
time.sleep(6)
driver.close()