ele.input
返回: Noneele.input(text, clear=False)向输入框输入文字。clear=True 先清空再输入。
参数说明
| 参数 | 说明 |
|---|---|
| text | 要输入的文本。 |
| clear | True 先清空输入框,False 追加输入。 |
常见坑
- 部分框架的自定义输入框可能需要先 click() 聚焦。
相关示例
表单操作包括输入、选择、文件上传和表单提交。掌握 input/click/select 三个核心方法即可覆盖大部分场景。
ele.input(text, clear=False)向输入框输入文字。clear=True 先清空再输入。
| 参数 | 说明 |
|---|---|
| text | 要输入的文本。 |
| clear | True 先清空输入框,False 追加输入。 |
ele.click() / ele.click_self()点击元素。click() 滚动到元素后点击,click_self() 直接原地点击。
ele.select(value=None, text=None, index=None)选择 <select> 下拉框的选项。支持按 value/text/index 选择。
| 参数 | 说明 |
|---|---|
| value | option 的 value 属性值。 |
| text | option 的显示文本。 |
| index | option 的索引(从 0 开始)。 |
page.actions.press(key).perform()按键操作,常用于表单提交(Enter)、Tab 切换焦点。
| 参数 | 说明 |
|---|---|
| key | Keys 枚举值,如 Keys.ENTER、Keys.TAB。 |
| API | 说明 |
|---|---|
| ele.clear() | 清空输入框 |
| ele.attr('value') | 读取输入框当前值 |
| ele.attr('checked') | 读取复选框状态 |
| page.run_js('form.submit()') | JS 提交表单 |
from ruyipage import launch, Keys
page = launch()
try:
page.get("https://cn.bing.com/")
# 找到搜索框并输入
search_box = page.ele("#sb_form_q")
search_box.input("小肩膀教育", clear=True)
# 按 Enter 提交
page.actions.press(Keys.ENTER).perform()
page.wait(3)
print(f"搜索结果页: {page.title}")
finally:
page.quit()# 按显示文本选择
select_ele = page.ele("css:select#country")
select_ele.select(text="中国")
# 按 value 选择
select_ele.select(value="CN")
# 按索引选择
select_ele.select(index=0) # 选第一项围绕元素对象的高层交互,覆盖输入、点击、选择和状态读取。
源码文件:app/content/ruyipage_examples/03_element_interaction.py · 仓库:03_element_interaction.py
# =============================
# RuyiPage 示例注释版
# 标题: 元素交互:点击、输入、选择、悬停、表单提交
# 说明: 围绕元素对象的高层交互,覆盖输入、点击、选择和状态读取。
# 你会学到:
# 1. 点击按钮并读取页面反馈
# 2. 填写文本、邮箱、密码和数字输入框
# 3. 清空后重新输入
# 4. 切换复选框和单选框
# 5. 在原生模式与兼容模式下操作 select
# 相关 API: click_self, input, clear, value, select.by_value, double_click, right_click, hover
# =============================
# -*- coding: utf-8 -*-
"""
示例3: 元素交互
测试功能:
- 点击元素
- 输入文本
- 清空输入
- 双击、右键点击
- 鼠标悬停
- 拖拽
"""
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_element_interaction():
"""测试元素交互功能"""
print("=" * 60)
print("测试3: 元素交互")
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. 点击按钮:")
click_btn = page.ele("#click-btn")
click_btn.click_self()
page.wait(0.5)
result = page.ele("#click-result").text
print(f" 点击结果: {result}")
# 再点击几次
click_btn.click_self()
click_btn.click_self()
page.wait(0.5)
result = page.ele("#click-result").text
print(f" 多次点击后: {result}")
# 2. 输入文本
print("\n2. 输入文本:")
text_input = page.ele("#text-input")
text_input.input("Hello RuyiPage!")
page.wait(0.5)
print(f" 输入的值: {text_input.value}")
# 3. 清空并重新输入
print("\n3. 清空并重新输入:")
text_input.clear()
text_input.input("新的文本内容")
print(f" 新的值: {text_input.value}")
# 4. 输入到其他类型的输入框
print("\n4. 输入到不同类型的输入框:")
page.ele("#email-input").input("[email protected]")
page.ele("#password-input").input("password123")
page.ele("#number-input").input("42")
page.ele("#textarea").input("这是多行文本\n第二行\n第三行")
print(f" ✓ 所有输入框填写完成")
# 5. 复选框操作
print("\n5. 复选框操作:")
checkbox1 = page.ele("#checkbox1")
checkbox2 = page.ele("#checkbox2")
print(f" checkbox1初始状态: {checkbox1.is_checked}")
checkbox1.click_self()
page.wait(0.3)
print(f" checkbox1点击后: {checkbox1.is_checked}")
checkbox2.click_self()
page.wait(0.3)
print(f" checkbox2点击后: {checkbox2.is_checked}")
# 6. 单选框操作
print("\n6. 单选框操作:")
radio1 = page.ele("#radio1")
radio2 = page.ele("#radio2")
radio1.click_self()
page.wait(0.3)
print(f" radio1选中: {radio1.is_checked}")
radio2.click_self()
page.wait(0.3)
print(f" radio2选中: {radio2.is_checked}")
print(f" radio1现在: {radio1.is_checked}")
# 7. 下拉选择
print("\n7. 下拉选择:")
select = page.ele("#select-single")
# 教学建议:优先 native_only,失败再切 compat。
select_ok = select.select.by_value("opt2", mode="native_only")
if not select_ok:
print(" native_only 失败,切换到 compat 模式保底...")
select_ok = select.select.by_value("opt2", mode="compat")
page.wait(0.5)
print(f" 选中的值: {select.value}")
selected = select.select.selected_option
print(f" 选中的文本: {selected['text']}")
print(f" 原生选择结果: {select_ok}")
# 8. 双击
print("\n8. 双击按钮:")
dbl_btn = page.ele("#double-click-btn")
dbl_btn.double_click()
page.wait(0.5)
result = page.ele("#click-result").text
print(f" 双击结果: {result}")
# 9. 右键点击
print("\n9. 右键点击:")
right_btn = page.ele("#right-click-btn")
right_btn.right_click()
page.wait(0.5)
result = page.ele("#click-result").text
print(f" 右键点击结果: {result}")
# 10. 鼠标悬停
print("\n10. 鼠标悬停:")
hover_target = page.ele("#hover-target")
hover_target.hover()
page.wait(0.5)
hover_result = page.ele("#hover-result").text
print(f" 悬停结果: {hover_result}")
# 11. 提交表单
print("\n11. 提交表单:")
submit_btn = page.ele("#submit-btn")
submit_btn.click_self()
page.wait(0.5)
form_result = page.ele("#form-result").text
print(f" 表单结果: {form_result[:50]}...")
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_element_interaction()
连接 script 与 input 的高级能力,是 script 页的重要支撑示例。
源码文件:app/content/ruyipage_examples/29_script_input_advanced.py · 仓库:29_script_input_advanced.py
#!/usr/bin/env python
# =============================
# RuyiPage 示例注释版
# 标题: Script 与 Input 高级能力:realms、handle 回收、文件输入
# 说明: 连接 script 与 input 的高级能力,是 script 页的重要支撑示例。
# 你会学到:
# 1. 获取全部和 window 类型 realms
# 2. 执行脚本得到远程对象句柄
# 3. 回收单个和批量 handle
# 4. 利用 file input 上传单文件和多文件
# 相关 API: page.get_realms, page.eval_handle, page.disown_handles, ele.input
# =============================
# -*- coding: utf-8 -*-
"""示例29: Script + Input 高级能力(严格结果版)"""
import io
import os
import sys
from typing import Dict, List
if sys.platform == "win32":
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8")
sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding="utf-8")
from ruyipage import FirefoxPage, ScriptResult
def add_result(
results: List[Dict[str, str]], item: str, status: str, note: str
) -> None:
results.append({"item": item, "status": status, "note": note})
def print_results(results: List[Dict[str, str]]) -> None:
print("\n| 项目 | 状态 | 说明 |")
print("| --- | --- | --- |")
for row in results:
print(f"| {row['item']} | {row['status']} | {row['note']} |")
def main() -> None:
print("=" * 70)
print("测试 29: Script + Input 高级能力")
print("=" * 70)
page = FirefoxPage()
results: List[Dict[str, str]] = []
html_path = os.path.join(os.path.dirname(__file__), "test_file_input.html")
file1 = os.path.join(os.path.dirname(__file__), "test1.txt")
file2 = os.path.join(os.path.dirname(__file__), "test2.txt")
try:
page.get("https://www.example.com")
add_result(results, "页面加载", "成功", "example.com 已加载")
# 1. script.getRealms
realms = page.get_realms()
if realms:
add_result(
results, "script.getRealms all", "成功", f"realm 数量: {len(realms)}"
)
else:
add_result(results, "script.getRealms all", "失败", "未返回任何 realm")
window_realms = page.get_realms(type_="window")
if window_realms:
add_result(
results,
"script.getRealms window",
"成功",
f"window realm 数量: {len(window_realms)}",
)
else:
add_result(
results, "script.getRealms window", "失败", "未返回 window realm"
)
# 2. script.disown
single: ScriptResult = page.eval_handle("({data: 'test', array: [1, 2, 3]})")
if single.success and single.result.handle:
page.disown_handles([single.result.handle])
add_result(
results,
"script.disown single",
"成功",
f"handle={single.result.handle}",
)
else:
add_result(results, "script.disown single", "跳过", "脚本结果未返回 handle")
handles = []
for i in range(3):
item = page.eval_handle(f"({{id: {i}, value: 'test{i}'}})")
if item.success and item.result.handle:
handles.append(item.result.handle)
if handles:
page.disown_handles(handles)
add_result(
results, "script.disown batch", "成功", f"句柄数量: {len(handles)}"
)
else:
add_result(results, "script.disown batch", "跳过", "未拿到可用 handle")
# 3. input.setFiles 通过高层文件输入
html_content = """
<!DOCTYPE html>
<html>
<head><meta charset='utf-8'><title>File Input Test</title></head>
<body>
<input type='file' id='single-file' />
<input type='file' id='multiple-files' multiple />
<div id='result'></div>
<script>
document.getElementById('single-file').addEventListener('change', function(e) {
document.getElementById('result').textContent = 'Single file: ' + e.target.files[0].name;
});
document.getElementById('multiple-files').addEventListener('change', function(e) {
document.getElementById('result').textContent = 'Multiple files: ' + e.target.files.length;
});
</script>
</body>
</html>
"""
with open(html_path, "w", encoding="utf-8") as f:
f.write(html_content)
with open(file1, "w", encoding="utf-8") as f:
f.write("Test file 1 content")
with open(file2, "w", encoding="utf-8") as f:
f.write("Test file 2 content")
page.get(f"file:///{html_path.replace(os.sep, '/')}")
add_result(results, "文件测试页加载", "成功", "本地 file input 页面已加载")
page.ele("#single-file").input(file1)
single_text = page.ele("#result").text
if "test1.txt" in single_text:
add_result(results, "input.setFiles single", "成功", single_text)
else:
add_result(results, "input.setFiles single", "失败", single_text)
page.ele("#multiple-files").input([file1, file2])
multi_text = page.ele("#result").text
if "Multiple files: 2" in multi_text:
add_result(results, "input.setFiles multiple", "成功", multi_text)
else:
add_result(results, "input.setFiles multiple", "失败", multi_text)
print_results(results)
except Exception as e:
add_result(results, "示例执行", "失败", str(e)[:120])
print_results(results)
raise
finally:
for path in (file1, file2, html_path):
try:
if os.path.exists(path):
os.remove(path)
except Exception:
pass
try:
page.quit()
except Exception:
pass
if __name__ == "__main__":
main()
专门帮助排查 select 的焦点、键盘与 trusted change 路径问题。
源码文件:app/content/ruyipage_examples/36_native_bidi_select.py · 仓库:36_native_bidi_select.py
# =============================
# RuyiPage 示例注释版
# 标题: 原生 Select 选择:只测 native_only 模式与事件诊断
# 说明: 专门帮助排查 select 的焦点、键盘与 trusted change 路径问题。
# 你会学到:
# 1. 检查 select 初始状态
# 2. 聚焦后通过键盘切换选项
# 3. 强制只走 native_only 模式
# 4. 读取 changeCount 和 trustedChange 诊断信息
# 相关 API: select.by_value, select.selected_option, click_self, page.actions.key_down, page.actions.key_up, page.run_js
# =============================
# -*- coding: utf-8 -*-
"""
示例36: 原生 BiDi Select 检测(仅原生)
目标:
1) 只测试 native_only(不允许 JS 保底)
2) 输出分步诊断信息,帮助定位焦点/键盘路径问题
"""
import io
import os
import sys
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 FirefoxOptions, FirefoxPage, Keys
def _state(page, select):
s = page.run_js("return window.nativeBidiSelectState")
return {
"value": select.value,
"selected_option": select.select.selected_option,
"focused": s.get("focused"),
"trusted_change": s.get("trustedChange"),
"change_count": s.get("changeCount"),
"events": s.get("events", []),
}
def test_native_bidi_select():
print("=" * 60)
print("测试36: 原生 BiDi Select(仅原生)")
print("=" * 60)
opts = FirefoxOptions()
opts.headless(False)
page = FirefoxPage(opts)
try:
test_page = os.path.join(
os.path.dirname(__file__), "test_pages", "native_bidi_select_test.html"
)
test_url = "file:///" + os.path.abspath(test_page).replace("\\", "/")
page.get(test_url)
page.wait(1)
select = page.ele("#single-select")
print("\n1. 初始状态:")
st = _state(page, select)
print(f" value: {st['value']}")
print(f" selected_option: {st['selected_option']}")
print(f" focused: {st['focused']}")
print("\n2. 手动焦点探测(原生 click + 一步键盘):")
select.click_self()
page.wait(0.1)
page.actions.key_down(Keys.DOWN).key_up(Keys.DOWN).perform()
page.wait(0.1)
st_probe = _state(page, select)
print(f" probe value: {st_probe['value']}")
print(f" probe focused: {st_probe['focused']}")
print(f" probe changeCount: {st_probe['change_count']}")
print("\n3. 使用 selector native_only 选择 opt2:")
ok = select.select.by_value("opt2", mode="native_only")
page.wait(0.3)
st = _state(page, select)
print(f" native_only结果: {ok}")
print(f" value: {st['value']}")
print(f" selected_option: {st['selected_option']}")
print(f" focused: {st['focused']}")
print(f" trustedChange: {st['trusted_change']}")
print(f" changeCount: {st['change_count']}")
print("\n4. 页面事件日志:")
for line in st["events"]:
print(f" {line}")
if not ok or select.value != "opt2":
raise RuntimeError("native_only 未成功切换到 opt2")
print("\n" + "=" * 60)
print("✓ 原生 BiDi Select 测试通过!")
print("=" * 60)
except Exception as e:
print(f"\n✗ 测试失败: {e}")
import traceback
traceback.print_exc()
finally:
page.wait(1)
page.quit()
if __name__ == "__main__":
test_native_bidi_select()