Bagaimana saya bisa menggulir halaman web menggunakan selenium webdriver in python?

132

Saat ini saya menggunakan selenium webdriver untuk mem-parsing melalui halaman teman-teman pengguna facebook dan mengekstrak semua id dari skrip AJAX. Tapi saya perlu gulir ke bawah untuk mendapatkan semua teman. Bagaimana saya bisa gulir ke bawah di Selenium. Saya menggunakan python.

pengguna2523364
sumber
2
kemungkinan duplikat dari Bagaimana cara menggulir halaman dengan selenium
Louis
driver.execute_script (f "window.scrollTo (0, {2 ** 127});")
AturSams

Jawaban:

264

Kamu bisa memakai

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

di mana Y adalah tinggi (pada monitor fullhd itu 1080). (Terima kasih kepada @ Lukas)

Anda juga bisa menggunakan

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

untuk menggulir ke bagian bawah halaman.

Jika Anda ingin menggulir ke halaman dengan pemuatan tanpa batas , seperti yang ada di jejaring sosial, facebook, dll. (Terima kasih kepada @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

Metode lain (terima kasih kepada Juanse) adalah, pilih objek dan

label.sendKeys(Keys.PAGE_DOWN);
OWADVL
sumber
1
Luar biasa, dapatkah Anda menjelaskan sedikit tentang scrollHeight, apa artinya dan bagaimana cara kerjanya secara umum?
Jason Goal
Lalu bagaimana Anda menggunakan variabel "last_height"? Saya memiliki sesuatu yang serupa dalam kode saya dan browser sedang bergulir. Namun, ketika saya melihat data saya menggoresnya hanya menggores data dari halaman pertama kali k dengan "k" menjadi berapa kali browser gulir ke bawah.
Peter Lenaers
72

Jika Anda ingin menggulir ke bawah ke halaman tak terbatas (seperti linkedin.com ), Anda dapat menggunakan kode ini:

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

Referensi: https://stackoverflow.com/a/28928684/1316860

Cuong Tran
sumber
Ini bagus. Bagi siapa saja yang mencoba menggunakan ini pada instagram, Anda mungkin perlu tab pertama ke tombol "Muat lebih" menggunakan ActionChains, kemudian menerapkan solusi Cuong Tran ... setidaknya itulah yang bekerja untuk saya.
Mwspencer
Terima kasih atas jawabannya! Apa yang ingin saya lakukan adalah gulir misalnya di instagram ke bagian bawah halaman, lalu ambil seluruh html halaman. Apakah ada fungsi di selenium di mana saya bisa memberikan last_height sebagai input dan mendapatkan seluruh halaman html, setelah saya menggulir ke bawah?
Swan87
2
The SCROLL_PAUSE_TIMEbervariasi, dibutuhkan sekitar 2 detik untuk saya.
ssi-anik
30

Anda dapat menggunakan send_keysuntuk mensimulasikan penekanan tombol END(atau PAGE_DOWN) (yang biasanya menggulir halaman):

from selenium.webdriver.common.keys import Keys
html = driver.find_element_by_tag_name('html')
html.send_keys(Keys.END)
LIU YUE
sumber
21

metode yang sama seperti yang ditunjukkan di sini :

dalam python Anda bisa menggunakan

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

(Y adalah posisi vertikal yang ingin Anda gulir ke)

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

element.location_once_scrolled_into_view

ini membantu ketika saya mencoba mengakses 'li' yang tidak terlihat.

firasat
sumber
'find_element_by_xpath' adalah fungsi driver atau apa, '.location_once_scrolled_into_view' mengembalikan kesalahan NoSuchElementException: Pesan: tidak ada elemen seperti: Tidak dapat menemukan elemen: {"metode": "xpath", "selector": "// * [@ id = "timeline-medley"] / div / div [2] / div [1] "}
Walid Bousseta
Hanya satu lagi. Alasan mengapa location_once_scrolled_into_viewharus dipanggil tanpa () adalah itu location_once_scrolled_into_viewadalah Python property. lihat kode sumber di sini: selenium / webelement.py di d3b6ad006bd7dbee59f8539d81cee4f06bd81d64 · SeleniumHQ / selenium
DataAlchemist
10

Untuk tujuan saya, saya ingin menggulir lebih ke bawah, dengan mengingat posisi jendela. Solusi saya serupa dan digunakanwindow.scrollY

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

yang akan pergi ke posisi gulir y saat ini + 200

Nick Brady
sumber
8

Ini adalah cara Anda menggulir ke bawah halaman web:

driver.execute_script("window.scrollTo(0, 1000);")
sahaja nadendla
sumber
7

Cara termudah yang saya temukan untuk menyelesaikan masalah itu adalah dengan memilih label dan kemudian mengirim:

label.sendKeys(Keys.PAGE_DOWN);

Semoga berhasil!

Juanse
sumber
6

Tidak satu pun dari jawaban ini yang berfungsi untuk saya, paling tidak untuk menelusuri halaman hasil pencarian facebook, tetapi saya menemukan setelah banyak menguji solusi ini:

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
Bass Dee
sumber
Ini bekerja, tetapi sangat lambat (setidaknya untuk saya). Saya menemukan bahwa jika Anda menetapkan SCROLL_PAUSE_TIMEdi stackoverflow.com/a/27760083/7326714 untuk 2, bekerja dengan baik dan Anda gulir ke bawah 100x lebih cepat.
LucSpan
6

Saat bekerja dengan youtube, elemen apung memberikan nilai "0" sebagai tinggi gulir daripada menggunakan "return document.body.scrollHeight" coba gunakan "return document.documentElement.scrollHeight" yang ini sesuaikan waktu jeda gulir sesuai internet Anda kecepatan lain itu akan berjalan hanya untuk satu waktu dan kemudian istirahat setelah itu.

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
sumber
5

Saya sedang mencari cara untuk menggulir halaman web yang dinamis, dan secara otomatis berhenti setelah akhir halaman tercapai, dan menemukan utas ini.

Posting oleh @Cuong Tran , dengan satu modifikasi utama, adalah jawaban yang saya cari. Saya pikir orang lain mungkin menganggap modifikasi itu membantu (ini memiliki efek nyata pada bagaimana kode bekerja), maka dari itu postingan ini.

Modifikasinya adalah dengan memindahkan pernyataan yang menangkap ketinggian halaman terakhir di dalam loop (sehingga setiap pemeriksaan membandingkan dengan tinggi halaman sebelumnya).

Jadi, kode di bawah ini:

Menggulir ke bawah halaman web dinamis ( .scrollTo()) secara terus-menerus , hanya berhenti ketika, untuk satu iterasi, tinggi halaman tetap sama.

(Ada modifikasi lain, di mana pernyataan break berada di dalam kondisi lain (jika halaman 'stick') yang dapat dihapus).

    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
sumber
5

Kode ini bergulir ke bawah tetapi tidak mengharuskan Anda menunggu setiap waktu. Ini akan terus bergulir, dan kemudian berhenti di bagian bawah (atau batas waktu)

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

Ini jauh lebih cepat daripada menunggu 0,5-3 detik setiap kali untuk respons, ketika respons itu bisa memakan waktu 0,1 detik

AlbertWolfgang
sumber
3

gulir memuat halaman. Contoh: medium, quora, dll

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
sumber
1
haruskah driver.quit () berada di luar blok sementara atau tidak? dan juga tunggu implisit terakhir tidak diperlukan .. seseorang tolong konfirmasi. @ashishmishra
ihightower
1

jika Anda ingin menggulir dalam tampilan / bingkai tertentu (WebElement), apa yang hanya perlu Anda lakukan adalah mengganti "tubuh" dengan elemen tertentu yang ingin Anda gulir ke dalamnya. saya mendapatkan elemen itu melalui "getElementById" pada contoh di bawah ini:

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

ini adalah kasus di YouTube , misalnya ...

Furkan Unluturk
sumber
1

The ScrollTo()fungsi tidak bekerja lagi. Inilah yang saya gunakan dan itu bekerja dengan baik.

driver.execute_script("document.getElementById('mydiv').scrollIntoView();")
MoKG
sumber
Hanya metode ini yang berhasil dalam kasus saya, bukan yang lain yang berhasil. Terima kasih.
ePandit
0
driver.execute_script("document.getElementById('your ID Element').scrollIntoView();")

ini bekerja untuk kasus saya.

Long Lê Hoàng
sumber