page.scroll.to_top / to_bottom
返回: Nonepage.scroll.to_top() / page.scroll.to_bottom()页面级滚动到顶部或底部。
常见坑
- 无限滚动页面 to_bottom 只到当前已加载内容的底部。
相关示例
滚动操作覆盖页面滚动、容器滚动和元素可见性判断。page.scroll 用于整页滚动,ele.scroll 用于可滚动容器。
page.scroll.to_top() / page.scroll.to_bottom()页面级滚动到顶部或底部。
page.scroll.to_see(ele)滚动页面直到指定元素进入视口。
| 参数 | 说明 |
|---|---|
| ele | 目标元素。 |
page.scroll.by(x, y)按像素距离滚动页面。
| 参数 | 说明 |
|---|---|
| x | 水平滚动像素(正值向右)。 |
| y | 垂直滚动像素(正值向下)。 |
ele.scroll.to_top() / ele.scroll.to_bottom()在可滚动容器内滚动到顶部或底部。
page.actions.scroll(delta_x, delta_y)通过动作链模拟鼠标滚轮事件,产生 isTrusted=true。
| 参数 | 说明 |
|---|---|
| delta_x | 水平滚动量。 |
| delta_y | 垂直滚动量。 |
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()围绕滚轮和滚动可见性组织的一组常见交互。
源码文件:app/content/ruyipage_examples/10_scrolling.py · 仓库:10_scrolling.py
# =============================
# 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()
覆盖最常用的页面与元素截图输出能力。
源码文件:app/content/ruyipage_examples/06_screenshot.py · 仓库:06_screenshot.py
# =============================
# 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()