How to click Elements on websites with Selenium Python - python

So, I'm not very familiar with Python nor HTML
But I made this code so I could vote in a poll on a website, as far as I'm concerned there is nothing morally wrong with this idea because it is encouraged to refresh your page so you can vote for the same person over and over again. I want to use the code to click a button.
Below is the code I've got so far
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
from selenium.webdriver.common.keys import Keys
import time
PATH = "C:\Program Files (x86)\chromedriver.exe"
driver = webdriver.Chrome(PATH)
driver.get("https://www.nfl.com/voting/rookies/")
So I've gotten as far as going onto the website but I'm not sure if the person I am going to vote for has an HTML ID/Class/Element, I'm not really sure how to find it with inspect element or if it even has an HTML ID/Class/Element. If I want to vote for someone like Justin Herbert of the LAC, how should my code look? How would I click the white button next to Justin with Python? Thank you!

From the driver.get we get a popup, an iframe to handle and we need to click on the div tag that responds to a player. You should be able to translate these steps to your player.
Popup:
<div class="slidedown-footer" id="slidedown-footer"><button class="align-right primary slidedown-button" id="onesignal-slidedown-allow-button">Allow</button><button class="align-right secondary slidedown-button" id="onesignal-slidedown-cancel-button">No Thanks</button><div class="clearfix"></div></div>
Iframe:
<iframe title="Content from Riddle" style="border: none; width: 100%; position: static; opacity: 1; height: 539px !important;" src="https://www.riddle.com/a/288390"></iframe>
Player:
<span class="list-title ng-binding" ng-bind-html="item.title">Salvon Ahmed, MIA</span>
For this we use the following:
driver.get("https://www.nfl.com/voting/rookies/")
wait=WebDriverWait(driver, 10)
wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "#onesignal-slidedown-cancel-button"))).click()
wait.until(EC.frame_to_be_available_and_switch_to_it((By.XPATH, "//iframe[#title='Content from Riddle']")))
wait.until(EC.element_to_be_clickable((By.XPATH, "//span[text()='Salvon Ahmed, MIA']/parent::div/parent::div/div[2]/div"))).click()
Import
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

Related

Send_keys to a textarea jsname in Python Selenium

I'm trying to 'send_keys' to a textarea in Google Reviews using Python Selenium :
This is the element:
<textarea jsname="B7I4Od" jsaction="focus:DTi7Pd; blur:PLbHqf; input:JD9Kbd; change:JD9Kbd; keyup:JD9Kbd; mouseup:nL5Qe" class="shklGc eFqywb T4CXLd" placeholder="Share your experience" aria-label="Enter review" id="Yc71gb" style="height: 90px;"></textarea>
I tried with:
driver.find_element((By.XPATH, '//*[#id="Yc71gb"]')).send_keys('text')
driver.find_element((By.XPATH, "//textarea[contains(#placeholder,'Share your experience')]")).send_keys('text')
driver.find_element((By.XPATH, "//textarea[contains(#aria-label,'Enter review')]")).send_keys('text')
driver.find_element((By.XPATH, "//textarea[contains(#jsname,'B7I4Od')]")).send_keys('text')
driver.find_element((By.CSS_SELECTOR, '#Yc71gb')).send_keys('text')
wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "[aria-label='Enter review']"))).send_keys('text')
But none worked. Any idea?
Thank you.
The text area is in iframe
<iframe name="goog-reviews-write-widget" role="presentation" class="goog-reviews-write-widget" src="https://www.google.com/maps/api/js/ReviewsService.LoadWriteWidget2?key=AIzaSyAQiTKe3tivKXammrJ6ov6u8E7KwZPNFss&authuser=0&hl=en&pb=!2m1!1sChIJo2FtG0NpwokRn0ICTCCkHTw!3shttps%3A%2F%2Fwww.google.com!5sen!7b1&cb=18503887"></iframe>
so you first have to switch to iframe then you can interact with the text area :
WebDriverWait(driver, 20).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH, "//iframe[#name='goog-reviews-write-widget']")))
You'll need imports as well :
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
after that WebDriverWait line you can write the line to identify text area and send the keys.

How to handle drop down list with div tag and multiple attributes?

