【问题标题】:Locating Lazy Load Elements While Scrolling in PhantomJS in Python在 Python 中的 PhantomJS 中滚动时定位延迟加载元素
【发布时间】:2017-02-15 16:47:21
【问题描述】:

我正在使用 python 和 Webdriver 从页面中抓取数据,该页面在用户向下滚动页面时动态加载内容(延迟加载)。我一共有 30 个数据元素,而没有先向下滚动就只显示了 15 个。

在多次滚动到页面底部直到每个元素都加载后,我正在定位我的元素,并通过以下方式获取它们的值:

# Get All Data Items
all_data = self.driver.find_elements_by_css_selector('div[some-attribute="some-attribute-value"]')

# Iterate Through Each Item, Get Value
data_value_list = []
for d in all_data:
    # Get Value for Each Data item
    data_value = d.find_element_by_css_selector('div[class="target-class"]').get_attribute('target-attribute')

    #Save Data Value to List
    data_value_list.append(data_value)

当我使用 ChromeDriver 执行上述代码时,同时将浏览器窗口留在我的屏幕上,我得到所有 30 个数据值来填充我的 data_value_list。当我使用 ChromeDriver 执行上述代码并最小化窗口时,我的列表 data_value_list 仅填充了最初的 15 个数据值。

使用 PhantomJS 时也会出现同样的问题,我的 data_value_list 仅限于页面上最初可见的数据值。

是否可以在最小化浏览器的同时加载这些类型的元素,最好是在使用 PhantomJS 的同时加载这些类型的元素?

注意:我正在使用操作链向下滚动,使用以下方法 .send_keys(Keys.PAGE_DOWN).perform() 计算次数。

【问题讨论】:

    标签: python web-scraping webdriver phantomjs


    【解决方案1】:

    我遇到了完全相同的问题。我找到的解决方案是在虚拟浏览器中执行 javascript 代码来强制元素滚动到底部。

    在将 Javascript 命令放入 selenium 之前,我建议在 Firefox 中打开您的页面并检查元素以找到可滚动的内容。该元素应该包含所有动态行,但它应该包含滚动条 然后,在使用 javascript 选择元素后,您可以通过将其 scrollTop 属性设置为它的 scrollHeight 属性来将其滚动到底部。

    然后,您需要在浏览器中测试滚动内容。如果元素有 id,则选择元素的最简单方法是通过 ID,但其他方式也可以。要选择 ID 为“scrollableContent”的元素并将其滚动到底部,请在浏览器的 javascript 控制台中执行以下代码:

    e = document.getElementById('scrollableContent'); e.scrollTop = e.scrollHeight;
    

    当然,这只会将内容滚动到当前顶部,如果您需要滚动多次,则需要在新内容加载后重复此操作。另外,我无法弄清楚如何找到确切的元素,对我来说这是反复试验。

    这是我尝试过的一些代码。但是,我觉得它可以改进,并且应该用于旨在测试代码或不可预测地抓取的应用程序。我不知道如何明确地等待直到加载更多元素(也许获取元素的数量,滚动到底部,然后等待子元素 + 1 出现,如果它们不退出循环),所以我硬编码了 5 个滚动事件并使用了 time.sleep。 time.sleep 很难看,可能会导致问题,部分原因是它取决于您机器的速度。

    def scrollElementToBottom(driver, element_id):
     time.sleep(.2)
     for i in range(5):
       driver.execute_script("e = document.getElementById('" + element_id + "'); e.scrollTop = e.scrollHeight;")
       time.sleep(.2)
    

    需要注意的是,以下解决方案适用于 Firefox 驱动程序,但我认为它没有理由不适用于您的设置。

    【讨论】:

    • 感谢您的回答,我认为我能够相当有效地确定何时停止滚动。您介意进一步详细说明“可滚动内容”的含义吗?您是指正在加载的其他 html 元素吗?所以我基本上会找到最后一个,滚动到它,然后找到下一个最后一个 - 滚动并重复直到我到达最后一个元素?
    • 通过“可滚动内容”,我的意思是 container,您可以滚动它包含元素,而不是其他元素。如果您尝试使用上面的代码将无法工作它在最后一个元素上。容器应该有其他元素作为子元素。我会尽量在我的帖子中更清楚地说明这一点。
    • 啊,我相信我现在明白了。我现在离开我的电脑有一段时间了,但我会尝试这种方法。
    猜你喜欢
    • 2015-11-04
    • 1970-01-01
    • 2023-02-19
    • 2022-01-19
    • 1970-01-01
    • 1970-01-01
    • 2013-10-27
    • 2011-07-20
    • 2021-05-30
    相关资源
    最近更新 更多