Selenium does not load html properly - Python3.8 [duplicate] - python-3.x

This question already has answers here:
Unable to locate element of credit card number using selenium python
(2 answers)
NoSuchElementException: Message: Unable to locate element while trying to click on the button VISA through Selenium and Python
(3 answers)
org.openqa.selenium.NoSuchElementException: Returned node (null) was not a DOM element when trying to locate card-fields-iframe by CssSelector
(3 answers)
Closed 3 years ago.
i'm using selenium with python to register into a website.
My problem is that when i need to insert the credit card number and the security number, though i copy the xpath of the field, wait for the field to be visible and clickable, python raise a timeout exception becouse he didn't find any field with that xpath. The html code of the field is that:
<input id="cardnumber" autocomplete="cc-number" type="tel" pattern="[0-9]*" placeholder="1111 2222 3333 4444" data-encrypted-name="number" class="form-control">
UPDATE: Maybe I understand.
When I print out driver.page_source I notice that it's not loaded properly, and now I understand why Selenium can't find nothing, neither by xpath, neither by name or everything. I notice that what is loaded can be clicked and all, but some fields are not loaded.
So why Selenium behave like that?
UPDATE AGAIN: Solved, the solution is that i need to switch iframe every time.

Try This By Adding Some Wait:
from selenium.webdriver.common.by import By
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait as Wait
driver = webdriver.Chrome()
driver.maximize_window()
driver.get("Your Website")
try:
cardnumber = WebDriverWait(driver, 20).until(EC.presence_of_element_located((By.ID, "#cardnumber")))
except:
print('Sorry!')
cardnumber.send_keys('XXXXX')

You are passing wrong ID. You dont need to pass #when you are trying to identify element with its ID.
cardnumber = WebDriverWait(driver, 20).until(EC.presence_of_element_located((By.ID, "cardnumber")))
Please check locator strategies :https://selenium-python.readthedocs.io/locating-elements.html

Related

Which method should I use for selenium.webdriver.support.expected_conditions object when waiting for Ajax based card details to load?

I'm trying to spider a page for links with a specific CSS class with Selenium for Python 3. For some reason it just stops, when it should loop through again
def spider_me_links(driver, max_pages, links):
page = 1 # NOTE: Change this to start with a different page.
while page <= max_pages:
url = "https://www.example.com/home/?sort=title&p=" + str(page)
driver.get(url)
# Timeout after 2 seconds, and duration 5 seconds between polls.
wait = WebDriverWait(driver, 120, 5000)
wait.until(EC.visibility_of_all_elements_located((By.CSS_SELECTOR, 'card-details')))
# Obtain source text
source_code = driver.page_source
soup = BeautifulSoup(source_code, 'lxml')
print("findAll:", len(soup.findAll('a', {'class' : 'card-details'}))) # returns 12 at every loop iteration.
links += soup.findAll('a', {'class' : 'card-details'})
page += 1
The two lines I think I have it wrong on are the following:
# Timeout after 2 seconds, and duration 5 seconds between polls.
wait = WebDriverWait(driver, 120, 5000)
wait.until(EC.visibility_of_all_elements_located((By.CSS_SELECTOR, 'card-details')))
Because during that point I'm waiting for content to be loaded dynamically with Ajax, and the content loads fine. If I don't use the function to load it and I don't run the above two lines, I'm able to grab the <a> tags, but if I put it in the loop it just gets stuck.
I looked at the documentation for the selenium.webdriver.support.expected_conditions class (the EC object in my code above), and I'm fairly unsure about which method I should use to make sure the content has been loaded before scraping it with BS4.
Usually creditcard name, creditcard numbers resides within <frame> / <iframe>
To focus on those elements, you have to:
Induce WebDriverWait for the desired frame to be available and switch to it.
You can use either of the following Locator Strategies:
Using ID:
WebDriverWait(driver, 20).until(EC.frame_to_be_available_and_switch_to_it((By.ID,"iframe_id")))
Using NAME:
WebDriverWait(driver, 20).until(EC.frame_to_be_available_and_switch_to_it((By.NAME,"iframe_name")))
Using CLASS_NAME:
WebDriverWait(driver, 20).until(EC.frame_to_be_available_and_switch_to_it((By.CLASS_NAME,"iframe_classname")))
Using CSS_SELECTOR:
WebDriverWait(driver, 20).until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR,"iframe_css")))
Using XPATH:
WebDriverWait(driver, 20).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH,"iframe_xpath")))
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
Unable to locate element of credit card number using selenium python
NoSuchElementException: Message: Unable to locate element while trying to click on the button VISA through Selenium and Python
Your selector "means" that you want to select element with tag name 'card-details' while you need to select element with #class='card-details'
Try either
(By.CSS_SELECTOR, '.card-details')
or
(By.CLASS_NAME, 'card-details')
I ended up using:
wait.until(EC.presence_of_element_located((By.CLASS_NAME, 'card-details')))
And it appears to have worked.

