I'd like to scrape the second page of this Power BI dashboard. In order to get the data from a specific month, I must set the date in a slicer:
However, when I expand a year element to display the month elements, some are out of sight and thus unrendered. Therefore, I must scroll down the slicer. However, I have yet to find a method that works.
Before I give further details, this is how I get to the desired page and expand the slicer:
# Selenium resources
from selenium import webdriver
from selenium.webdriver.edge.options import Options
from selenium.webdriver.common.by import By
# Driver service
driver_file = r"d:\dev\selenium\msedgedriver.exe" # or whatever driver is available
service = Service(driver_file)
# Browser options
options = Options()
options.add_experimental_option("detach", True)
options.add_experimental_option("excludeSwitches", ["enable-automation"])
options.add_experimental_option("useAutomationExtension", False)
options.add_argument("--disable-blink-features=AutomationControlled")
options.add_argument("--inprivate")
# Open browser
driver = webdriver.Edge(service = service, options = options)
# Get URL
url = "https://app.powerbi.com/view?r=eyJrIjoiZWIzNDg3YzUtMGFlMC00MzdmLTgzOWQtZThkOWExNTU2NjBlIiwidCI6IjQ0OTlmNGZmLTI0YTYtNGI0Mi1iN2VmLTEyNGFmY2FkYzkxMyJ9"
driver.get(url)
# Proceed to next page
driver.find_element(By.XPATH, '//button[@aria-label="Próxima Página"]/i').click()
# Open date slicer
driver.find_element(By.XPATH, '//div[@class="slicer-dropdown-menu"]/i')
# Expand month options for a year, e.g. 2024
(driver \
.find_element(By.XPATH, '//div[@class="slicerItemContainer" and @title="2024"]/div[@class="expandButton"]') \
.click())
And so:
But as it stands, I cannot select any month beyond March.
The slicer doesn't budge when I execute a JavaScript snippet:
slicer_container = driver.find_element(By.XPATH, '//div[@class="slicerContainer"]')
driver.execute_script("arguments[0].scrollTop = arguments[0].scrollHeight", slicer_container)
Trying to scroll down with keys throws an ElementNotInteractableException:
from selenium.webdriver.common.keys import Keys
scroll_container = driver.find_element(By.CLASS_NAME, "scroll-bar")
scroll_container.send_keys(Keys.DOWN)
ElementNotInteractableException: Message: element not interactable (Session info: MicrosoftEdge=135.0.3179.85)
ActionChains yield the same error:
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.keys import Keys
actions = ActionChains(driver)
actions.move_to_element(scroll_bar).click().send_keys(Keys.PAGE_DOWN).perform()
ElementNotInteractableException: Message: element not interactable (Session info: MicrosoftEdge=135.0.3179.85)
And finally, I've tried to use a style transform – but it only manages to scroll the element visually and doesn't trigger the rendering of the next slicer items.
visible_group = driver.find_element(By.CLASS_NAME, 'visibleGroup')
driver.execute_script(f'arguments[0].style.transform = "translateY(-60px)";', visible_group)
All told, I have no idea what to do. Any ideas? Please feel free to ask for further details.
ActionChains
with scrolling via move_to_element
, click_and_hold
, and move_by_offset,
It is key when interacting with complex UIs like Power BI embedded dashboards or custom dropdowns.
move_to_element(): Ensures you're hovering over the correct scrollable area.
click_and_hold(): Simulates a mouse drag. Without this, the scroll may not happen.
move_by_offset(0, 100): Moves the view vertically (down). Can be adjusted for a larger scroll.
release(): Finishes the simulated mouse action.
Here's a working code that I've tested:
# ===== IMPORTS =====
from time import sleep
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
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 import ActionChains
# ===== SETUP OPTIONS =====
options = Options()
options.add_argument("--start-maximized")
options.add_experimental_option("excludeSwitches", ["enable-automation"])
options.add_argument("force-device-scale-factor=0.95")
driver = webdriver.Chrome(options=options)
wait = WebDriverWait(driver, 10)
def report_analyser(year: str, month: int) -> None:
url = "https://app.powerbi.com/view?r=eyJrIjoiZWIzNDg3YzUtMGFlMC00MzdmLTgzOWQtZThkOWExNTU2NjBlIiwidCI6IjQ0OTlmNGZmLTI0YTYtNGI0Mi1iN2VmLTEyNGFmY2FkYzkxMyJ9"
driver.get(url)
# Wait for the page navigation element
wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, 'div[aria-label="Mercado Page navigation . Mercado"]')))
# Click to go to second page
wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, '#embedWrapperID>div.logoBarWrapper>logo-bar>div>div>div>logo-bar-navigation>span>button:nth-child(3)'))).click()
# Click to open the date drop-down
wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, '#pvExplorationHost > div > div > exploration > div > explore-canvas > div > div.canvasFlexBox > div > div.displayArea.disableAnimations.fitToPage > div.visualContainerHost.visualContainerOutOfFocus > visual-container-repeat > visual-container:nth-child(6) > transform > div > div.visualContent > div > div > visual-modern > div > div > div.slicer-content-wrapper > div>i'))).click()
# Expand month options for 2023
wait.until(EC.presence_of_element_located((By.XPATH, f'//div[@class="slicerItemContainer" and @title="{year}"]/div[@class="expandButton"]'))).click()
sleep(3) # Let dropdown finish animating
sc = driver.find_element(By.CSS_SELECTOR, 'div[id^="slicer-dropdown-popup-"]>div>div>div:nth-child(2)>div>div:nth-child(3)')
# Scroll the slicer container
action_chains = ActionChains(driver)
action_chains.move_to_element(sc).click_and_hold().move_by_offset(0, 100).release().perform()
sleep(2)
driver.find_element(By.XPATH, f'//div[@class="slicerItemContainer" and @aria-posinset="{month}"]').click()
sleep(2)
report_analyser('2022', 1)
Visual output:
https://github.com/Help-the-community/Web_Scraping_with_Selenium/blob/main/app_powerbi_com_anp.gif
you can check here for a cleaner version of the code: https://github.com/Help-the-community/Web_Scraping_with_Selenium/blob/main/app_powerbi_com_anp.py