How does Selenium click on elements that are 50% on screen and 50% not on screen?
element’s in-view center point
As per the WebDriver W3C Specification an element’s in-view center point is the origin position of the rectangle that is the intersection between the element’s first DOM client rectangle and the initial viewport.
Given an element that is known to be in view, it can be calculated this way:
- Let rectangle be the first element of the DOMRect sequence returned by calling getClientRects on element.
- Let left be max(0, min(x coordinate, x coordinate + width dimension)).
- Let right be min(innerWidth, max(x coordinate, x coordinate + width dimension)).
- Let top be max(0, min(y coordinate, y coordinate + height dimension)).
- Let bottom be min(innerHeight, max(y coordinate, y coordinate + height dimension)).
- Let x be floor((left + right) ÷ 2.0).
- Let y be floor((top + bottom) ÷ 2.0).
- Return the pair of (x, y).
An element is in view if it is a member of its own pointer-interactable paint tree, given the pretense that its pointer events are not disabled.
Element Click
As per the documentation the Element Click command scrolls into view the element if it is not already pointer-interactable, and clicks its in-view center point.
Note: If the element’s center point is obscured by another element, an element click intercepted error is returned. If the element is outside the viewport, an element not interactable error is returned.
Solution
In such cases there are two possible solutionas follows:
You can induce WebDriverWait setting the expected_conditions as
element_to_be_clickable()
. So effectively your line of code will be:WebDriverWait(browser, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, ".reply-button"))).click()
You can use
move_to_element(to_element)
andclick(on_element=None)
method respectively. So effectively your line of code will be:ActionChains(driver).move_to_element(element).click(element).perform()
Reference
You can find a relevant discussion in selenium.common.exceptions.ElementClickInterceptedException: Message: element click intercepted: Element is not clickable with Selenium and Python
Selenium - element click intercepted: Element is not clickable at point
That page can be scraped without the overheads and complexities of Selenium: you can use requests/bs4 instead:
import requests
from bs4 import BeautifulSoup
headers= {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36'}
s = requests.Session()
s.headers.update(headers)
for x in range(1, 10): ## pick up the range here
r = s.get(f'https://g1.globo.com/ciencia/index/feed/pagina-{x}.ghtml', headers=headers)
soup = BeautifulSoup(r.text, 'html.parser')
news = soup.select('div.feed-post-body')
for n in news:
title = n.select_one('a')
print(title.get_text(strip=True))
This returns the titles, but you can select any other elements:
O supertelescópio que vai investigar a origem das estrelas
Pesquisa liga beijos na Idade do Bronze a origem da herpes labial
Os animais que fazem arte - e podem ter vantagens evolutivas com isso
O que é a hipótese de Gaia, que defende que a Terra 'está viva'
Septuagenárias e rebeldes
If you are keen on using Selenium, then bear in mind that page will load the first three pages worth of news by detecting scrolling to the bottom of the page, and then you can click the button to take you to page 4. You also need to dismiss the cookie button, and to wait for the heavy javascript adverts from page to load.You also need to account for the actual url of the page changing on click, and to redefine the elements.
Message: element click intercepted: Element span ... /span is not clickable at point (657, 594). Other element would receive the click with Selenium
The LOAD MORE element is a Angular element so to click on it 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.nvidia.com/en-us/shop/geforce/?page=1&limit=9&locale=en-us")
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "div#cookiePolicy-btn-close>span"))).click()
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "input.buy-link.load-more-btn[value='LOAD MORE']"))).click()Using
XPATH
:driver.get("https://www.nvidia.com/en-us/shop/geforce/?page=1&limit=9&locale=en-us")
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//div[@id='cookiePolicy-btn-close']/span"))).click()
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//input[@class='buy-link load-more-btn' and @value='LOAD MORE']"))).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 ECBrowser Snapshot:
How to dynamically check table is available ( waiting ) using Selenium instead of having a fixed sleep
With the following instance of WebDriverWait
:
var wait = new WebDriverWait(Driver, TimeSpan.FromMilliseconds(500);
Once you click and enable the rows, to wait for the rows to exist there can be two approaches:
As there is some ambiguity regarding the number of rows (no row, 1 row or multiple rows), a safer approach would be to probe the Displayedness of the MyTable element as you mentioned in your comment. The element displayed algorithm is a boolean state where
true
signifies that the element is displayed and false signifies that the element is not displayed.TcAssert.WaitUntilTrue(() => this.Page.MyTable.Displayed);
The other approach would be to wait for the Visibility of the element MyTable. The visibility of an element is guided by what is perceptually visible to the human eye. and is based on crude approximations about an element's nature and relationship in the tree. An element is in general to be considered visible if any part of it is drawn on the canvas within the boundaries of the viewport.
Element Out Of The ScreenShot error while taking screenshot from whatsapp using selenium and VBA
As you are seeing Element Out Of The ScreenShot
error presumably you may need to scroll the element within the Viewport before taking the screenshot as follows:
Set element = bot.FindElementByXPath("//span[@data-testid='status-dblcheck']")
element.ScrollIntoView().TakeScreenshot().Copy
Sheets(1).Cells(5, 5).PasteSpecial
Related Topics
What Do <Form Action="#"> and <Form Method="Post" Action="#"> Do
How to Stretch Flex Child to Fill Height of the Container
Twitter Bootstrap Multiple Accordions But Only One Open Panel at a Time
Do HTML Websockets Maintain an Open Connection for Each Client? Does This Scale
How to Show Multiline Text in a Table Cell
R Web Scraping Across Multiple Pages
How to Escape HTML in Node.Js Ejs View
How to Determine What Technology a Website Is Built On
Extra Space Under Textarea, Differs Along Browsers
Does the <Li> Tag in HTML Have an Ending Tag
Chrome Rendering Issue. Fixed Position Anchor with Ul in Body
With a Browser, How to Know Which Decimal Separator Does the Operating System Use
How to Create a Polygon Shape Div
Input Type=Password, Don't Let Browser Remember the Password