如何使用 python 中的 selenium webdriver 滚动网页?

2024-12-04 08:56:00
admin
原创
288
摘要:问题描述:我目前正在使用 selenium webdriver 解析 Facebook 用户好友页面并从 AJAX 脚本中提取所有 ID。但我需要向下滚动才能获取所有好友。如何在 Selenium 中向下滚动。我正在使用 python。解决方案 1:您可以使用driver.execute_script(&qu...

问题描述:

我目前正在使用 selenium webdriver 解析 Facebook 用户好友页面并从 AJAX 脚本中提取所有 ID。但我需要向下滚动才能获取所有好友。如何在 Selenium 中向下滚动。我正在使用 python。


解决方案 1:

您可以使用

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

其中 Y 是高度(在全高清显示器上为 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);

解决方案 2:

如果您想向下滚动到无限页面(如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

解决方案 3:

您可以使用send_keys来模拟END(或PAGE_DOWN)按键(通常滚动页面):

from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
html = driver.find_element(By.TAG_NAME, 'html')
html.send_keys(Keys.END)

解决方案 4:

与此处所示的方法相同:

在 python 中你可以使用

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

(Y 是要滚动到的垂直位置)

解决方案 5:

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

element.location_once_scrolled_into_view

当我尝试访问不可见的“li”时,这很有帮助。

解决方案 6:

为了达到我的目的,我想向下滚动更多,同时记住窗口的位置。我的解决方案类似,并使用window.scrollY

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

这将转到当前 y 滚动位置 + 200

解决方案 7:

这是你向下滚动网页的方式:

driver.execute_script("window.scrollTo(0, 1000);")

解决方案 8:

我发现解决该问题的最简单方法是选择一个标签然后发送:

label.sendKeys(Keys.PAGE_DOWN);

希望它有效!

解决方案 9:

当使用 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

解决方案 10:

滚动加载页面。例如: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()

解决方案 11:

这些答案对我都不起作用,至少对于向下滚动 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

解决方案 12:

以下是可用于此类目的的示例 selenium 代码片段。它会转到 YouTube 上“Enumerate python tutorial”搜索结果的 URL,然后向下滚动,直到找到标题为“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

解决方案 13:

我正在寻找一种滚动动态网页的方法,并在到达页面末尾时自动停止,然后找到了这个线程。

@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

解决方案 14:

此代码会滚动到底部,但不需要每次都等待。它会持续滚动,然后停在底部(或超时)

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 秒

解决方案 15:

您可以使用send_keys来模拟PAGE_DOWN按键(通常滚动页面):

from selenium.webdriver.common.keys import Keys
html = driver.find_element_by_tag_name('html')
html.send_keys(Keys.PAGE_DOWN)

解决方案 16:

如果您想在特定视图/框架(WebElement)内滚动,您只需用您打算在其中滚动的特定元素替换“body”。在下面的示例中,我通过“getElementById”获取该元素:

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

例如,YouTube就是这种情况……

解决方案 17:

ScrollTo()功能不再起作用。这是我用过的,它工作正常。

driver.execute_script("document.getElementById('mydiv').scrollIntoView();")

解决方案 18:

根据文档,该课程ActionChains完成以下工作:

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').perform()

解决方案 19:

插入此行driver.execute_script("window.scrollBy(0,925)", "")

解决方案 20:

使用“发送键”方法滚动页面的循环:

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

解决方案 21:

下面是我编写的一种方法,用于缓慢向下滚动到目标元素

您可以将 CSS 选择器元素的第 Y 个位置传递给它

它就像我们通过鼠标滚轮滚动一样

一旦调用此方法,您就可以使用相同的驱动程序对象但使用新的目标元素再次调用它,然后它将在该元素存在的任何位置向上/向下滚动

def slow_scroll_to_element(self, driver, element_selector=None, target_yth_location=None):
    current_scroll_position = int(driver.execute_script("return window.scrollY"))
    
    if element_selector:
        target_yth_location = int(driver.execute_script("return document.querySelector('{}').getBoundingClientRect()['top'] + window.scrollY".format(element_selector)))
    
    scrollSpeed = 100 if target_yth_location-current_scroll_position > 0 else -100

    def chunks(a, n):
        k, m = divmod(len(a), n)
        return (a[i*k+min(i, m):(i+1)*k+min(i+1, m)] for i in range(n))
    
    for l in list(chunks(list(range(current_scroll_position, target_yth_location, scrollSpeed)) + list([target_yth_location+(-scrollSpeed if scrollSpeed > 0 else scrollSpeed)]), 3)):
        for pos in l:
            driver.execute_script("window.scrollTo(0, "+str(pos)+");")
            time.sleep(0.1)
        time.sleep(random.randint(1,3))

解决方案 22:

滚动到一个元素:找到该元素并使用此代码滚动。

scroll_element = driver.find_element(By.XPATH, "your element xpath")
driver.execute_script("arguments[0].scrollIntoView();", scroll_element)

解决方案 23:

您是否会考虑使用 Selenium 的扩展,这样您就不必自己编写所有代码了?我是Browserist软件包的作者。Browserist是 Selenium Web 驱动程序的轻量级、简洁的扩展,可让浏览器自动化变得更加容易。只需使用 安装该软件包即可pip install browserist

Browserist有多种滚动选项。无论是滚动到特定元素、向下或向上几个像素、向下或向上整个页面、页面末尾或顶部,只需几行代码即可。示例:

from browserist import Browser

browser = Browser()
browser.open.url("https://stackoverflow.com")
browser.scroll.into_view("/html/body/div[3]/div[2]/div[1]/div[3]/div/div/div[6]")
browser.scroll.page.to_end()
browser.scroll.page.to_top()
browser.scroll.page.down()
browser.scroll.down_by(100)
browser.scroll.up_by(50)

这是我得到的结果(由于Browserist完成工作很快,所以速度变慢了)。希望这对您有所帮助。如果您有疑问,请告诉我。

使用 Browserist 滚动的示例

解决方案 24:

有几种方法可以实现此目的,但如果您将它们用于无限加载网站,那么所有方法都有限制。

限制在于等待新滚动发生的时间,这非常糟糕,因为我们无法确定其他人的互联网速度。无论如何,如果我找到任何解决方案,我会更新这篇文章。

第一种解决方案

loading_waiting_time = 1

# Get actual page height
previous_page_height = driver.execute_script("return document.body.scrollHeight")

# Run infinte loop and stop it if new_page_height is equal to previous_page_height
while True:
    # Scroll to the end of page
    driver.execute_script('window.scrollTo(0, document.body.scrollHeight);')

    # Waiting until new images loaded
    time.sleep(loading_waiting_time)

    # Get new page height
    new_page_height = driver.execute_script("return document.body.scrollHeight")
    if new_page_height == previous_page_height:
        break
    previous_page_height = new_page_height

第二种解决方案该解决方案适用于非固定页脚。

loading_waiting_time = 1

# Get actual page height
previous_page_height = driver.execute_script("return document.body.scrollHeight")

# Run infinte loop and stop it if new_page_height is equal to previous_page_height
while True:
    # Scroll to `footer` using JS
    footer_element = driver.find_element(By.TAG_NAME, 'footer')
    driver.execute_script('arguments[0].scrollIntoView(true)', footer_element)
    
    # Waiting until new images loaded
    time.sleep(loading_waiting_time)

    # Get new page height
    new_page_height = driver.execute_script("return document.body.scrollHeight")
    if new_page_height == previous_page_height:
        break
    previous_page_height = new_page_height

第三种解决方案此解决方案适用于非固定页脚。

loading_waiting_time = 1

# Get actual page height
previous_page_height = driver.execute_script("return document.body.scrollHeight")

# Run infinte loop and stop it if new_page_height is equal to previous_page_height
while True:
    # Scroll to until `footer` is visible
    WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.TAG_NAME, 'footer')))

    # Waiting until new images loaded
    time.sleep(loading_waiting_time)

    # Get new page height
    new_page_height = driver.execute_script("return document.body.scrollHeight")
    if new_page_height == previous_page_height:
        break
    previous_page_height = new_page_height

