全球动态代理 · 静态住宅代理 · 极高质量 · 包月不限量 · 学员低价 · 联系如意进行免费测试 · 欢迎公司及学员采购 · 另有任何海外数据采集需求,随时联系 · 商务合作微信:Charleval
Automation / 滚动
RuyiPage Docs

RuyiPage 滚动

滚动操作覆盖页面滚动、容器滚动和元素可见性判断。page.scroll 用于整页滚动,ele.scroll 用于可滚动容器。

核心 API

快速上手

python 页面滚动与容器滚动
from ruyipage import launch

page = launch()
try:
    page.get("https://example.com")

    # 滚动到底部
    page.scroll.to_bottom()

    # 滚动到指定元素
    footer = page.ele("tag:footer")
    page.scroll.to_see(footer)

    # 容器内滚动
    container = page.ele("css:.scroll-box")
    container.scroll.to_bottom()

    # 动作链滚轮滚动
    page.actions.scroll(0, 300)
finally:
    page.quit()

相关示例源码

2 个示例 ▶ 点击展开

滚动操作:页面滚动、容器滚动、滚动到元素

examples/10_scrolling.py

围绕滚轮和滚动可见性组织的一组常见交互。

GitHub 仓库 查看仓库源码 page.actions.scrollpage.scroll.to_bottompage.scroll.to_toppage.scroll.to_seeele.scroll.to_bottomele.scroll.to_topstates.is_in_viewport
  • 滚动到页面顶部与底部
  • 按像素距离滚动
  • 滚动直到目标元素进入视口
  • 控制容器内部滚动
  • 读取滚动位置用于调试

源码文件:app/content/ruyipage_examples/10_scrolling.py · 仓库:10_scrolling.py

python 注释版
# =============================
# RuyiPage 示例注释版
# 标题: 滚动操作:页面滚动、容器滚动、滚动到元素
# 说明: 围绕滚轮和滚动可见性组织的一组常见交互。
# 你会学到:
#   1. 滚动到页面顶部与底部
#   2. 按像素距离滚动
#   3. 滚动直到目标元素进入视口
#   4. 控制容器内部滚动
#   5. 读取滚动位置用于调试
# 相关 API: page.actions.scroll, page.scroll.to_bottom, page.scroll.to_top, page.scroll.to_see, ele.scroll.to_bottom, ele.scroll.to_top, states.is_in_viewport
# =============================

# -*- coding: utf-8 -*-
"""
示例10: 滚动操作
测试功能:
- 滚动到顶部/底部
- 滚动到元素
- 滚动指定距离
- 元素内滚动
"""

import os
import sys
import io

# 设置控制台输出编码为UTF-8(Windows兼容)
if sys.platform == "win32":
    sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8")
    sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding="utf-8")

sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))

from ruyipage import FirefoxPage, FirefoxOptions


