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

RuyiPage 移动端模拟

移动端模拟通过 apply_mobile_preset 一键配置视口、UA、触摸和屏幕尺寸,适合测试移动端页面和触摸交互。

核心 API

page.touch.tap

返回: None
page.touch.tap(ele_or_xy)

移动端触摸点击。

参数说明
参数说明
ele_or_xy元素或坐标。
常见坑
  • 需要先启用触摸或应用移动端预设。
相关示例

快速上手

python 模拟 iPhone 访问
from ruyipage import launch

page = launch()
try:
    # 应用 iPhone 预设
    page.emulation.apply_mobile_preset("iPhone 14")

    page.get("https://m.example.com")
    print(f"视口: {page.rect.viewport_size}")

    # 触摸操作
    page.touch.tap(page.ele("css:.menu-btn"))
    page.touch.swipe((200, 500), (200, 100))
finally:
    page.quit()

相关示例源码

2 个示例 ▶ 点击展开

移动端模拟访问 Google

examples/21_mobile_google_emulation.py

把移动端预设能力放到真实站点中验证,是 mobile 页的主示例。

GitHub 仓库 查看仓库源码 page.emulation.apply_mobile_presetpage.emulation.set_touch_enabledpage.getpage.run_jspage.title
  • 使用 iPhone 风格 UA 和视口访问 Google
  • 设置 locale 与 timezone
  • 检查 UA、innerWidth、devicePixelRatio
  • 验证移动页面是否正常加载

源码文件:app/content/ruyipage_examples/21_mobile_google_emulation.py · 仓库:21_mobile_google_emulation.py

python 注释版
# =============================
# RuyiPage 示例注释版
# 标题: 移动端模拟访问 Google
# 说明: 把移动端预设能力放到真实站点中验证,是 mobile 页的主示例。
# 你会学到:
#   1. 使用 iPhone 风格 UA 和视口访问 Google
#   2. 设置 locale 与 timezone
#   3. 检查 UA、innerWidth、devicePixelRatio
#   4. 验证移动页面是否正常加载
# 相关 API: page.emulation.apply_mobile_preset, page.emulation.set_touch_enabled, page.get, page.run_js, page.title
# =============================

# -*- coding: utf-8 -*-
"""示例21-Mobile: 移动端模拟访问 Google

目标:
1) 使用 RuyiPage 的移动端模拟接口
2) 访问 Google 首页
3) 验证 UA / 视口 / 页面标题

说明:
- 当前 Firefox 对 emulation.setTouchOverride 未实现,因此触摸支持可能显示为 False。
- 本示例重点验证“移动端参数模拟 + 页面访问”整体链路。
"""

import io
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")


from ruyipage import FirefoxOptions, FirefoxPage


def test_mobile_google_emulation():
    print("=" * 70)
    print("测试: 移动端模拟访问 Google")
    print("=" * 70)

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

    try:
        iphone_ua = (
            "Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) "
            "AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 "
            "Mobile/15E148 Safari/604.1"
        )

        print("\n1. 应用移动端模拟参数...")
        support = page.emulation.apply_mobile_preset(
            iphone_ua,
            width=390,
            height=844,
            device_pixel_ratio=3.0,
            orientation_type="portrait-primary",
            angle=0,
            locale="en-US",
            timezone_id="America/Los_Angeles",
            touch=False,
        )
        print(f"   基础支持情况: {support}")

        touch_results = {}
        for scope in ("context", "global", "user_context"):
            try:
                ok = page.emulation.set_touch_enabled(
                    True, max_touch_points=5, scope=scope
                )
            except Exception as e:
                ok = False
                print(f"   触摸作用域 {scope} 异常: {e}")
            page.refresh()
            touch_points = page.run_js("navigator.maxTouchPoints || 0")
            touch_results[scope] = {"supported": ok, "maxTouchPoints": touch_points}
        print(f"   触摸作用域结果: {touch_results}")

        print("\n2. 打开 Google 首页...")
        page.get("https://www.google.com/ncr")
        page.wait(2)

        print("\n3. 读取移动端环境信息...")
        ua = page.run_js("navigator.userAgent")
        width = page.run_js("window.innerWidth")
        height = page.run_js("window.innerHeight")
        dpr = page.run_js("window.devicePixelRatio")
        language = page.run_js("navigator.language")
        touch_points = page.run_js("navigator.maxTouchPoints || 0")
        title = page.title

        print(f"   页面标题: {title}")
        print(f"   UA: {ua}")
        print(f"   视口: {width}x{height}")
        print(f"   DPR: {dpr}")
        print(f"   语言: {language}")
        print(f"   maxTouchPoints: {touch_points}")

        ua_ok = "iPhone" in str(ua)
        viewport_ok = int(width) <= 500
        title_ok = "Google" in str(title)

        print("\n4. 结果判断...")
        print(f"   UA 命中移动端: {ua_ok}")
        print(f"   视口为移动端宽度: {viewport_ok}")
        print(f"   Google 页面打开成功: {title_ok}")

        if not (ua_ok and viewport_ok and title_ok):
            raise RuntimeError("移动端模拟访问 Google 的关键检查未全部通过")

        print("\n" + "=" * 70)
        print("✓ 移动端模拟访问 Google 测试通过")
        print("=" * 70)

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

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