解决方案 25:

driver.execute_script("document.getElementById('your ID Element').scrollIntoView();")

它对我的情况很有效。

解决方案 26:

到目前为止提供的解决方案只是一个小的变化:有时在抓取时您必须满足以下要求:

  • 继续一步一步滚动。否则,如果您总是跳到底部,某些元素仅作为容器/div 加载,但其内容不会被加载,因为它们从不可见(因为您直接跳到了底部);

  • 留出足够的时间来加载内容;

  • 不是一个无限滚动的页面,它有一个结尾,你必须识别何时到达结尾;

以下是一个简单的实现:

from time import sleep
def keep_scrolling_to_the_bottom():
    while True:
        previous_scrollY = my_web_driver.execute_script( 'return window.scrollY' )
        my_web_driver.execute_script( 'window.scrollBy( 0, 230 )' )
        sleep( 0.4 )
        if previous_scrollY == my_web_driver.execute_script( 'return window.scrollY' ):
            print( 'job done, reached the bottom!' )
            break

已在 Windows 7 x64、Python 3.8.0、selenium 4.1.3、Google Chrome 107.0.5304.107、房产租赁网站上测试并运行。

解决方案 27:

滚动到页面的特定元素、位置或末尾:

from selenium import webdriver

driver = webdriver.Chrome()
driver.get("https://example.com")

# Find the target element you want to scroll to
element = driver.find_element_by_id("target-element-id")



# Scroll to the target element
driver.execute_script("arguments[0].scrollIntoView();", element)

# Scroll to a specific position (x, y coordinates)
driver.execute_script("window.scrollTo(0, 500)")

# Scroll to the end of the page
driver.execute_script("window.scrollTo(0, document.body.scrollHeight)")
相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   1565  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1354  
  信创国产芯片作为信息技术创新的核心领域,对于推动国家自主可控生态建设具有至关重要的意义。在全球科技竞争日益激烈的背景下,实现信息技术的自主可控,摆脱对国外技术的依赖,已成为保障国家信息安全和产业可持续发展的关键。国产芯片作为信创产业的基石,其发展水平直接影响着整个信创生态的构建与完善。通过不断提升国产芯片的技术实力、产...
国产信创系统   21  
  信创生态建设旨在实现信息技术领域的自主创新和安全可控,涵盖了从硬件到软件的全产业链。随着数字化转型的加速,信创生态建设的重要性日益凸显,它不仅关乎国家的信息安全,更是推动产业升级和经济高质量发展的关键力量。然而,在推进信创生态建设的过程中,面临着诸多复杂且严峻的挑战,需要深入剖析并寻找切实可行的解决方案。技术创新难题技...
信创操作系统   27  
  信创产业作为国家信息技术创新发展的重要领域,对于保障国家信息安全、推动产业升级具有关键意义。而国产芯片作为信创产业的核心基石,其研发进展备受关注。在信创国产芯片的研发征程中,面临着诸多复杂且艰巨的难点,这些难点犹如一道道关卡,阻碍着国产芯片的快速发展。然而,科研人员和相关企业并未退缩,积极探索并提出了一系列切实可行的解...
国产化替代产品目录   28  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用