selenium.common.exceptions.ElementNotInteractableException: Message: element not interactable sending text to First name field using Selenium Python

Through Selenium, I try to enter the username on one popular site, but, for some reason I do not understand, this does not work. Everything opens, a click occurs on the desired input field, but immediately after that an error appears when trying to enter text.
Here is my code:
webdriverDir = "./chromedriver.exe"
home_url = 'https://appleid.apple.com/account/'
browser = webdriver.Chrome(executable_path=webdriverDir)
browser.get(home_url)
elem = browser.find_element_by_id("firstNameInput")
elem.click()
elem.send_keys('namename')
time.sleep(5)
I also tried to change the solution to this:
browser.find_element_by_id("firstNameInput").send_keys("namename")
But it also does not work. I can’t understand what’s the matter.
Also tried through xpath, class_name and css_selector. The result was either the same or the element was simply not detected. Although everything was copied from element code from console.
Error Code:
selenium.common.exceptions.ElementNotInteractableException: Message: element not interactable
Where could there be a mistake? Or can it be the site itself?
The element with firstNameInput id is not an input and it's a custom tag and your send-keys commands can not access that element.
what you have to do is, access the input present in the parent element.
driver.find_element_by_css_selector("#firstNameInput input").send_keys('hello')
To send a character sequence to the First name field you have to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following Locator Strategies:
Using CSS_SELECTOR:
driver.get("https://appleid.apple.com/account/")
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "first-name-input#firstNameInput input"))).send_keys("haruhi")
Using XPATH:
driver.get("https://appleid.apple.com/account/")
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//span[#class='form-label' and normalize-space()='First name']//preceding::input[1]"))).send_keys("haruhi")
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:

Switching Between Windows of JS Page Selenium Python [duplicate]

This question already has answers here:
Switching into new window using Selenium after button click
(1 answer)
Windows Handling Closes the whole browser if i try to close the current window in python
(2 answers)
Closed 3 years ago.
Does driver.switch_to.window Function work with Javascript Pages for Selenium Python?
The question relates to whether driver.switch_to.window would work with JS Pages. It doesnt as per my recent finding.
I recently discovered in my project that it doesnt work.I used the work around of using the back button in browser
from selenium import webdriver
import time
from selenium.webdriver.common.keys import Keys
import pdb
from selenium.webdriver.support.ui import Select
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
chrome_path=r'C:\webdrivers\chromedriver.exe'
driver=webdriver.Chrome(chrome_path)
url='https://www.google.com/'
URL_List=['1line williams']
for i in range(0,2):
driver.get(url)
SearchPage = driver.window_handles[0]
searchbar=driver.find_element_by_name('q')
time.sleep(2)
searchbar.send_keys(URL_List[i])
searchbar.send_keys(Keys.ENTER)
if i==2:
PipelineID=1
SelectLink=driver.find_element_by_xpath('//*[#id="rso"]/div[1]/div/div/div/div/div[1]/a/h3').click()
time.sleep(2)
Links=driver.find_elements_by_class_name("links")
aElements = driver.find_elements_by_tag_name("a")
for name in aElements:
window_after=driver.window_handles[0]
time.sleep(5)
SelectPipeline=driver.find_element_by_xpath('//*[#id="splashContent_pipelines"]/div['+str(PipelineID)+']/p[2]/a[1]').click()
time.sleep(2)
Location=driver.find_element_by_xpath('//*[#id="navmenu-v"]/li[4]/a').click()
time.sleep(2)
File=driver.find_element_by_xpath('//*[#id="navmenu-v"]/li[4]/ul/li/a').click()
time.sleep(15)
document=driver.find_element_by_tag_name('iframe')
driver.switch_to.frame(document)
time.sleep(2)
DownloadFile=driver.find_element_by_xpath('//*[#id="list:downloadBtn"]').click()
time.sleep(2)
driver.execute_script("window.history.go(-2)")
PipelineID=PipelineID+1
time.sleep(3)
if PipelineID>3:
driver.quit()
break
This is the code Im using. Im using Selenium to go to google use the keyword and download data in Location column. Here I tried using driver.switch_to.window instead of execute script cmd at last(browser back button)but it dint work
So once again I would like to know if driver.switch_to.window works on JS Pages or not.