I am trying to automate the location selection process, however I am struggle with it.
So for, I can only open the menu and select the first item.
And my code is:
import bs4
from bs4 import BeautifulSoup
import selenium
from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.support.ui import Select
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Chrome(ChromeDriverManager().install())
url = 'https://www.ebay.com/b/Food-Beverages/14308/bn_1642947?listingOnly=1&rt=nc'
driver.get(url)
soup = BeautifulSoup(driver.page_source, 'html.parser')
button = driver.find_element_by_id('gh-shipto-click') //find the location button
button.click()
button2 = driver.find_element_by_id('gh-shipto-click-body-cnt') //open the menu
button2.click()
driver.find_element(By.XPATH,"//div[#role='menuitemradio']").click() //choose the first location
I believe the attribute "data-makeup-index" (show in the pic) would help, but I don't know how to use it.
Sine some of you may not able to find the "ship to" button. Here is the html code I copied from the web.
<li id="gh-shipto-click" class="gh-eb-li">
<div class="gh-menu">
<button _sp="m570.l46241" title="Ship to" class="gh-eb-li-a gh-icon" aria-expanded="false" aria-controls="gh-shipto-click-o" aria-label="Ship to Afghanistan"><i class="flgspr gh-flag-bg flaaf"></i><span>Ship to</span></button>
<i class="flgspr gh-flag-bg flaaf"></i>
I have found my answer as below:
driver.find_element(By.XPATH,"//div[#role='menuitemradio'][{an integer}]").click()
Although the Ship to was not visible to my location, I've inspected it from different Geo location and guess what I was able to find this elementstyle="display: none;
I've removed the none temporarily, and it got displayed.
<li id="gh-shipto-click" class="gh-eb-li gh-modal-active" style="display:none;" aria-hidden="false">
You could find the element by these XPath and handle the dropdown
#This XPath is taking you to the specific div where you need to provide the element index [1][2][3] the ID of this XPath is dynamic
driver.find_element_by_xpath("((((//*[contains(#id,'nid-')])[2])//child::div/div")
driver.find_element_by_xpath("//*[#class='cn']")
I know you got your solution, but this what I've tried It might help

Selenium Python library can't find elements on login page

I am attempting to make a web scraper for the Cisco Webex control hub. Since the login page and subsequent pages use Javascript I am using the Selenium Python library to accomplish this. Unfortunately, I am unable to find the text box and sign in button elements with Selenium.
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
# ブラウザを開く。
driver = webdriver.Chrome()
driver.get('https://admin.webex.com')
driver.find_element_by_class_name('md-input ng-pristine ng-invalid ng-touched').send_keys('email#address.com')
driver.find_element_by_class_name('md-panel__cta').click()
I don't have much code yet, but I have tried every way to find the elements, but nothing I tried has worked. Is there any reason why I can't find the elements?
I have moved on ahead and finished the code for the password entry page. However, how Cisco has made each page is different so I was unable to reuse the code from the password entry section on the username entry code.
Your issue was page loading. Induce some waits or you'll miss the element.
WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.CSS_SELECTOR, "input.md-input"))).send_keys("email#address.com")
Import
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
when an element has more than one class, it will not be a good idea to locate element with class like this find_element_by_class_name('md-input ng-pristine ng-invalid ng-touched').
In this case, xpath or cssSelector is a good choice:
driver.find_element_by_xpath("//input[#name='email']")

How to wait till page loads and then press the load more button in selenium?

Using selenium to load and page and need to click load more button, but after it clicks load more than 100 times
i m getting this error of element click intercepted. because after 100 times the page takes time to load. and code doesnt know where to click.
Tried increasing sleep time to 20 seconds also but at some points if page takes more than 20 seconds the code returns error
error :
ElementNotInteractableException: Message: element not interactable (Session info: chrome=75.0.3770.100)
code :
from selenium import webdriver
import time
import pandas as pd
driver = webdriver.Chrome('/Users/1/chromedriver.exe')
driver.get('https://simpletire.com/catalog?select=1&brand=61&query=catalog')
click_more=True
while click_more:
time.sleep(2)
driver.find_element_by_css_selector(".btn.btn-primary.btn-lg").click();
Consider introducing Explicit Wait to ensure that the button is there prior to attempting clicking it
Example code:
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.Chrome('/Users/1/chromedriver.exe')
driver.get('https://simpletire.com/catalog?select=1&brand=61&query=catalog')
click_more=True
while click_more:
WebDriverWait(driver, 30).until(EC.presence_of_element_located((By.CSS_SELECTOR, ".btn.btn-primary.btn-lg"))).click()
More information:
Python Selenium: Wait Support
Python Selenium: Waits
How to use Selenium to test web applications using AJAX technology
In these situations I typically stop the page load, perhaps scroll a couple of times and use screen coordinates with a macro tool like AppRobotic to click the button. Something like this should work for you:
import win32com.client
from win32com.client import Dispatch
x = win32com.client.Dispatch("AppRobotic.API")
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.Chrome('/Users/1/chromedriver.exe')
driver.get('https://simpletire.com/catalog?select=1&brand=61&query=catalog')
# wait 20 seconds per question
x.Wait(20000)
# scroll down a couple of times in case page javascript is waiting for user interaction
x.Type("{DOWN}")
x.Wait(2000)
x.Type("{DOWN}")
x.Wait(2000)
# forcefully stop pageload at this point
driver.execute_script("window.stop();")
# if clicking with Selenium still does not work here, use screen coordinates
x.MoveCursor(xCoord, yCoord)
x.MouseLeftClick
x.Wait(2000)
It would appear that you might be running into the google ad at the bottom of the page.
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
from selenium.common.exceptions import TimeoutException
driver = webdriver.Chrome()
driver.get('https://simpletire.com/catalog?select=1&brand=61&query=catalog')
click_more=True
wait = WebDriverWait(driver, 30)
while click_more:
try:
elem = wait.until(EC.visibility_of_element_located((By.XPATH, '//button[#class="btn btn-primary btn-lg"]')),
"Cannot find 'Load More' button")
elem.click()
except TimeoutException:
click_more = False
Using xpath and visibility_of_element_located I get the following exception:
selenium.common.exceptions.ElementClickInterceptedException: Message: element click intercepted: Element <button class="btn btn-primary btn-lg">...</button> is not clickable at point (591, 797). Other element would receive the click: <iframe id="google_ads_iframe_/21692090825/ST_FlexFooter_0" title="3rd party ad content" name="google_ads_iframe_/21692090825/ST_FlexFooter_0" width="970" height="90" scrolling="no" marginwidth="0" marginheight="0" frameborder="0" srcdoc="" style="border: 0px; vertical-align: bottom;" data-google-container-id="1" data-load-complete="true"></iframe>
You either need to close the google add or scroll the page down a little before attempting to click the button. Once that is done, the while loop should work.
Try the script below to keep clicking on that button until there is none left to click.
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.support import expected_conditions as EC
with webdriver.Chrome() as driver:
wait = WebDriverWait(driver, 10)
driver.get('https://simpletire.com/catalog?select=1&brand=61&query=catalog')
while True:
try:
item = wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, "#load_button > button")))
except TimeoutException:
item = ""
if not item: break
driver.execute_script("arguments[0].scrollIntoView();", item)
item.click()

