i want to read the toner values on the web pages of the various printers in my office.
The problem is that the page is made up of several frames, and the one in which there is the remaining toner, is written in js and I can't read it even with selenium
This is my code:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.expected_conditions import (
presence_of_element_located)
from selenium.webdriver.support.wait import WebDriverWait
def get_comment_count(driver, url):
driver.get(url)
wait = WebDriverWait(driver, 3)
e = driver.find_elements_by_xpath("/html/frameset/frame")
driver.switch_to_frame(e[0])
toner_iframe = driver.find_elements_by_xpath('//*[#id="contain"]')
# iframe_url = toner_iframe.get_attribute('src')
#driver.switch_to_frame(toner_iframe)
driver.switch_to.frame(toner_iframe)
print(toner_iframe)
url = "https://pritner_web_page"
options = webdriver.ChromeOptions()
options.add_argument('--ignore-certificate-errors')
options.add_argument('--ignore-ssl-errors')
driver = webdriver.Chrome(options=options)
get_comment_count(driver,url)
I tried also...
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.common.action_chains import ActionChains
from selenium import webdriver
options = webdriver.ChromeOptions()
options.add_argument('--ignore-certificate-errors')
options.add_argument('--ignore-ssl-errors')
driver = webdriver.Chrome(options=options)
driver.get("http://printer_web_page")
WebDriverWait(driver,5).until(EC.frame_to_be_available_and_switch_to_it((By.ID,'wlmframe')))
WebDriverWait(driver,5).until(EC.frame_to_be_available_and_switch_to_it((By.ID,'toner')))
page_source=driver.page_source
print(page_source)
This is DOM Inspector of page. The various frames are dynamic and written in js as follows:
The code I wrote is just one of several different attempts to get to the frame, but to no avail
The element is within nested <frame> / <iframe> elements so you have to:
Induce WebDriverWait for the parent frame to be available and switch to it.
Induce WebDriverWait for the child frame to be available and switch to it.
Induce WebDriverWait for the desired element to be clickable.
You can use either of the following Locator Strategies:
Using CSS_SELECTOR:
driver.get("http://printer_web_page")
WebDriverWait(driver, 20).until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR,"frame[name='wlmframe']")))
WebDriverWait(driver, 20).until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR,"iframe#toner[name='toner']")))
Using XPATH:
driver.get("http://printer_web_page")
WebDriverWait(driver, 20).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH,"//frame[#name='wlmframe']")))
WebDriverWait(driver, 20).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH,"//iframe[#id='toner' and #name='toner']")))
Note : You have to add the following imports :
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
Reference
You can find a couple of relevant discussions in:
Ways to deal with #document under iframe
Switch to an iframe through Selenium and python
How to write appropriate Xpath to locate text value
How To sign in to Applemusic With Python Using Chrome Driver With Selenium
Related
"""
Web scraping the wikipidia page
"""
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))
driver.get("https://en.wikipedia.org/wiki/Main_Page")
num_articles1 = driver.find_element(By.CSS_SELECTOR, '#articlecount a')
print(num_articles1.text)
num_articles1.click()
driver.close()
Question: num_articles1 returns the value but why is the click() not working ?
can't understand why is this happening, what am i missing?
On my Windows 10 using latest Selenium, ChromeDriver and Chrome the number of articles i.e. 6,559,615 gets printed perfectly and the click() is also performed perfecto.
However, to click on the clickable element ideally you need to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following locator strategies:
Using CSS_SELECTOR:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "#articlecount a"))).click()
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//div[#id='articlecount']/a"))).click()
Note: You have to add the following imports :
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
Code trials:
from selenium import webdriver
from selenium.webdriver import Keys, ActionChains
from selenium.webdriver.chrome.service import Service
from time import time
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
service = Service(executable_path="C:\\Users\\aps\\Desktop\\Python\\chromedriver.exe")
driver = webdriver.Chrome(service=service)
driver.get("https://youtube.com")
search = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "search")))
ActionChains(driver).move_to_element(search).pause(2).click_and_hold().send_keys("Iktarfa").perform()
button = driver.find_element(By.ID, "search-icon-legacy").click()
Search field is getting fetched.
But after that I am getting following error, I am out of ideas and a new learner. Please HELP!!
The locator strategy which you have used:
(By.ID, "search")
identifies multiple elements within the HTML DOM.
and the first WebElement having the property style="display: none;". Hence you see the error.
Solution
To send a character sequence to the element you need to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following locator strategies:
Using CSS_SELECTOR:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "ytd-searchbox#search"))).send_keys("text")
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//ytd-searchbox[#id='search']"))).send_keys("text")
Note: You have to add the following imports :
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
There is no need to add a Actions class for this scenario. It is perfectly capable of doing the search after just using the click and then searching for the element.
I used this code piece and it works perfectly fine
import time
from seleniumwire import webdriver
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
svc = Service(ChromeDriverManager().install())
options = Options()
options.add_argument('--allow-running-insecure-content')
options.add_argument('--ignore-certificate-errors')
driver = webdriver.Chrome(service=svc,options=options)
driver.maximize_window()
driver.get("https://youtube.com")
search = WebDriverWait(driver, 20).until(EC.presence_of_element_located((By.ID, "search")))
driver.find_element(By.NAME,'search_query').click()
time.sleep(5)
driver.find_element(By.NAME,'search_query').send_keys('Iktarfa')
button = driver.find_element(By.ID, "search-icon-legacy").click()
time.sleep(5)
driver.quit()
I've used the sleep method, but you should in general use an intelligent wait mechanism like Explicit waits.
Output screenshot -
I would like to click button "ja ik ga akkoord" on url anwb.nl with python selenium chrome. I have copied the relative xpath but when is use it i keep getting NoSuchElementException. Also id, name, etc no luck
I start with:
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
options = Options()
driver = webdriver.Chrome(options=options)
driver.get('https://anwb.nl')
When i inspect the page, xpath of the button gives me:
//*[#id="accept default level"]
When i use this with ...by_xpath i get NoSuchElementException
The code of the button is:
<button class="btn-decide_link-internal" type="button"
name="save"
id="accept default level"> ==$0
Ja, ik ga akkoord</button>
I tried id (accept def...), name (save), but all nosuchelement
In general i would really like to understand how to interpret the web code in general can solve future problems.
The element with text as Ja, ik ga akkoord is within an <iframe> so you have to:
Induce WebDriverWait for the desired frame to be available and switch to it.
Induce WebDriverWait for the desired element to be clickable.
You can use either of the following Locator Strategies:
Using CSS_SELECTOR:
driver.get("https://www.anwb.nl/");
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR,"iframe[src*='anwb']")))
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button.btn-decide_link-internal"))).click()
Using XPATH:
driver.get("https://www.anwb.nl/");
WebDriverWait(driver,10).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH,"//iframe[contains(#src, 'anwb')]")))
WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.XPATH,"//button[#id='accept default level']"))).click()
Note : You have to add the following imports :
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
Browser snapshot:
Here you can find a relevant discussion on Ways to deal with #document under iframe
There is an iframe.Induce WebDriverWait and switch to frame first and then click on the button.
EC.frame_to_be_available_and_switch_to_it()
EC.element_to_be_clickable()
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 import webdriver
from selenium.webdriver.chrome.options import Options
options = Options()
driver = webdriver.Chrome(options=options)
driver.get('https://anwb.nl')
WebDriverWait(driver,10).until(EC.frame_to_be_available_and_switch_to_it((By.TAG_NAME,"iframe")))
WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.ID,"accept default level"))).click()
I'm experimenting witch selenium in Python. I'm trying to click at up or down vote button below the comment. I'm using XPath to determinate specyfic button. There's no error occured but counter doesn't increase after clicking. I have tried on different webpages but results are same.
My first approach was that, I have used find_element_by() function but after that I could't use click() method on returned element. Now I'm useing ActionChains
This is my script
from selenium import webdriver
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
import time
driver = webdriver.Firefox()
driver.get("https://forsal.pl/praca/wynagrodzenia/artykuly/1422953,nik-w-nbp-sa-nieprawidlowosci.html")
driver.maximize_window()
wait = WebDriverWait(driver,30)
action = ActionChains(driver)
cookieButton = wait.until(EC.element_to_be_clickable((By.ID,"inforcwp-y")))
cookieButton.click()
time.sleep(5)
#wait.until(EC.visibility_of((By.XPATH,"/html/body/div[2]/section/div[2]/div[1]/div[1]/div[1]/div/div[9]/div[2]/div/ul/li[20]/p[1]/span[4]/a[2]")))
element = driver.find_element(By.XPATH,"/html/body/div[2]/section/div[2]/div[1]/div[1]/div[1]/div/div[4]/div[2]/div/ul/li[8]/p[1]/span[4]/a[2]")
element.location_once_scrolled_into_view
time.sleep(5)
action.double_click(element)
time.sleep(5)
driver.quit()
I'm expecting to increase up/down vote cunter after clicking on "voting hand"
Please give mo some advices how to achive my goal
To click() on the upvote icon you need to induce WebDriverWait for the element to be clickable and you can use the following Locator Strategies:
Code Block:
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
chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument("start-maximized")
chrome_options.add_argument('disable-infobars')
driver = webdriver.Chrome(options=chrome_options, executable_path=r'C:\Utility\BrowserDrivers\chromedriver.exe')
driver.get("https://forsal.pl/praca/wynagrodzenia/artykuly/1422953,nik-w-nbp-sa-nieprawidlowosci.html")
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.ID,"inforcwp-y"))).click()
driver.execute_script("return arguments[0].scrollIntoView(true);", WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.XPATH,"//span[#class='headerUnderline' and contains(., 'Komentarze')]"))))
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH,"//ul[#id='commentsList']/li/p//span[#class='kf-rating']//a[#class='ratingUp']"))).click()
On the website the selenium script cannot find the login and password fields. I tried to search by xpath, css selector, name and class name. But nothing worked.
from selenium import webdriver
from time import sleep
driver = webdriver.Firefox()
driver.get("https://login.aliexpress.com/")
driver.find_element_by_id("fm-login-id").send_keys("test_id")
driver.find_element_by_id("fm-login-password").clear()
driver.find_element_by_id("fm-login-password").send_keys("test_pass")
driver.find_element_by_id("fm-login-submit").click()`
I tried to do this with the help of Selenium IDE, and everything worked in the GUI. But after I exported the code to python and ran it, the program gave an error that it could not find the element.
The login form is inside of a frame, you need to switch to it first.
from selenium import webdriver
from time import sleep
driver = webdriver.Firefox()
driver.get("https://login.aliexpress.com/")
frame = driver.find_element_by_id("alibaba-login-box")
driver.switch_to.frame(frame)
driver.find_element_by_id("fm-login-id").send_keys("test_id")
driver.find_element_by_id("fm-login-password").clear()
driver.find_element_by_id("fm-login-password").send_keys("test_pass")
driver.find_element_by_id("fm-login-submit").click()
However as the the desired elements are within an <iframe> so you have to:
Induce WebDriverWait for the desired frame to be available and switch to it.
Induce WebDriverWait for the desired elements to be clickable.
You can use the following solution:
Using CSS_SELECTOR:
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Firefox(executable_path=r'C:\Utility\BrowserDrivers\geckodriver.exe')
driver.get("https://login.aliexpress.com/")
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR,"iframe#alibaba-login-box[src^='https://passport.aliexpress.com/mini_login.htm?']")))
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "input.fm-text#fm-login-id"))).send_keys("test_id")
driver.find_element_by_css_selector("input.fm-text#fm-login-password").send_keys("test_pass")
driver.find_element_by_css_selector("input.fm-button#fm-login-submit").click()
Interim Broswer Snapshot:
Note : You have to add the following imports :
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
Reference
You can find a relevant discussion in
Ways to deal with #document under iframe