How to fix "element is not attached to the page document/element not interactable"? [duplicate]

This question already has answers here:
How to resolve ElementNotInteractableException: Element is not visible in Selenium webdriver?
(6 answers)
Selenium WebDriver throws Exception in thread "main" org.openqa.selenium.ElementNotInteractableException
(1 answer)
Closed 3 years ago.
I'm setting up a function that auto scrolls and auto likes on Instagram but when i try run it, it either comes up with an error that element not interactable or element is not attached to the page document
I tried the time.sleep and driver.implicitly_wait to check if it because the elements haven't loaded yet
html = self.driver.find_element_by_tag_name('html')
while True:
button = self.driver.find_element_by_class_name('_9AhH0')
time.sleep(0.5)
html.send_keys(Keys.PAGE_DOWN)
time.sleep(0.5)
try:
button.send_keys(Keys.ENTER)
print("Like")
except Exception as e:
print(e)
Try adding a wait condition before interacting with the element:
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.support.ui import WebDriverWait
button= WebDriverWait(driver, 20).until(
expected_conditions.presence_of_element_located(By.CSS_SELECTOR, "._9AhH0")).send_keys(Keys.ENTER)

ElementNotVisibleException: Message: element not interactable error while trying to click on the top video in a youtube search

I cannot seem to find a way to click on the right element in order to get the url I am looking for. In essence I am trying to click on the top video in a youtube search (the most highly ranked returned video).
How to resolve ElementNotInteractableException: Element is not visible in Selenium webdriver?
-> This is for Java but it let me in the right direction (knowing I needed to execute JavaScript)
http://www.teachmeselenium.com/2018/04/17/python-selenium-interacting-with-the-browser-executing-javascript-through-javascriptexecutor/
-> This shows me how I should try to execute the javascript in python.
I have also seen countless articles about waits but they do not solve my problem.
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time
wrds = ["Vivaldi four seasons", "The Beatles twist and shout", "50
cent heat"] #Random list of songs
driver = webdriver.Chrome()
for i in wrds:
driver.get("http://www.youtube.com")
elem = driver.find_element_by_id("search")
elem.send_keys(i)
elem.send_keys(Keys.RETURN)
time.sleep(5)
driver.execute_script("arguments[0].click()",driver.find_element_by_id('video-title')) #THIS CLICKS ON WRONG VIDEO
#elem = driver.find_element_by_id("video-title").click() #THIS FAILS
time.sleep(5)
url = driver.current_url
driver.close()
I get a ElementNotVisibleException: Message: element not interactable error when I do not execute any javascript (even though it has actually worked before it is just no way near robust). When I do execute the javascript it clicks on the wrong videos.
I have tried all types of waits "Explicit" and "Implicit" this did now work.
I am quite sure I need to execute some JavaScript but I don't know how.
You were almost there. You need to induce WebDriverWait for the element to be clickable and you can use the following solution:
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
wrds = ["Vivaldi four seasons", "The Beatles twist and shout", "50 cent heat"]
kwrd = ["Vivaldi", "Beatles", "50"]
options = webdriver.ChromeOptions()
options.add_argument("start-maximized")
options.add_argument("disable-infobars")
options.add_argument("--disable-extensions")
driver=webdriver.Chrome(chrome_options=options, executable_path=r'C:\WebDrivers\\chromedriver.exe')
for i, j in zip(wrds, kwrd):
driver.get("https://www.youtube.com/")
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "input#search"))).send_keys(i)
driver.find_element_by_css_selector("button.style-scope.ytd-searchbox#search-icon-legacy").click()
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "h3.title-and-badge.style-scope.ytd-video-renderer a"))).click()
WebDriverWait(driver, 10).until(EC.title_contains(j))
print(driver.current_url)
driver.quit()
That's one of the reasons you should never use JavaScript click, Selenium Webdriver is designed to stimulate as if a real user is able to click. Real user can't click an invisible element in the page but you can click through Javascript. If you search the element by that id video-title, it matches totally 53 videos. But I don't know which one you want to click. You may match that element by some other way(not by id).
I will give you an idea how to click that element but you need to find out the index first before you click.
driver.find_element_by_xpath("(//*[#id='video-title'])[1]").click
If the first one is invisible, then pass 2, [2] then three, figure out which one it's clicking the desired element. Or you may specify the exact element, we may try to locate that element by some other way.

Resources