Selenium changing html on a page with python - python

<div id="modalContent" style="opacity: 1; top: 35%;">
</div>
Say I want to delete this on everytime I go to a particular website.
driver = webdriver.Chrome()
driver.get("some url")
#driver.removeelement("""<div id="modalContent" style="opacity: 1; top: 35%;">
#</div>""")
Is there a way to do this?

To do this, you should execute some javascript on the DOM element. Here is how I would do it.
driver.execute_script("document.getElementById('modalContent').remove()")
Should work.

Related

ElementClickInterceptedException in Selenium when the element is only partially obscured

I'm using Selenium for testing. I want to click on an element. The element is very much clickable and visible, but it happens that the middle point of the element is obscured, causing the error.
Here is a MCVE:
HTML code (link to demo):
<style>
button {
width: 90vw;
height: 90vh;
position: fixed;
top: 5vh;
left: 5vw;
}
.cover {
background: grey;
opacity: 0.3;
width: 80vw;
height: 80vh;
position: fixed;
top: 10vh;
left: 10vw;
}
</style>
<button onclick="alert('hi');">
Click me!
</button>
<div class="cover">
I'm in the way!
</div>
Python selenium code:
from selenium import webdriver
driver = webdriver.Chrome()
driver.implicitly_wait(10)
driver.get("https://blissfulpreciouslanservers--five-nine.repl.co/")
button = driver.find_element_by_tag_name("button")
button.click()
Result:
selenium.common.exceptions.ElementClickInterceptedException: Message: element click intercepted: Element <button onclick="alert('hi');">...</button> is not clickable at point (451, 450). Other element would receive the click: <div class="cover">...</div>
This seems like a rather sad limitation of Selenium. The button is clickable, just not at all points. I don't want to have to fiddle with scrolling and coordinates.
There are many similar questions about the exception in general, e.g:
Can not click on a Element: ElementClickInterceptedException in Splinter / Selenium
Selenium can't click element because other element obscures it
Element not clickable since another element obscures it in python
However the questions are never specifically about an element that is only partially obscured, so I haven't managed to find a proper answer to my own question. The answers to other questions generally fall into these categories:
Wait until the element is clickable. Doesn't apply here.
Use action chains, e.g. ActionChains(driver).move_to_element(button).click().perform(). This doesn't help because .move_to_element() moves to the middle of the element.
Use JavaScript to perform the click. It seems like I might have to resort to this, but it's very unsatisfactory. I still want to validate that the element is clickable at least somewhere and not bypass all checks.
Have you tried to add a class to your button and then search for the class? For example:
<button class="btn" onclick="alert('hi');">
Click me!
</button>
Then use the following to find and click on that button:
driver.findElement(By.className("btn")).click();
similar to this stack overflow response by alecxe

Cannot click on button with selenium

I have the following website where I want to click on the button "SKIP THIS AD" that popup after waiting x seconds.
My code is as follows:
import selenium
from selenium import webdriver
driver = webdriver.Chrome()
driver.get('http://festyy.com/wpixmC')
sleep(10)
driver.find_element_by_xpath('/html/body/div[3]/div[1]/span[5]').click()
However, when I inspect the element I don't see a connected link to be clicked. In addition, I get
ElementClickInterceptedException: Message: element click intercepted: Element <span class="skip-btn
show" id="skip_button" style="cursor: pointer">...</span> is not clickable at point (765, 31). Other
element would receive the click: <div style="position: absolute; top: 0px; left: 0px; width: 869px;
height: 556px; z-index: 2147483647; pointer-events: auto;"></div>
Somehow it seems that everything is redirected to the larger class? How can I overcome this? When I try to copy the xpath I get also only the following: /div
Thanks in advance
It seems that the error that you receive ('element click intercepted') is due to the fact that there is a div that is placed on page load, that takes up the whole page, preventing Selenium from clicking on the skip button.
Therefore you have to remove that div first and then run this:
driver.find_element_by_xpath('/html/body/div[3]/div[1]/span[5]').click()
You can remove the div by running some JavaScript code as follows:
driver.execute_script("""
var badDivSelector = document.evaluate('/html/body/div[7]',
document.documentElement, null, XPathResult.FIRST_ORDERED_NODE_TYPE,
null);
if (badDivSelector) {
var badDiv = badDivSelector.singleNodeValue;
badDiv.parentNode.removeChild(badDiv);
}
""")
The code above finds the full page div (identified by xpath) and removes it from the page.
Your final code should look something like this:
import selenium
from selenium import webdriver
from time import sleep
driver = webdriver.Chrome()
driver.get('http://festyy.com/wpixmC')
sleep(10)
driver.execute_script("""
var badDivSelector = document.evaluate('/html/body/div[7]',
document.documentElement, null, XPathResult.FIRST_ORDERED_NODE_TYPE,
null)
if (badDivSelector) {
var badDiv = badDivSelector.singleNodeValue;
badDiv.parentNode.removeChild(badDiv);
}
""")
driver.find_element_by_xpath('/html/body/div[3]/div[1]/span[5]').click()
....

Can't Click Element