def test_scrolling():
    """测试滚动操作功能"""
    print("=" * 60)
    print("测试10: 滚动操作")
    print("=" * 60)

    opts = FirefoxOptions()
    opts.headless(False)
    page = FirefoxPage(opts)

    try:
        # 加载测试页面
        test_page = os.path.join(
            os.path.dirname(__file__), "test_pages", "test_page.html"
        )
        test_url = "file:///" + os.path.abspath(test_page).replace("\\", "/")
        page.get(test_url)
        page.wait(1)

        # 1. 滚动到页面底部
        print("\n1. 滚动到页面底部:")
        page.actions.scroll(0, 4000).perform()
        page.wait(1)
        print(f"   ✓ 已滚动到底部")

        # 2. 滚动到页面顶部
        print("\n2. 滚动到页面顶部:")
        page.actions.scroll(0, -4000).perform()
        page.wait(1)
        print(f"   ✓ 已滚动到顶部")

        # 3. 滚动到特定元素
        print("\n3. 滚动到特定元素:")
        table_section = page.ele("#table-section")
        while not table_section.states.is_in_viewport:
            page.actions.scroll(0, 500).perform()
            page.wait(0.2)
        page.wait(1)
        print(f"   ✓ 已滚动到表格区域")

        # 4. 滚动指定像素
        print("\n4. 向下滚动500像素:")
        page.actions.scroll(0, 500).perform()
        page.wait(1)
        print(f"   ✓ 已向下滚动")

        # 5. 向上滚动
        print("\n5. 向上滚动300像素:")
        page.actions.scroll(0, -300).perform()
        page.wait(1)
        print(f"   ✓ 已向上滚动")

        # 6. 滚动到元素使其可见
        print("\n6. 滚动到元素使其可见:")
        form_section = page.ele("#form-section")
        while not form_section.states.is_in_viewport:
            page.actions.scroll(0, -400).perform()
            page.wait(0.2)
        page.wait(1)
        print(f"   ✓ 元素已滚动到可见区域")

        # 7. 元素内部滚动
        print("\n7. 元素内部滚动:")
        scroll_container = page.ele("#scroll-container")

        # 滚动容器到可见区域
        while not scroll_container.states.is_in_viewport:
            page.actions.scroll(0, 400).perform()
            page.wait(0.2)
        page.wait(0.5)

        # 在容器内滚动
        scroll_container.scroll.to_bottom()
        page.wait(1)
        print(f"   ✓ 容器已滚动到底部")

        scroll_container.scroll.to_top()
        page.wait(1)
        print(f"   ✓ 容器已滚动到顶部")

        # 8. 滚动到容器内的元素
        print("\n8. 滚动到容器内的元素:")
        scroll_target = page.ele("#scroll-target")
        scroll_container.scroll.to_see(scroll_target)
        page.wait(1)
        print(f"   ✓ 已滚动到目标元素")

        # 9. 获取滚动位置
        print("\n9. 获取页面滚动位置:")
        scroll_pos = page.run_js("return {x: window.scrollX, y: window.scrollY}")
        print(
            f"   当前滚动位置: X={scroll_pos.get('x', 0)}, Y={scroll_pos.get('y', 0)}"
        )

        # 10. 平滑滚动
        print("\n10. 平滑滚动到顶部:")
        page.actions.scroll(0, -4000).perform()
        page.wait(2)
        print(f"   ✓ 平滑滚动完成")

        # 11. 滚动到页面特定位置
        print("\n11. 滚动到页面中间:")
        page.actions.scroll(0, 500).perform()
        page.wait(1)
        print(f"   ✓ 已滚动到指定位置")

        # 12. 将元素滚动到视图
        print("\n12. 将元素滚动到视图:")
        network_section = page.ele("#network-section")
        while not network_section.states.is_in_viewport:
            page.actions.scroll(0, 450).perform()
            page.wait(0.2)
        page.wait(1)
        print(f"   ✓ 元素已滚动到视图")

        print("\n" + "=" * 60)
        print("✓ 所有滚动操作测试通过!")
        print("=" * 60)

    except Exception as e:
        print(f"\n✗ 测试失败: {e}")
        import traceback

        traceback.print_exc()
    finally:
        page.wait(2)
        page.quit()


if __name__ == "__main__":
    test_scrolling()

截图功能:整页、元素、base64、bytes

examples/06_screenshot.py

覆盖最常用的页面与元素截图输出能力。

GitHub 仓库 查看仓库源码 page.screenshotele.screenshotpage.scroll.to_seepage.scroll.to_bottom
  • 整页截图并保存到文件
  • 对单个元素或区域截图
  • 滚动到目标后截图
  • 获取截图的 base64 和 bytes 数据

源码文件:app/content/ruyipage_examples/06_screenshot.py · 仓库:06_screenshot.py

python 注释版
# =============================
# RuyiPage 示例注释版
# 标题: 截图功能:整页、元素、base64、bytes
# 说明: 覆盖最常用的页面与元素截图输出能力。
# 你会学到:
#   1. 整页截图并保存到文件
#   2. 对单个元素或区域截图
#   3. 滚动到目标后截图
#   4. 获取截图的 base64 和 bytes 数据
# 相关 API: page.screenshot, ele.screenshot, page.scroll.to_see, page.scroll.to_bottom
# =============================

# -*- coding: utf-8 -*-
"""
示例6: 截图功能
测试功能:
- 整页截图
- 元素截图
- 保存为文件
- 获取base64
- 获取bytes
"""

import os
import sys
import io