if __name__ == "__main__":
    test_mobile_google_emulation()

Emulation 模块:UA、地理位置、时区、语言、屏幕与移动预设

examples/21_emulation.py

讲清 emulation 在 Firefox 路线上的主要能力边界。

GitHub 仓库 查看仓库源码 page.emulation.set_user_agentpage.emulation.set_geolocationpage.emulation.set_timezonepage.emulation.set_localepage.emulation.set_screen_orientationpage.emulation.set_screen_sizepage.emulation.set_network_offlinepage.emulation.set_touch_enabled
  • 覆盖 UA
  • 模拟地理位置、时区和语言
  • 设置屏幕尺寸和方向
  • 切换网络离线状态
  • 尝试开启触摸能力
  • 应用移动端预设

源码文件:app/content/ruyipage_examples/21_emulation.py · 仓库:21_emulation.py

python 注释版
#!/usr/bin/env python
# =============================
# RuyiPage 示例注释版
# 标题: Emulation 模块:UA、地理位置、时区、语言、屏幕与移动预设
# 说明: 讲清 emulation 在 Firefox 路线上的主要能力边界。
# 你会学到:
#   1. 覆盖 UA
#   2. 模拟地理位置、时区和语言
#   3. 设置屏幕尺寸和方向
#   4. 切换网络离线状态
#   5. 尝试开启触摸能力
# 相关 API: page.emulation.set_user_agent, page.emulation.set_geolocation, page.emulation.set_timezone, page.emulation.set_locale, page.emulation.set_screen_orientation, page.emulation.set_screen_size, page.emulation.set_network_offline, page.emulation.set_touch_enabled
# =============================

# -*- coding: utf-8 -*-
"""示例21: Emulation 模块测试(严格结果版)"""

import io
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")

from ruyipage import FirefoxPage


class Row:
    def __init__(self):
        self.rows = []

    def add(self, name, status, detail=""):
        self.rows.append((name, status, detail))
        print(f"  {status}: {name}")
        if detail:
            print(f"     详情: {detail}")

    def table(self):
        print("\n" + "=" * 70)
        print("测试结果汇总")
        print("=" * 70)
        print(f"{'序号':<5} {'项目':<32} {'状态':<8} {'说明'}")
        print("-" * 70)
        for i, (name, status, detail) in enumerate(self.rows, 1):
            print(f"{i:<5} {name:<32} {status:<8} {detail[:32]}")
        print("-" * 70)