I am trying to make click for this element,
but getting error like
>> ElementClickInterceptedException: Message: element click intercepted: Element is not clickable at point (271, 705)
element = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, '//*[#action="/battle/"]/div/input[2]')))
element.click();
This is not helping also getting timeoutexception. I think element kinda covered
with:
[driver.find_element_by_xpath('//[#action="/battle/"]/div/input[2]').click()]
<form action="/battle/" method="post" name="4416" id="4416" onsubmit="get('/battle/', '', this); disableSubmitButton(this); return false;"><div class="battleView" style="float:left; width:65%;"><h3 class="heading-maroon no-right-border-rad margin-right-2">Attack Results</h3><table cellpadding="0" cellspacing="0" style="width: 80%; text-align: center; margin: 0 auto;">
...
</tbody></table><input type="hidden" class="button-maroon button-small" name="action" value="attack">
<input type="submit" class="button-maroon button-small" value=" Attack .. "></div>
</form>
It looks like it's showing the X/Y coordinates (271,705) in the error message. I'd try a macro product like AppRobotic to look up the X/Y coordinates of elements that you have issues finding with XPATH, moving the mouse, or sending keystroke TABS, and clicking it. A simple example:
import win32com.client
x = win32com.client.Dispatch("AppRobotic.API")
from selenium import webdriver
# navigate to Yahoo
driver = webdriver.Firefox()
driver.get('https://www.yahoo.com')
# sleep 1 second
x.Wait(1000)
link = driver.find_element_by_link_text('Mail')
if len(link) > 0
link[0].click()
else
x.Wait(3000)
# use UI Item Explorer to get X,Y coordinates of Mail box
x.MoveCursor(271,705)
# click inside Search box
x.MouseLeftClick
# could also try tabbing over and pressing Enter
x.Type("{TAB}")
x.Type("{ENTER}")
Another idea is to try scrolling to the element with Selenium first:
from selenium.webdriver.common.action_chains import ActionChains
element = driver.find_element_by_xpath('//[#action="/battle/"]/div/input[2]')
actionchains = ActionChains(driver)
actionchains.move_to_element(element).perform()

Python - Unable to click button in Selenium under tooltip, webpage throws request error

This is the element I am trying to click (the info button). It's located on pokemongomap.info, and you can see it in chrome devtools under any pokestop or gym.
<a href="#" target="_self" class="tooltip tooltipstered" id="infoboxmoreinfobtnbind" style="display: inline;">
<div id="infoboxmoreinfohit"></div>
<div id="infoboxmoreinfobtn" class="infoboxbtn">
<i class="fa fa-info-circle" aria-hidden="true" style="color: rgb(57, 135, 140);">
</i>
</div>
</a>
I am unable to click it using ActionChains, element.click(), or anything else. If I try to click it using either of those methods, I get a request error from the website. Can anyone help me? Here is some of the code I have tried.
wait = WebDriverWait(driver, 10)
actions = Actions(driver)
element = wait.until(EC.element_to_be_clickable((By.ID, 'infoboxmoreinfobtnbind')))
#element = wait.until(EC.element_to_be_clickable((By.XPATH, '//i[#class="fa fa-info-circle"]'))) also throws error when clicked
#actions.move_to_element(element).click(element).perform() doesn't work either.
action = actions.move_to_element(element)
action.click()
action.perform()
I've also tried clicking on other infobox elements using ActionChains or element.click(), all of them either do nothing or give a request error or aren't clickable at the point.
As a last resort, you can use JS with execute_script:
wait = WebDriverWait(driver, 10)
actions = Actions(driver)
element = wait.until(EC.element_to_be_clickable((By.ID, 'infoboxmoreinfobtnbind')))
driver.execute_script("$(arguments[0]).click();", element)
This is not a humanlike automation but it should do the job...
Hope this helps you!

How to make click using Selenium?

I got stuck with extracting href="/ttt/play" from the following HTML code.
<div class="collection-list-wrapper-2 w-dyn-list">
<div class="w-dyn-items">
<div typeof="ListItem" class="collection-item-2 w-clearfix w-dyn-item">
<div class="div-block-38 w-hidden-medium w-hidden-small w-hidden-tiny"><img src="https://global-uploads.webflow.com/59cf_home.svg" width="16" height="16" alt="Official Link" class="image-28">
<a property="url" href="/ttt/play" class="link-block-4 w-inline-block">
<div class="row-7 w-row"><div class="column-10 w-col w-col-2"><img height="25" property="image" src="https://global-fb0edc0001b4b11d/5a77ba9773fd490001ddaaaa_play.png" alt="Play" class="image-23"><h2 property="name" class="heading-34">Play</h2><div style="background-color:#d4af37;color:white" class="text-block-28">GOLD LEVEL</div><div class="text-block-30">HOT</div><div style="background-color:#d4af37;color:white" class="text-block-28 w-condition-invisible">SILVER LEVEL</div></div></div></a>
</div>
<div typeof="ListItem" class="collection-item-2 w-clearfix w-dyn-item">
This is my code in Python:
driver = webdriver.PhantomJS()
driver.implicitly_wait(20)
driver.set_window_size(1120, 550)
driver.get(website_url)
tag = driver.find_elements_by_class_name("w-dyn-item")[0]
tag.find_element_by_tag_name("a").click()
url = driver.current_url
print(url)
driver.quit()
When I print url using print(url), I want to see url equal to website_url/ttt/play, but instead of it I get website_url.
It looks like the click event does not work and the new link is not really opened.
When using .click() it must be "visible" (you using PhantomJS) and not hidden, in a drop-down for example.
Also make sure the page is completely loaded.
As i see it you have two options:
Ether use selenium to revile it, and then click.
Use java script to do the actual click
I strongly suggest to click with javascript, its much faster and more reliable.
Here is a little wrapper to make things easier:
def execute_script(driver, xpath):
""" wrapper for selenium driver execute_script
:param driver: selenium driver
:param xpath: (str) xpath to the element
:return: execute_script result
"""
execute_string = "window.document.evaluate('{}', document, null, 9, null).singleNodeValue.click();".format(xpath)
return driver.execute_script(execute_string)
The wrapper basically implement this technique to click on elements with javascript.
then in your selenium script use the wrapper like so:
execute_script(driver, element_xpath)
you can also make it more general to not only do clicks, but scrolls and other magic..
ps. in my example i use xpath, but you can also use css_path basically, what-ever runs in javascript.

Categories

Resources