# 设置控制台输出编码为UTF-8(Windows兼容)
if sys.platform == 'win32':
    sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
    sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding='utf-8')

sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))

from ruyipage import FirefoxPage, FirefoxOptions

def test_screenshot():
    """测试截图功能"""
    print("=" * 60)
    print("测试6: 截图功能")
    print("=" * 60)

    opts = FirefoxOptions()
    opts.headless(False)
    page = FirefoxPage(opts)

    try:
        # 加载测试页面
        test_page = os.path.join(os.path.dirname(__file__), 'test_pages', 'test_page.html')
        test_url = 'file:///' + os.path.abspath(test_page).replace('\\', '/')
        page.get(test_url)
        page.wait(1)

        # 创建输出目录
        output_dir = os.path.join(os.path.dirname(__file__), 'output', 'screenshots')
        os.makedirs(output_dir, exist_ok=True)

        # 1. 整页截图
        print("\n1. 整页截图:")
        full_path = os.path.join(output_dir, 'full_page.png')
        page.screenshot(full_path)
        print(f"   ✓ 整页截图已保存: {full_path}")

        # 2. 元素截图
        print("\n2. 元素截图:")
        title = page.ele('#main-title')
        title_path = os.path.join(output_dir, 'title_element.png')
        title.screenshot(title_path)
        print(f"   ✓ 标题元素截图已保存: {title_path}")

        # 3. 表单区域截图
        print("\n3. 表单区域截图:")
        form_section = page.ele('#form-section')
        form_path = os.path.join(output_dir, 'form_section.png')
        form_section.screenshot(form_path)
        print(f"   ✓ 表单区域截图已保存: {form_path}")

        # 4. 按钮截图
        print("\n4. 按钮截图:")
        btn = page.ele('#click-btn')
        # 先滚动到按钮位置确保可见
        page.scroll.to_see(btn)
        page.wait(0.5)
        btn_path = os.path.join(output_dir, 'button.png')
        try:
            btn.screenshot(btn_path)
            print(f"   ✓ 按钮截图已保存: {btn_path}")
        except Exception as e:
            print(f"   ⚠ 按钮截图跳过(元素尺寸问题): {str(e)[:50]}")

        # 5. 获取截图的base64
        print("\n5. 获取截图base64:")
        base64_data = page.screenshot(as_base64=True)
        print(f"   ✓ Base64数据长度: {len(base64_data)} 字符")

        # 6. 获取截图的bytes
        print("\n6. 获取截图bytes:")
        bytes_data = page.screenshot(as_bytes=True)
        print(f"   ✓ Bytes数据长度: {len(bytes_data)} 字节")

        # 7. 元素base64截图
        print("\n7. 元素base64截图:")
        try:
            # 使用表单区域元素,它更稳定
            form_elem = page.ele('#form-section')
            elem_base64 = form_elem.screenshot(as_base64=True)
            print(f"   ✓ 元素Base64数据长度: {len(elem_base64)} 字符")
        except Exception as e:
            print(f"   ⚠ 元素base64截图跳过(元素尺寸问题): {str(e)[:50]}")

        # 8. 滚动后截图
        print("\n8. 滚动后截图:")
        page.scroll.to_bottom()
        page.wait(0.5)
        bottom_path = os.path.join(output_dir, 'page_bottom.png')
        page.screenshot(bottom_path)
        print(f"   ✓ 页面底部截图已保存: {bottom_path}")

        # 9. 表格截图
        print("\n9. 表格截图:")
        table = page.ele('#data-table')
        table_path = os.path.join(output_dir, 'table.png')
        try:
            page.scroll.to_see(table)
            page.wait(0.5)
            table.screenshot(table_path)
            print(f"   ✓ 表格截图已保存: {table_path}")
        except Exception as e:
            print(f"   ⚠ 表格截图跳过(元素尺寸问题): {str(e)[:50]}")

        print("\n" + "=" * 60)
        print("✓ 所有截图测试通过!")
        print(f"截图保存在: {output_dir}")
        print("=" * 60)

    except Exception as e:
        print(f"\n✗ 测试失败: {e}")
        import traceback
        traceback.print_exc()
    finally:
        page.wait(2)
        page.quit()

if __name__ == '__main__':
    test_screenshot()