def test_emulation():
    print("=" * 70)
    print("测试 21: Emulation 模块")
    print("=" * 70)

    page = FirefoxPage()
    rows = Row()

    try:
        page.get("data:text/html,<html><body><h1>Emulation Test</h1></body></html>")

        # 1) UA
        original_ua = page.run_js("navigator.userAgent")
        custom_ua = (
            "Mozilla/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X) "
            "AppleWebKit/605.1.15"
        )
        page.emulation.set_user_agent(custom_ua)
        page.refresh()
        new_ua = page.run_js("navigator.userAgent")
        rows.add(
            "User-Agent 覆盖",
            "✓ 通过" if custom_ua in str(new_ua) else "✗ 失败",
            f"UA={'命中' if custom_ua in str(new_ua) else '未命中'}",
        )

        # 2) geolocation
        try:
            page.emulation.set_geolocation(39.9042, 116.4074, accuracy=100)
            rows.add("地理位置覆盖", "✓ 通过", "命令执行成功")
        except Exception as e:
            rows.add("地理位置覆盖", "✗ 失败", str(e))

        # 3) timezone
        try:
            page.emulation.set_timezone("America/New_York")
            page.refresh()
            timezone = page.run_js("Intl.DateTimeFormat().resolvedOptions().timeZone")
            ok = "New_York" in str(timezone)
            rows.add("时区覆盖", "✓ 通过" if ok else "✗ 失败", f"当前={timezone}")
        except Exception as e:
            rows.add("时区覆盖", "✗ 失败", str(e))

        # 4) locale
        try:
            page.emulation.set_locale("ja-JP")
            page.refresh()
            language = page.run_js("navigator.language")
            ok = "ja" in str(language).lower()
            rows.add("语言覆盖", "✓ 通过" if ok else "✗ 失败", f"当前={language}")
        except Exception as e:
            rows.add("语言覆盖", "✗ 失败", str(e))

        # 5) orientation
        try:
            page.emulation.set_screen_orientation("landscape-primary", angle=90)
            page.refresh()
            orientation = page.run_js("screen.orientation.type")
            ok = "landscape" in str(orientation)
            rows.add(
                "屏幕方向覆盖", "✓ 通过" if ok else "✗ 失败", f"当前={orientation}"
            )
        except Exception as e:
            rows.add("屏幕方向覆盖", "✗ 失败", str(e))

        # 6) screen settings
        try:
            page.emulation.set_screen_size(1920, 1080, device_pixel_ratio=2.0)
            page.refresh()
            sw = page.run_js("screen.width")
            sh = page.run_js("screen.height")
            ok = sw == 1920 and sh == 1080
            rows.add("屏幕设置覆盖", "✓ 通过" if ok else "✗ 失败", f"当前={sw}x{sh}")
        except Exception as e:
            rows.add("屏幕设置覆盖", "✗ 失败", str(e))

        # 7) network offline
        supported = page.emulation.set_network_offline(True)
        rows.add(
            "网络条件模拟",
            "✓ 通过" if supported else "⚠ 不支持",
            "离线模式" if supported else "当前 Firefox 未实现",
        )

        # 8) touch override
        supported = page.emulation.set_touch_enabled(True)
        rows.add(
            "触摸模拟",
            "✓ 通过" if supported else "⚠ 不支持",
            "启用触摸" if supported else "当前 Firefox 未实现",
        )

        # 9) javascript enable
        supported = page.emulation.set_javascript_enabled(True)
        rows.add(
            "JavaScript 开关",
            "✓ 通过" if supported else "⚠ 不支持",
            "启用 JS" if supported else "当前 Firefox 未实现",
        )

        # 10) scrollbar
        supported = page.emulation.set_scrollbar_type("overlay")
        rows.add(
            "滚动条类型",
            "✓ 通过" if supported else "⚠ 不支持",
            "overlay" if supported else "当前 Firefox 未实现",
        )

        # 11) forced colors
        supported = page.emulation.set_forced_colors_mode("dark")
        rows.add(
            "强制颜色模式",
            "✓ 通过" if supported else "⚠ 不支持",
            "dark" if supported else "当前 Firefox 未实现",
        )

        # 12) bypass csp
        supported = page.emulation.set_bypass_csp(True)
        rows.add(
            "CSP 绕过",
            "✓ 通过" if supported else "⚠ 不支持",
            "enabled=True" if supported else "当前 Firefox 未实现",
        )

        # 13) mobile preset
        support = page.emulation.apply_mobile_preset(
            custom_ua,
            width=390,
            height=844,
            device_pixel_ratio=3.0,
            orientation_type="portrait-primary",
            angle=0,
            locale="en-US",
            timezone_id="America/New_York",
            touch=True,
        )
        rows.add("移动端预设", "✓ 通过", str(support))

        print("\n" + "=" * 70)
        print("✓ Emulation 模块测试完成")
        print("=" * 70)
    finally:
        rows.table()
        page.quit()


if __name__ == "__main__":
    test_emulation()