ฉันจะเลื่อนหน้าเว็บโดยใช้ selenium webdriver ใน python ได้อย่างไร


132

ฉันกำลังใช้ selenium webdriver เพื่อแยกวิเคราะห์ผ่านหน้าเพื่อนของผู้ใช้ facebook และแยกรหัสทั้งหมดจากสคริปต์ AJAX แต่ฉันต้องเลื่อนลงเพื่อรับเพื่อนทั้งหมด ฉันจะเลื่อนลงในซีลีเนียมได้อย่างไร ฉันใช้ python


2
เป็นไปได้ที่ซ้ำกันของวิธีการเลื่อนหน้าด้วยซีลีเนียม
Louis

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

คำตอบ:


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

อีกวิธีหนึ่ง (ขอบคุณ Juanse) คือเลือกวัตถุและ

label.sendKeys(Keys.PAGE_DOWN);

1
ยอดเยี่ยมช่วยอธิบายหน่อยได้scrollHeightไหมว่ามันหมายความว่าอย่างไรและโดยทั่วไปทำงานอย่างไร
Jason Goal

คุณจะใช้ตัวแปร "last_height" อย่างไร ฉันมีบางอย่างที่คล้ายกันในโค้ดของฉันและเบราว์เซอร์กำลังเลื่อนลง อย่างไรก็ตามเมื่อฉันดูข้อมูลที่ฉันกำลังขูดมันจะคัดเฉพาะข้อมูลจากหน้าแรก k ครั้งโดย "k" เป็นจำนวนครั้งที่เบราว์เซอร์เลื่อนลง
Peter Lenaers

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


นี่มันเยี่ยมมาก สำหรับใครก็ตามที่พยายามใช้สิ่งนี้บน 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_scrolled_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 propertyดูซอร์สโค้ดที่นี่: ซีลีเนียม / webelement.py ที่ d3b6ad006bd7dbee59f8539d81cee4f06bd81d64 · SeleniumHQ / ซีลีเนียม
DataAlchemist

10

สำหรับจุดประสงค์ของฉันฉันต้องการเลื่อนลงมากขึ้นโดยคำนึงถึงตำแหน่งของหน้าต่าง วิธีแก้ปัญหาของฉันคล้ายกันและใช้window.scrollY

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

ซึ่งจะไปที่ตำแหน่งเลื่อน y ปัจจุบัน + 200



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()) หยุดเฉพาะเมื่อสำหรับการวนซ้ำครั้งเดียวความสูงของหน้าจะยังคงเท่าเดิม

(มีการปรับเปลี่ยนอีกอย่างหนึ่งโดยที่คำสั่ง 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

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

เลื่อนหน้าโหลด ตัวอย่าง: 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()

1
driver.quit () ควรอยู่นอกบล็อก while หรือไม่? และไม่จำเป็นต้องรอโดยปริยายสุดท้าย .. มีคนยืนยัน @ashishmishra
ihightower

ไม่ถ้า driver.quit () อยู่ใน while loop ไดรเวอร์จะถูกปิดการวนซ้ำแต่ละครั้งของลูป เมื่อไม่มีความยาวไปที่หน้าแล้วมันจะออก การรอครั้งสุดท้ายอาจเป็นการให้เวลาในการโหลดหน้าเว็บ?
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

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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.