I'm trying to click the next button (>) and then repeat until the last page is reached. I've tried searching for solutions from similar questions but I couldn't figure out what's wrong/make it work.
Here is my code, thank you!
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait as Wait
from selenium.webdriver.support.ui import WebDriverWait
from selenium.common.exceptions import TimeoutException
driver = webdriver.Chrome("C:/Users/krish/Desktop/chromedriver_win32/chromedriver.exe")
driver.get('https://www.cnbcindonesia.com/tag/pasar-modal')
wait = WebDriverWait(driver,30)
while True:
try:
element = wait.until(EC.element_to_be_clickable((By.XPATH, "//a[#class = 'icon icon-angle-right']/i")))
if (element != 0):
element.click()
except TimeoutException as ex:
break
Figured it out, finally works by using execute_script() method
while True:
try:
time.sleep(2)
driver.execute_script("arguments[0].click();", WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, ".icon.icon-angle-right"))))
except NoSuchElementException:
break
Thank you all for your answers
Your xpath looks incorrect, please try the below
Xpath
//i[#class='icon icon-angle-right']
CSS Selector
.icon.icon-angle-right
There are multiple approaches to address this issue and a couple of them are as follows:
As you intent to invoke click() you need to induce WebDriverWait in conjunction with the WebDriverWaitWebDriverWait 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, ".icon.icon-angle-right"))).click()
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//i[#class='icon icon-angle-right']"))).click()
Incase the error ...another element obscures it... still persists first you need to induce WebDriverWait inconjunction with the expected_conditions for the invisibility_of_element() of the blocking element as follows:
Using CSS_SELECTOR:
WebDriverWait(driver, 20).until(EC.invisibility_of_element((By.CSS_SELECTOR, ".icon.icon-angle-right")))
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, ".icon.icon-angle-right"))).click()
Using XPATH:
WebDriverWait(driver, 20).until(EC.invisibility_of_element((By.XPATH, "//i[#class='icon icon-angle-right']")))
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//i[#class='icon icon-angle-right']"))).click()
If the issue still persists you can use the execute_script() method as follows:
Using CSS_SELECTOR:
WebDriverWait(driver, 20).until(EC.invisibility_of_element((By.CSS_SELECTOR, ".icon.icon-angle-right")))
driver.execute_script("arguments[0].click();", WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, ".icon.icon-angle-right"))))
Using XPATH:
WebDriverWait(driver, 20).until(EC.invisibility_of_element((By.XPATH, "//i[#class='icon icon-angle-right']")))
driver.execute_script("arguments[0].click();", WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//i[#class='icon icon-angle-right']"))))
Note: : You have to import below
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
You can do it easy with playwright
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.webkit.launch(headless=False)
baseurl = "https://www.cnbcindonesia.com/tag/pasar-modal"
page = browser.new_page()
page.goto(baseurl)
next_page = page.wait_for_selector("//i[#class='icon icon-angle-right']")
next_page.click()
browser.close()
Also if you want to paginate, you can do it with changing just URL param.
Go to page 87: https://www.cnbcindonesia.com/tag/pasar-modal/87?kanal=&tipe=
Related
I would like to scrape data from this page: https://www.investing.com/equities/nvidia-corp-financial-summary.
There are two buttons that I'd like to click:
Accept button.
Checking the XPath of the button:
XPath = //*[#id="onetrust-accept-btn-handler"]
Replicating the steps performed here: Clicking a button with selenium using Xpath doesn't work
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
wait = WebDriverWait(driver, 5)
link= wait.until(EC.element_to_be_clickable((By.XPATH, "//*[#id="onetrust-accept-btn-handler")))
I got the error: SyntaxError: invalid syntax
Annual button
there is a toggle between Annual and Quarterly (default is quarterly)
XPath is //*[#id="leftColumn"]/div[9]/a[1]
wait.until(EC.element_to_be_clickable((By.XPATH, "//*[#id="leftColumn"]/div[9]/a[1]")))
also returned invalid Syntax.
Updated Code
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
company = 'nvidia-corp'
driver = webdriver.Chrome(path)
driver.get(f"https://www.investing.com/equities/{company}-financial-summary")
wait = WebDriverWait(driver, 2)
accept_link= wait.until(EC.element_to_be_clickable((By.XPATH, '//*[#id="onetrust-accept-btn-handler"]')))
accept_link.click()
scrollDown = "window.scrollBy(0,500);"
driver.execute_script(scrollDown)
#scroll down to get the page data below the first scroll
driver.maximize_window()
time.sleep(10)
wait = WebDriverWait(driver, 2)
scrollDown = "window.scrollBy(0,4000);"
driver.execute_script(scrollDown)
#scroll down to get the page data below the first scroll
try:
close_popup_link= wait.until(EC.element_to_be_clickable((By.XPATH,'//*[#id="PromoteSignUpPopUp"]/div[2]/i')))
close_popup_link.click()
except NoSuchElementException:
print('No such element')
wait = WebDriverWait(driver, 3)
try:
annual_link = wait.until(EC.element_to_be_clickable((By.XPATH, '//*[#id="leftColumn"]/div[9]/a[1]')))
annual_link()
# break
except NoSuchElementException:
print('No element of that id present!')
The first accept button was successfully clicked,
but clicking the Annual button returns Timeout Exception error.
Annual button
At least for me I saw we need to use another locator to access that element.
I used scrolling until I can click that element.
The following code works for me:
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
options = Options()
options.add_argument("--start-maximized")
s = Service('C:\webdrivers\chromedriver.exe')
driver = webdriver.Chrome(options=options, service=s)
company = 'nvidia-corp'
wait = WebDriverWait(driver, 5)
driver.get(f"https://www.investing.com/equities/{company}-financial-summary")
try:
wait.until(EC.element_to_be_clickable((By.XPATH, '//*[#id="PromoteSignUpPopUp"]/div[2]/i'))).click()
except:
pass
while True:
try:
wait.until(EC.element_to_be_clickable((By.XPATH, "//div[#class='float_lang_base_1']//a[#data-ptype='Annual']"))).click()
break
except:
driver.execute_script("window.scrollBy(0, arguments[0]);", 1000)
You need to take care of a couple of things here as follows:
If you are supplying the xpath within double qoutes, i.e. "..." then the attribute values needs to be within single quotes, i.e. '...'
Similarly, if you are supplying the xpath within single qoutes, i.e. '...' then the attribute values needs to be within double quotes, i.e. "..."
This take care of both the SyntaxError: invalid syntax
Effectively, the lines of code will be:
link= wait.until(EC.element_to_be_clickable((By.XPATH, "//*[#id='onetrust-accept-btn-handler')))
and
wait.until(EC.element_to_be_clickable((By.XPATH, "//*[#id='leftColumn']/div[9]/a[1]")))
Solution
To click on the clickable elements you need to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following locator strategies:
Clicking on I Accept:
Using CSS_SELECTOR:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button#onetrust-accept-btn-handler"))).click()
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//button[#id='onetrust-accept-btn-handler']"))).click()
Clicking on Annual:
Using CSS_SELECTOR:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "a[data-ptype='Annual']"))).click()
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//a[#data-ptype='Annual']"))).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
What can I do to replace find_element_css_selector in Selenium Python to click on a specific onclick value
(javascript:unitsSelectUnit(1))
The browser is google chrome
browser.get("http://eatsmart.housing.illinois.edu/NetNutrition/46#")
browser.find_element_css_selector("a[onclick*=javascript:unitsSelectUnit(1);]").click()
html = browser.page_source
time.sleep(2)
print(html)
# close web browser
browser.close()
To click on the element with text as Ikenberry Dining Center (IKE) you need to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following Locator Strategies:
Using LINK_TEXT:
driver.get("http://eatsmart.housing.illinois.edu/NetNutrition/46#")
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.LINK_TEXT, "New"))).click()
Using CSS_SELECTOR:
driver.get("http://eatsmart.housing.illinois.edu/NetNutrition/46#")
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "a[onclick*='unitsSelectUnit(1)']"))).click()
Using XPATH:
driver.get("http://eatsmart.housing.illinois.edu/NetNutrition/46#")
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//a[contains(#onclick, 'unitsSelectUnit(1)')]"))).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:
This CSS_SELECTOR
a[onclick*=javascript:unitsSelectUnit(1);]
that you are using in your code is wrong. Basically, you are missing ''
CSS_SELECTOR follow the below syntax:
node_name[attribute_name = 'attribute_value']
You can cross verify as well by following the below steps:
Steps to check:
Press F12 in Chrome -> go to element section -> do a CTRL + F -> then paste the css selector and see, if your desired element is getting highlighted with 1/1 matching node.
This a[onclick*=javascript:unitsSelectUnit(1);] won't match anything, where as a[onclick*='javascript:unitsSelectUnit(1);'] will match Ikenberry Dining Center (IKE) node.
Now If you want to click on it, please use the below code:
Code:
browser.maximize_window()
wait = WebDriverWait(browser, 30)
browser.get("http://eatsmart.housing.illinois.edu/NetNutrition/46#")
try:
btn = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "a[onclick*='javascript:unitsSelectUnit(1);']")))
btn.click()
except:
print("Could not click on button")
pass
Imports:
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
How do I paginate to the next page in selenium python?
Code trials:
import os,json,requests, time
from pprint import pprint
from selenium import webdriver
import csv
driver = webdriver.Chrome()
driver.get('https://www.ebay.co.uk/b/Cordless-Drills/184655/bn_9863722?rt=nc&_dmd=1')
time.sleep(0.5)
links = driver.find_elements_by_xpath('//div[#class="s-item__wrapper clearfix"]//a[#class="s-item__link"]')
for link in links:
print(link.get_attribute('href'))
To paginate to the next page you need 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://www.ebay.co.uk/b/Cordless-Drills/184655/bn_9863722?rt=nc&_dmd=1')
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button#gdpr-banner-accept[aria-label='Accept privacy terms and settings']"))).click()
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "li.ebayui-pagination__li.ebayui-pagination__li--selected +li > a"))).click()
Using XPATH:
driver.get('https://www.ebay.co.uk/b/Cordless-Drills/184655/bn_9863722?rt=nc&_dmd=1')
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//button[#id='gdpr-banner-accept']"))).click()
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//li[#class='ebayui-pagination__li ebayui-pagination__li--selected']//following::li[1]/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
Browser Snapshot:
driver = webdriver.Chrome()
driver.get("https://twitter.com/i/flow/signup")
driver.implicitly_wait(10)
setname = driver.find_element_by_name("name")
setname.click()
setname.send_keys("NAME SURNAME")
driver.implicitly_wait(10)
emailoption = driver.find_element_by_xpath("/html/body/div/div/div/div[2]/main/div/div/div/div[2]/div[2]/div/div[4]") #selenium can not find the element XPATH (I found it manually)
emailoption.click() #need to click in the element :)
driver.close()
Selenium can not find the element XPATH (I found it manually) ---Use email instead---.
Tried to find this element other ways... same result.
Maybe there is another way to click in it?
Add a Selenium expected condition (element_to_be_clickable) to your code and use relative XPath. To input your name, click on the link and input your email, you can use :
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//input[#autocomplete='name']"))).send_keys('name')
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//input[#autocomplete='tel']/following::span[1]']"))).click()
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//input[#autocomplete='email']"))).send_keys('email')
Be sure to add the following imports :
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
If it still fails you can use Javascript :
name = "your_name"
email = "your_email"
elem = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//input[#autocomplete='name']")))
self.driver.execute_script("arguments[0].setAttribute('value', '" + name +"')", elem)
elem2 = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//input[#autocomplete='tel']/following::span[1]']")))
self.driver.execute_script("arguments[0].click();", elem2)
elem3 = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//input[#autocomplete='email']")))
self.driver.execute_script("arguments[0].setAttribute('value', '" + email +"')", elem3)
The elements within Twitter Signup page are React elements. So to send a character sequence to the 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://twitter.com/i/flow/signup")
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "input[name='name']"))).send_keys("Manoel Augusto")
Using XPATH:
driver.get("https://twitter.com/i/flow/signup")
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//input[#name='name']"))).send_keys("Manoel Augusto")
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:
Reference
You can find a detailed relevant discussion in:
selenium.common.exceptions.NoSuchElementException: Message: Unable to locate element error sending text to Email field in twitter with Selenium Python
Try below code -
from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time
driver = webdriver.Chrome()
action = ActionChains(driver)
wait = WebDriverWait(driver, 20)
driver.get('https://twitter.com/i/flow/signup')
time.sleep(5) # Add wait here so that twitter login page will load.
NameElement = driver.find_element_by_xpath("//input[#name='name']")
action.move_to_element(NameElement).click().perform()
NameElement.send_keys("Hello")
EmailOption = driver.find_element_by_xpath('//span[text()="Use email instead"]/parent::div')
EmailOption.click()
driver.close()
I ran your code on my computer and It worked perfectly, finding the email option and clicking on it. I also found the same xpath you provided, have you tried running your program in a debugger, and What IDE/text editor are you using? Also, are you leaving the window open when you are running your program? If you close the window it will throw an error. If you have any more details on what is happening when you run your code let me know I'd love to help.
Try below code :
wait = WebDriverWait(driver, 10)
driver.get("https://twitter.com/i/flow/signup")
driver.implicitly_wait(10)
setname = driver.find_element_by_name("name")
setname.click()
setname.send_keys("NAME SURNAME")
driver.implicitly_wait(10)
element1 = wait.until(EC.element_to_be_clickable((By.XPATH, "//body//div[4]")))
element1.click()
Output::
I want to input password to the box with Selenium but it returns selenium.common.exceptions.WebDriverException: Message: element not interactable
My python script:
from selenium import webdriver
browser = webdriver.Chrome(r'c:\chromedriver.exe')
url = 'https://creis.fang.com/'
browser.get(url)
browser.find_element_by_id('cnotp').send_keys('123456')
If I run the script, the above error appears. However, if I type line by line in the console. Then there is no error.
What should I do?
Thanks.
To send a character sequence within the password field using Selenium you have to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following solutions:
Using CSS_SELECTOR:
driver.get("https://creis.fang.com/")
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "input.loginipt.fl#cnotp"))).click()
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "input.loginipt.fl#cnpassword"))).send_keys("Chan")
Using XPATH:
driver.get("https://creis.fang.com/")
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//input[#class='loginipt fl' and #id='cnotp']"))).click()
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//input[#class='loginipt fl' and #id='cnpassword']"))).send_keys("Chan")
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:
Maybe you should try to do it "by step". First select the element, clear its value then do the send_key stuff...
element = browser.find_element_by_id('cnotp')
element.clear()
element.send_keys('123456')
Hope it helps !
Wailt always whenever there is a url change.
from selenium import webdriver
driver = webdriver.Chrome() # Change
driver.get('https://creis.fang.com/')
element = WebDriverWait(driver, 60).until(
EC.presence_of_element_located((By.ID, "cnotp"))
)
element.clear()
element.send_keys("123456")
If it does not work, use js_executor
element = WebDriverWait(driver, 60).until(
EC.presence_of_element_located((By.ID, "cnotp"))
)
driver.execute_script("document.getElementById('cnotp').click()")
driver.execute_script("arguments[0].setAttribute('value', '123456')", element);