Unable to click on hidden AirPlay button element on Safari (mac) using the selenium webdriver

As part of testing using Python and Selenium, I intend to open a youtube link using selenium and want to click on the "AirPlay"button in order to send it across to the Apple TV.
Initially I had the problem with the element being hidden but that was taken care of using the ActionChains. The script executes but I do not see click being executed on the video played by which I could see the AppleTv name show up.
Below is the code:
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver import ActionChains
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import os , sys
server_url = "http://10.0.10.4:4444/wd/hub"
capabilities = DesiredCapabilities.SAFARI
driver = webdriver.Remote(desired_capabilities=capabilities,
command_executor=server_url)
driver.get("https://www.youtube.com/watch?v=_YhrCp9m14k")
#air_play = WebDriverWait(driver, 20).until(EC.presence_of_element_located((By.XPATH, '//*[#id="move_player"]/div[28]/div[2]/div[2]/button[6]')))
air_play = WebDriverWait(driver, 20).until(EC.presence_of_element_located((By.CLASS_NAME, 'ytp-airplay-button')))
#air_play = WebDriverWait(driver, 20).until(EC.presence_of_element_located((By.XPATH, '//*[#id="text"]')))
#air_play = driver.find_element_by_css_selector('button.ytp-ariplay-button')
hover = ActionChains(driver).move_to_element(air_play)
hover.perform()
hover1 = ActionChains(driver).click_and_hold(air_play).perform()
The html element is as follows:
<button class="ytp-airplay-button ytp-button" title="AirPlay" style=""><svg
height="100%" version="1.1" viewBox="0 0 36 36" width="100%"><use
class="ytp-svg-shadow" NS1:href="#ytp-id-27"></use><path class="ytp-svg-
fill" d="M12,28 L24,28 L18,22 L12,28 Z M27,9 L9,9 C7.9,9 7,9.9 7,11 L7,23
C7,24.1 7.9,25 9,25 L13,25 L13,23 L9,23 L9,11 L27,11 L27,23 L23,23 L23,25
L27,25 C28.1,25 29,24.1 29,23 L29,11 C29,9.9 28.1,9 27,9 L27,9 Z" id="ytp-
id-27"></path></svg></ button>
The XPATH is as follows:
//*[#id="movie_player"]/div[28]/div[2]/div[2]/button[6]
The CSS Selector is as follows:
#movie_player > div.ytp-chrome-bottom > div.ytp-chrome-controls > div.ytp-
right- controls > button.ytp-airplay-button.ytp-button
Can someone help with as to why the button does not get clicked and show up the available Airplay options?
Before hovering over the video.
After hovering over the video and clicking on the AirPlay button.
I don't have Safari on a Mac so I can't repro this myself but I'm guessing the issue (from your screenshot) is that the icon isn't visible until the video area is hovered. By design, Selenium will not interact with elements that a user can't see. There are a couple ways to do this.
The user way... hover the video, hover the icon, and then click the icon. If you are trying to simulate a user, this is the method you want to use.
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.support import expected_conditions as EC
video = driver.find_element_by_css_selector("video")
ActionChains(driver).move_to_element(video).perform()
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button[title='AirPlay']")).click()
The non-user way... click on it with JSE. With JSE we can click any element, visible or not. No user can click an invisible element so if you are trying to simulate a user, don't use this... use #1.
airplayButton = driver.find_element_by_css_selector("button[title='AirPlay']")
driver.execute_script("arguments[0].click();", airplayButton);

Categories

Resources