I am currently using selenium webdriver to parse through facebook user friends page and extract all ids from the AJAX script. But I need to scroll down to get all the friends. How can I scroll down in Selenium. I am using python.
-
2possible duplicate of [How to scroll page with selenium](http://stackoverflow.com/questions/8433223/how-to-scroll-page-with-selenium) – Louis Jan 03 '15 at 23:08
-
driver.execute_script(f"window.scrollTo(0, {2**127});") – AturSams Jun 08 '19 at 05:34
-
If in your case that there is a list of items, so you can follow this method stackoverflow.com/a/68970174/12272687 – Mori Aug 30 '21 at 14:42
21 Answers
You can use
driver.execute_script("window.scrollTo(0, Y)")
where Y is the height (on a fullhd monitor it's 1080). (Thanks to @lukeis)
You can also use
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
to scroll to the bottom of the page.
If you want to scroll to a page with infinite loading, like social network ones, facebook etc. (thanks to @Cuong Tran)
SCROLL_PAUSE_TIME = 0.5
# Get scroll height
last_height = driver.execute_script("return document.body.scrollHeight")
while True:
# Scroll down to bottom
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
# Wait to load page
time.sleep(SCROLL_PAUSE_TIME)
# Calculate new scroll height and compare with last scroll height
new_height = driver.execute_script("return document.body.scrollHeight")
if new_height == last_height:
break
last_height = new_height
another method (thanks to Juanse) is, select an object and
label.sendKeys(Keys.PAGE_DOWN);
- 9,777
- 6
- 53
- 67
-
2Excellent, can you explain a little bit on `scrollHeight`, what does it mean and how does it work in general? – Jason Goal Dec 01 '18 at 18:04
-
How would you then use the variable "last_height"? I have something similar in my code and the browser is scrolling down. However, when I look at the data I'm scraping it only scrapes the data from the first page k times with "k" being the number of times the browser scrolls down. – Peter Lenaers May 22 '19 at 09:27
-
@JasonGoal hope this will help: https://stackoverflow.com/a/22675563/6907424 – hafiz031 Dec 14 '20 at 17:38
-
`driver.execute_script` can be combined with smooth scrolling (https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollTo) to imitate more human-like behavior! – agupta231 Mar 17 '21 at 03:00
If you want to scroll down to bottom of infinite page (like linkedin.com), you can use this code:
SCROLL_PAUSE_TIME = 0.5
# Get scroll height
last_height = driver.execute_script("return document.body.scrollHeight")
while True:
# Scroll down to bottom
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
# Wait to load page
time.sleep(SCROLL_PAUSE_TIME)
# Calculate new scroll height and compare with last scroll height
new_height = driver.execute_script("return document.body.scrollHeight")
if new_height == last_height:
break
last_height = new_height
Reference: https://stackoverflow.com/a/28928684/1316860
- 1
- 1
- 1,739
- 19
- 21
-
1This is great. For anyone who is trying to use this on instagram, you may need to first tab to the "Load more" button using ActionChains, then apply Cuong Tran's solution... at least that's what worked for me. – Mwspencer Jan 23 '18 at 21:37
-
Thanks for the answer! What I would like to do is scroll for instance in instagram to the bottom of the page, then grab the entire html of the page. Is there a function in selenium where I could give last_height as input and get the entire page html, after I have scrolled to the bottom? – Swan87 Feb 23 '18 at 10:52
-
3
You can use send_keys to simulate an END (or PAGE_DOWN) key press (which normally scroll the page):
from selenium.webdriver.common.keys import Keys
html = driver.find_element_by_tag_name('html')
html.send_keys(Keys.END)
- 10,733
- 7
- 77
- 79
- 1,187
- 9
- 15
-
1Tried PAGE_DOWN on a loop and did not behave as expected, END worked as expected for w/e reason – Clocker Mar 12 '21 at 23:04
element=find_element_by_xpath("xpath of the li you are trying to access")
element.location_once_scrolled_into_view
this helped when I was trying to access a 'li' that was not visible.
- 9,073
- 146
- 84
- 117
- 249
- 3
- 7
-
'find_element_by_xpath' is a driver function or what, the '.location_once_scrolled_into_view' returns error NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":"//*[@id="timeline-medley"]/div/div[2]/div[1]"} – Walid Bousseta Jul 11 '19 at 19:40
-
Just one more thing. The reason why `location_once_scrolled_into_view` should be called without `()` is that `location_once_scrolled_into_view` is a Python `property`. see the source code here: [selenium/webelement.py at d3b6ad006bd7dbee59f8539d81cee4f06bd81d64 · SeleniumHQ/selenium](https://github.com/SeleniumHQ/selenium/blob/d3b6ad006bd7dbee59f8539d81cee4f06bd81d64/py/selenium/webdriver/remote/webelement.py) – DataAlchemist May 03 '20 at 08:09
For my purpose, I wanted to scroll down more, keeping the windows position in mind. My solution was similar and used window.scrollY
driver.execute_script("window.scrollTo(0, window.scrollY + 200)")
which will go to the current y scroll position + 200
- 5,447
- 1
- 40
- 61
This is how you scroll down the webpage:
driver.execute_script("window.scrollTo(0, 1000);")
- 39,105
- 12
- 41
- 62
- 121
- 1
- 2
None of these answers worked for me, at least not for scrolling down a facebook search result page, but I found after a lot of testing this solution:
while driver.find_element_by_tag_name('div'):
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
Divs=driver.find_element_by_tag_name('div').text
if 'End of Results' in Divs:
print 'end'
break
else:
continue
- 81
- 1
- 3
-
It works, but very slow (for me at least). I found that if you set `SCROLL_PAUSE_TIME` in https://stackoverflow.com/a/27760083/7326714 to `2`, it works just fine and you scroll down a 100x faster. – LucSpan Apr 28 '18 at 15:55
The easiest way i found to solve that problem was to select a label and then send:
label.sendKeys(Keys.PAGE_DOWN);
Hope it works!
- 81
- 1
- 1
scroll loading pages. Example: medium, quora,etc
last_height = driver.execute_script("return document.body.scrollHeight")
while True:
driver.execute_script("window.scrollTo(0, document.body.scrollHeight-1000);")
# Wait to load the page.
driver.implicitly_wait(30) # seconds
new_height = driver.execute_script("return document.body.scrollHeight")
if new_height == last_height:
break
last_height = new_height
# sleep for 30s
driver.implicitly_wait(30) # seconds
driver.quit()
- 335
- 2
- 14
-
1should driver.quit() be outside the while block or not? and also the last implicit wait is not required.. someone pls confirm. @ashishmishra – ihightower Jul 24 '20 at 10:29
-
No, if driver.quit() was inside the while loop, the driver would be closed each iteration of the loop. Once there is no more length to the page, then it will quit. The last wait could be there to give the page time to load? – Samt94 Aug 07 '20 at 13:23
When working with youtube the floating elements give the value "0" as the scroll height so rather than using "return document.body.scrollHeight" try using this one "return document.documentElement.scrollHeight" adjust the scroll pause time as per your internet speed else it will run for only one time and then breaks after that.
SCROLL_PAUSE_TIME = 1
# Get scroll height
"""last_height = driver.execute_script("return document.body.scrollHeight")
this dowsnt work due to floating web elements on youtube
"""
last_height = driver.execute_script("return document.documentElement.scrollHeight")
while True:
# Scroll down to bottom
driver.execute_script("window.scrollTo(0,document.documentElement.scrollHeight);")
# Wait to load page
time.sleep(SCROLL_PAUSE_TIME)
# Calculate new scroll height and compare with last scroll height
new_height = driver.execute_script("return document.documentElement.scrollHeight")
if new_height == last_height:
print("break")
break
last_height = new_height
- 487
- 5
- 8
This code scrolls to the bottom but doesn't require that you wait each time. It'll continually scroll, and then stop at the bottom (or timeout)
from selenium import webdriver
import time
driver = webdriver.Chrome(executable_path='chromedriver.exe')
driver.get('https://example.com')
pre_scroll_height = driver.execute_script('return document.body.scrollHeight;')
run_time, max_run_time = 0, 1
while True:
iteration_start = time.time()
# Scroll webpage, the 100 allows for a more 'aggressive' scroll
driver.execute_script('window.scrollTo(0, 100*document.body.scrollHeight);')
post_scroll_height = driver.execute_script('return document.body.scrollHeight;')
scrolled = post_scroll_height != pre_scroll_height
timed_out = run_time >= max_run_time
if scrolled:
run_time = 0
pre_scroll_height = post_scroll_height
elif not scrolled and not timed_out:
run_time += time.time() - iteration_start
elif not scrolled and timed_out:
break
# closing the driver is optional
driver.close()
This is much faster than waiting 0.5-3 seconds each time for a response, when that response could take 0.1 seconds
- 419
- 1
- 6
- 12
You can use send_keys to simulate a PAGE_DOWN key press (which normally scroll the page):
from selenium.webdriver.common.keys import Keys
html = driver.find_element_by_tag_name('html')
html.send_keys(Keys.PAGE_DOWN)
- 109
- 2
- 5
-
That's exactly [this answer](https://stackoverflow.com/questions/20986631/how-can-i-scroll-a-web-page-using-selenium-webdriver-in-python/63795903#51345544), simply more vague – xKobalt Sep 08 '20 at 14:53
-
1this the only code that works with me on the Specific page I work on but I must click on the slider with the mouse to work I don't know why I should do that and i try find another solution for my problem – NourEldin Osama Sep 19 '20 at 09:22
-
the page i works on: https://contacts.google.com/u/0/directory – NourEldin Osama Sep 19 '20 at 09:23
I was looking for a way of scrolling through a dynamic webpage, and automatically stopping once the end of the page is reached, and found this thread.
The post by @Cuong Tran, with one main modification, was the answer that I was looking for. I thought that others might find the modification helpful (it has a pronounced effect on how the code works), hence this post.
The modification is to move the statement that captures the last page height inside the loop (so that each check is comparing to the previous page height).
So, the code below:
Continuously scrolls down a dynamic webpage (
.scrollTo()), only stopping when, for one iteration, the page height stays the same.
(There is another modification, where the break statement is inside another condition (in case the page 'sticks') which can be removed).
SCROLL_PAUSE_TIME = 0.5
while True:
# Get scroll height
### This is the difference. Moving this *inside* the loop
### means that it checks if scrollTo is still scrolling
last_height = driver.execute_script("return document.body.scrollHeight")
# Scroll down to bottom
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
# Wait to load page
time.sleep(SCROLL_PAUSE_TIME)
# Calculate new scroll height and compare with last scroll height
new_height = driver.execute_script("return document.body.scrollHeight")
if new_height == last_height:
# try again (can be removed)
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
# Wait to load page
time.sleep(SCROLL_PAUSE_TIME)
# Calculate new scroll height and compare with last scroll height
new_height = driver.execute_script("return document.body.scrollHeight")
# check if the page height has remained the same
if new_height == last_height:
# if so, you are done
break
# if not, move on to the next loop
else:
last_height = new_height
continue
- 165
- 1
- 3
- 8
Here's an example selenium code snippet that you could use for this type of purpose. It goes to the url for youtube search results on 'Enumerate python tutorial' and scrolls down until it finds the video with the title: 'Enumerate python tutorial(2020).'
driver.get('https://www.youtube.com/results?search_query=enumerate+python')
target = driver.find_element_by_link_text('Enumerate python tutorial(2020).')
target.location_once_scrolled_into_view
- 143
- 2
- 8
The ScrollTo() function doesn't work anymore. This is what I used and it worked fine.
driver.execute_script("document.getElementById('mydiv').scrollIntoView();")
- 246
- 3
- 12
-
-
worked for me too. If you're calling scrollIntoView multiple times, be sure to set a setTimeout() function in order to allow the page to load the new content, or it won't find the new element. On a side note, to find an elem by href you can do: driver.execute_script(document.querySelector(\"a[href=\'your_href_link\']\").scrollIntoView();") – gl3yn Apr 03 '21 at 18:20
if you want to scroll within a particular view/frame (WebElement), what you only need to do is to replace "body" with a particular element that you intend to scroll within. i get that element via "getElementById" in the example below:
self.driver.execute_script('window.scrollTo(0, document.getElementById("page-manager").scrollHeight);')
this is the case on YouTube, for example...
insert this line driver.execute_script("window.scrollBy(0,925)", "")
- 180
- 5
-
1While this code may answer the question, [including an explanation](https://meta.stackoverflow.com/questions/392712/explaining-entirely-code-based-answers) of how or why this solves the problem would really help to improve the quality of your post. Remember that you are answering the question for readers in the future, not just the person asking now. Please [edit] your answer to add explanations and give an indication of what limitations and assumptions apply. – ppwater Jan 16 '21 at 07:51
The loop using the "send keys" method of scrolling the page:
pre_scroll_height = driver.execute_script('return document.body.scrollHeight;')
while True:
driver.find_element_by_tag_name('body').send_keys(Keys.END)
time.sleep(5)
post_scroll_height = driver.execute_script('return document.body.scrollHeight;')
print(pre_scroll_height, post_scroll_height)
if pre_scroll_height == post_scroll_height:
break
pre_scroll_height=post_scroll_height
- 435
- 4
- 10
According to the docs,
the class ActionChains does the job:
from selenium import webdriver
from selenium.webdriver import ActionChains
driver = webdriver.Firefox()
action_chains = ActionChains(driver)
action_chains.scroll(x: int, y: int, delta_x: int, delta_y: int, duration: int = 0, origin: str = 'viewport')
- 161
- 9
driver.execute_script("document.getElementById('your ID Element').scrollIntoView();")
it's working for my case.
- 35,848
- 27
- 79
- 88
- 13
- 5