Как я могу прокручивать веб-страницу с помощью selenium webdriver в Python?

132

В настоящее время я использую selenium webdriver для анализа страницы друзей пользователей facebook и извлечения всех идентификаторов из сценария AJAX. Но мне нужно прокрутить вниз, чтобы найти всех друзей. Как я могу прокрутить вниз в Selenium. Я использую питон.

user2523364
источник
driver.execute_script (f "window.scrollTo (0, {2 ** 127});")
AturSams 08

Ответы:

264

Ты можешь использовать

driver.execute_script("window.scrollTo(0, Y)") 

где Y - высота (на fullhd мониторе 1080). (Спасибо @lukeis)

Вы также можете использовать

driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")

для прокрутки вниз страницы.

Если вы хотите перейти на страницу с бесконечной загрузкой , например, в социальных сетях, facebook и т. Д. (Спасибо @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

Другой метод (спасибо Хуансу) - выбрать объект и

label.sendKeys(Keys.PAGE_DOWN);
OWADVL
источник
1
Отлично, не могли бы вы немного объяснить scrollHeight, что это значит и как вообще работает?
Джейсон Гол
Как бы вы тогда использовали переменную last_height? У меня что-то похожее есть в моем коде, и браузер прокручивается вниз. Однако, когда я смотрю на данные, которые я очищаю, он очищает данные только с первой страницы k раз, где «k» - это количество раз, когда браузер прокручивает страницу вниз.
Питер Ленаерс
73

Если вы хотите прокрутить вниз бесконечную страницу (например, linkedin.com ), вы можете использовать этот код:

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

Ссылка: https://stackoverflow.com/a/28928684/1316860

Cuong Tran
источник
Это круто. Для тех, кто пытается использовать это в Instagram, вам может потребоваться сначала перейти к кнопке «Загрузить еще» с помощью ActionChains, а затем применить решение Cuong Tran ... по крайней мере, это то, что сработало для меня.
Mwspencer
Спасибо за ответ! Я бы хотел прокрутить, например, в instagram до нижней части страницы, а затем захватить весь html страницы. Есть ли в селене функция, где я мог бы указать last_height в качестве ввода и получить всю страницу html после прокрутки вниз?
Swan87
2
Время SCROLL_PAUSE_TIMEразное, у меня это занимает около 2 секунд.
ssi-anik
21

тот же метод, что и здесь :

в Python вы можете просто использовать

driver.execute_script("window.scrollTo(0, Y)")

(Y - вертикальное положение, до которого нужно прокрутить)

lukeis
источник
15
element=find_element_by_xpath("xpath of the li you are trying to access")

element.location_once_scrolled_into_view

это помогло, когда я пытался получить доступ к невидимой «ли».

предчувствие
источник
'find_element_by_xpath' - это функция драйвера или что-то в этом роде, '.location_once_scrolled_into_view' возвращает ошибку NoSuchElementException: Сообщение: нет такого элемента: Невозможно найти элемент: {"method": "xpath", "selector": "// * [@ id = "timeline-medley"] / div / div [2] / div [1] "}
Валид Бусета
Еще одна вещь. Причина, по которой location_once_scrolled_into_viewследует вызывать без () него, location_once_scrolled_into_view- это Python property. см. исходный код здесь: selenium / webelement.py на d3b6ad006bd7dbee59f8539d81cee4f06bd81d64 · SeleniumHQ / selenium
DataAlchemist
10

Для моей цели я хотел больше прокручивать вниз, не забывая о положении окон. Мое решение было похожим и использовалосьwindow.scrollY

driver.execute_script("window.scrollTo(0, window.scrollY + 200)")

который перейдет в текущую позицию прокрутки y + 200

Ник Брэди
источник
8

Вот как вы прокручиваете страницу вниз:

driver.execute_script("window.scrollTo(0, 1000);")
Сахаджа Надендла
источник
7

Самый простой способ решить эту проблему - выбрать ярлык и отправить:

label.sendKeys(Keys.PAGE_DOWN);

Надеюсь, что это работает!

Хуанс
источник
6

Ни один из этих ответов не помог мне, по крайней мере, не для прокрутки страницы результатов поиска facebook, но после длительного тестирования я обнаружил это решение:

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
Басс Ди
источник
Работает, но очень медленно (по крайней мере, для меня). Я обнаружил, что если вы установите SCROLL_PAUSE_TIMEв stackoverflow.com/a/27760083/7326714 значение 2, он работает нормально, и вы прокручиваете вниз в 100 раз быстрее.
LucSpan
6

При работе с YouTube плавающие элементы дают значение «0» в качестве высоты прокрутки, поэтому вместо использования «return document.body.scrollHeight» попробуйте использовать этот «return document.documentElement.scrollHeight», отрегулируйте время паузы прокрутки в соответствии с вашим Интернетом. скорость, иначе он будет работать только один раз, а затем прервется.

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
Vinay Verma
источник
5

Я искал способ прокрутки динамической веб-страницы и автоматической остановки при достижении конца страницы, и нашел этот поток.

Сообщение @Cuong Tran с одной важной модификацией было тем ответом, который я искал. Я подумал, что другие могут найти эту модификацию полезной (она явно влияет на работу кода), отсюда и этот пост.

Модификация заключается в перемещении оператора, который фиксирует высоту последней страницы внутри цикла (так, чтобы каждая проверка сравнивалась с высотой предыдущей страницы).

Итак, код ниже:

Непрерывно прокручивает динамическую веб-страницу ( .scrollTo()), останавливаясь только тогда, когда для одной итерации высота страницы остается прежней.

(Есть еще одна модификация, где оператор break находится внутри другого условия (в случае, если страница «заедает»), которое можно удалить).

    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
Splarty
источник
5

Этот код прокручивается вниз, но не требует ожидания каждый раз. Он будет постоянно прокручиваться, а затем останавливаться внизу (или по истечении времени ожидания)

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()

Это намного быстрее, чем каждый раз ждать ответа 0,5–3 секунды, когда ответ может занять 0,1 секунды.

AlbertWolfgang
источник
3

прокрутите загрузочные страницы. Пример: medium, quora и т. Д.

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()
ashishmishra
источник
1
должен driver.quit () находиться вне блока while или нет? а также последнее неявное ожидание не требуется .. кто-нибудь, пожалуйста, подтвердите. @ashishmishra
ihightower
Нет, если driver.quit () находился внутри цикла while, драйвер закрывался бы на каждой итерации цикла. Как только длина страницы закончится, она будет закрыта. Последнее ожидание могло быть там, чтобы дать странице время для загрузки?
Samt94
2

Вот пример фрагмента кода селена, который вы могли бы использовать для таких целей. Он переходит к URL-адресу результатов поиска youtube в «Enumerate python tutorial» и прокручивает вниз, пока не находит видео с заголовком: «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
coder420
источник
1

если вы хотите прокрутить в пределах определенного представления / фрейма (WebElement), вам нужно всего лишь заменить «body» конкретным элементом, внутри которого вы собираетесь прокручивать. я получаю этот элемент через getElementById в примере ниже:

self.driver.execute_script('window.scrollTo(0, document.getElementById("page-manager").scrollHeight);')

это , например, случай на YouTube ...

Фуркан Унлютюрк
источник
1

ScrollTo()Функция больше не работает. Это то, что я использовал, и он работал нормально.

driver.execute_script("document.getElementById('mydiv').scrollIntoView();")
MoKG
источник
В моем случае работал только этот метод, другие не работали. Спасибо.
ePandit
0
driver.execute_script("document.getElementById('your ID Element').scrollIntoView();")

это работает в моем случае.

Лонг Ле Хоанг
источник