Як я можу прокручувати веб-сторінку за допомогою selenium webdriver в python?


131

В даний час я використовую веб-диск селену для розбору сторінки друзів користувача у Facebook та витягування всіх ідентифікаторів зі сценарію AJAX. Але мені потрібно прокрутити вниз, щоб набрати всіх друзів. Як я можу прокручуватися вниз до селену. Я використовую python.



driver.execute_script (f "window.scrollTo (0, {2 ** 127});")
AturSams

Відповіді:


263

Можна використовувати

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

інший метод (завдяки Juanse) полягає в тому, щоб вибрати об'єкт і

label.sendKeys(Keys.PAGE_DOWN);

1
Чудово, ви можете трохи пояснити scrollHeight, що це означає і як це працює взагалі?
Мета Джейсона

Як би ви потім використовували змінну "last_height"? У моєму коді є щось подібне, і браузер прокручується вниз. Однак, коли я дивлюся на дані, які я скреблю, вони лише викреслюють дані з першої сторінки k разів, "k" - кількість разів прокручування браузера.
Пітер Ленеерс

72

Якщо ви хочете прокрутити донизу нескінченну сторінку (наприклад, 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


Це чудово. Для всіх, хто намагається використовувати це на 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 - вертикальне положення, до якого потрібно прокрутити)


15
element=find_element_by_xpath("xpath of the li you are trying to access")

element.location_once_scrolled_into_view

це допомогло, коли я намагався отримати доступ до "li", який не було видно.


'find_element_by_xpath' - це функція драйвера чи що, '.location_once_scroll_into_view' повертає помилку NoSuchElementException: Повідомлення: немає такого елемента: Неможливо знайти елемент: {"method": "xpath", "selector": "// * [@ id = "timeline-medley"] / div / div [2] / div [1] "}
Walid Bousseta

Просто ще одна річ. Причина, по якій location_once_scrolled_into_viewслід називати без () , location_once_scrolled_into_view- це Python property. дивіться вихідний код тут: selenium / webelement.py at d3b6ad006bd7dbee59f8539d81cee4f06bd81d64 · SeleniumHQ /
selenium

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

5

Я шукав спосіб прокрутки динамічної веб-сторінки, і автоматично зупинявся, як тільки був досягнутий кінець сторінки, і знайшов цю тему.

Запис від @Cuong Tran , з однією основною модифікацією, був відповіддю, який я шукав. Я думав, що інші можуть вважати модифікацію корисною (це яскраво впливає на те, як працює код), звідси і ця публікація.

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

Отже, код нижче:

Постійно прокручує динамічну веб-сторінку ( .scrollTo()), зупиняючись лише тоді, коли за одну ітерацію висота сторінки залишається однаковою.

(Є ще одна модифікація, де оператор перерви знаходиться в іншій умові (у випадку, якщо сторінка 'приклеюється'), яку можна видалити).

    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

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 секунди


3

прокручування завантажуваних сторінок. Приклад: середній, квора тощо

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

1
чи повинен driver.quit () знаходитись поза блоком while чи ні? а також останнє неявне очікування не потрібно .. хтось pls підтверджує. @ashishmishra
ihightower

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

У моєму випадку працював лише цей метод, а не інший. Дякую.
ePandit

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.