i used this code to check splinter's clicking button option:
from splinter import Browser
with Browser() as browser:
# Visit URL
url = "http://www.google.com"
browser.visit(url)
browser.fill('q', 'splinter - python acceptance testing for web applications')
# Find and click the 'search' button
button = browser.find_by_name('btnG')
# Interact with elements
button.click()
if browser.is_text_present('splinter.readthedocs.org'):
print("Yes, the official website was found!")
else:
print("No, it wasn't found... We need to improve our SEO techniques")
and i got exception:
Element is not currently visible ans so may not be interacted.
waiting for the browser is not the solution (becuase i made sleep method for long time and still doesnt work).
this is sample code shown in https://splinter.readthedocs.org/en/latest/#sample-code , but is doesnt work for me
If you want to wait for an element to become invisible, you can use wait function:
wait = WebDriverWait(self.driver, 30)
wait.until(EC.invisibility_of_element_located((By.XX, "something")))
Related
I'm creating an Instagram bot but cannot figure out how to navigate to the next post.
Here is what I tried
#Attempt 1
next_button = driver.find_element_by_class_name('wpO6b ')
next_button.click()
#Attempt 2
_next = driver.find_element_by_class_name('coreSpriteRightPaginationArrow').click()
Neither of two worked and I get a NoSuchElementException or ElementClickInterceptedException . What corrections do I need to make here?
This is the button I'm trying to click(to get to the next post)
I have checked your class name coreSpriteRightPaginationArrow and i couldn't find any element with that exact class name. But I saw the class name partially. So it might help if you try with XPath contains as shown below.
//div[contains(#class,'coreSpriteRight')]
another xpath using class wpO6b. there are 10 elements with same class name so filtered using #aria-label='Next'
//button[#class='wpO6b ']//*[#aria-label='Next']
Try these and let me know if it works.
I have tried below code and it's clicking next button for 10 times
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
if __name__ == '__main__':
driver = webdriver.Chrome('/Users/yosuvaarulanthu/node_modules/chromedriver/lib/chromedriver/chromedriver') # Optional argument, if not specified will search path.
driver.maximize_window()
driver.implicitly_wait(15)
driver.get("https://www.instagram.com/instagram/");
time.sleep(2)
driver.find_element(By.XPATH,"//button[text()='Accept All']").click();
time.sleep(2)
#driver.find_element(By.XPATH,"//button[text()='Log in']").click();
driver.find_element(By.NAME,"username").send_keys('username')
driver.find_element(By.NAME,"password").send_keys('password')
driver.find_element(By.XPATH,"//div[text()='Log In']").click();
driver.find_element(By.XPATH,"//button[text()='Not now']").click();
driver.find_element(By.XPATH,"//button[text()='Not Now']").click();
#it open Instagram page and clicks 1st post and then it will click next post button for the specified range
driver.get("https://www.instagram.com/instagram/");
driver.find_element(By.XPATH,"//div[#class='v1Nh3 kIKUG _bz0w']").click();
for page in range(1,10):
driver.find_element(By.XPATH,"//button[#class='wpO6b ']//*[#aria-label='Next']" ).click();
time.sleep(2)
driver.quit()
As you can see, the next post right arrow button element locator is changing between the first post to other posts next page button.
In case of the first post you should use this locator:
//div[contains(#class,'coreSpriteRight')]
While for all the other posts you should use this locator
//a[contains(#class,'coreSpriteRight')]
The second element //a[contains(#class,'coreSpriteRight')] will also present on the first post page as well, however this element is not clickable there, it is enabled and can be clicked on non-first pages only.
As you can see on the picture below, the wp06b button is inside a lot of divs, in that case you might need to give Selenium that same path of divs to be able to access the button or give it a XPath.
It's not the most optimized but should work fine.
driver.find_element(By.XPATH("(.//*[normalize-space(text()) and normalize-space(.)='© 2022 Instagram from Meta'])[1]/following::*[name()='svg'][2]")).click()
Note that the XPath leads to a svg, so basically we are clicking on the svg element itself, not in the button.
I am using Selenium to simulate login with Chrome browser. The login page has Slider button which needs to be dragged to complete the login process.
The weird thing is that if I open the web page using driver.get(page). Then sliding verification code will always fail even I manually enter the username, pwd and drag the slider.
I tried to add user-agent but no help.
Is there any other way? I understand that we can add user-data to skip this part but I just want to figure it out first.
The slider verification code will display if you try to log in more than once. It seems that the web page just detect you are using the script to log in.
The error will be like:" ops, failed to verify. Please refresh again". Then I use driver.find_element_by_xpath("//*[#id='nocaptcha']/div/span/a").click() to refresh the slider.
Thanks in advance.
driver = webdriver.Chrome()
driver.get("https://login.taobao.com/member/login.jhtml?spm=a21bo.2017.754894437.1.5af911d95pqPfs&f=top&redirectURL=https%3A%2F%2Fwww.taobao.com%2F")
action = ActionChains(driver)
login()
def login():
driver.find_element_by_class_name("login-switch").click()
driver.find_element_by_id('TPL_username_1').clear()
driver.find_element_by_id('TPL_username_1').send_keys('xxx')
driver.find_element_by_id('TPL_password_1').clear()
driver.find_element_by_id('TPL_password_1').send_keys("xxx")
time.sleep(1.5)
# driver.find_element_by_id('J_SubmitStatic').click()
Slider()
def Slider():
#Sliding verification code
while True:
try:
slip=driver.find_element_by_xpath("//*[#id='nc_1_n1z']")
action.click_and_hold(slip).perform()
action.move_by_offset(150,0)
time.sleep(0.8)
action.move_by_offset(148,0)
action.release().perform()
time.sleep(2)
text = driver.find_element_by_xpath("//*[#id='nc_1__scale_text']/span")
if text.text.startswith("请在下方"):
print("Successful")
break
if text.text.startswith("请点击"):
print("Successful")
break
if text.text.startswith("请按住"):
print("Failed. Try again")
continue
except Exception:
##Error occurs, click the "Refresh" button to refresh the sliding verification code again
driver.find_element_by_xpath("//*[#id='nocaptcha']/div/span/a").click()
driver.find_element_by_id('J_SubmitStatic').click()
I'm using chromedriver + selenium to try to loop through a website with the same url structure for all their pages like so:
for i in range(1,3):
#iterate pages and get url
ureq = "https://somewebsite.com/#page=" + str(i)
driver.get(ureq.strip())
#create
soup = []
#main code here
try:
#Wait for page to load
WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.XPATH,"some element in the DOM")))
src = driver.page_source
#Parse page with bs
soup = bs(src, "lxml")
except TimeoutException:
print("Timed out")
driver.quit()
#main code
driver.quit()
The problem is when the loop fires a second time and the url changes to "#page=2", I can see the webpage and url has changed in the webdriver but the script just hangs. There is no timeout or error message, the script just freezes.
I've also tried placing a print statement before "webDriverWait" to see where the program hangs but that also doesn't fire. I think for some reason, the second get url request is the culprit.
Why is that, or is something else here the issue?
If you can obtain the url directly from the href attribute of link element, the url should work when you enter into address bar directly. But it's not always work, see the below explain for click event
But if you obtain the url from address bar after click on some element, you will fail to open the destination page by enter the url into address bar.
Because when you click on the element, there maybe a click event triggered which executed a javascript code in background to fetch data from backend or whatever.
For those background stuff, you can't trigger them by enter the url in address bar. So the safety way is to click on the element.
I know Angularjs App acted as such way in most time.
I need to use Python to open a web page, select options from drop-down lists and do some clicks all without making use of Selenium. Is there any in-built library in Python which can help me do this?
Have you tried Splinter
This is a simple example of browser interaction using it.
from splinter import Browser
with Browser() as browser:
# Visit URL
url = "http://www.google.com"
browser.visit(url)
browser.fill('q', 'splinter - python acceptance testing for web applications')
# Find and click the 'search' button
button = browser.find_by_name('btnG')
# Interact with elements
button.click()
if browser.is_text_present('splinter.readthedocs.io'):
print("Yes, the official website was found!")
else:
print("No, it wasn't found... We need to improve our SEO techniques")
currently i'm writing a web scraper that will work in infinite loop. It gets a page, searches for some buttons and clicks one of them. But sometimes it doesn't! I save a screenshot in case of some fail and it showed me that page didnt changed after button clicked.
driver.find_element_by_xpath('//input[#name = "btn"]').click()
time.sleep(3)
I have bypassed this with a loop checking does we see that element still.
while driver.find_elements_by_xpath('//input[#name = "Submit"]') != []:
driver.find_element_by_xpath('//input[#name = "Submit"]').click()
But hope to find a root cause of this. What it could be?
I also faced a similar problem with my application. Clicking the element through action class worked for me.
Here is the sample code in Java:
WebElement webElement = driver.findElement(By.id("Your ID Here"));
Actions builder = new Actions(driver);
builder.moveToElement(webElement).click(webElement);
builder.perform();
If clicking with action class does not work, you can also try clicking element by Javascript.
WebElement webElement = driver.findElement(By.id("Your ID here"));
JavascriptExecutor executor = (JavascriptExecutor) driver;
executor.executeScript("arguments[0].click();", webElement);