Flutter for OpenHarmony:puppeteer 远程控制 Chrome 浏览器,实现截图与自动化操作(Headless Chrome 适配) 深度解析与鸿蒙适配指南
OpenHarmony远程浏览器控制方案 摘要:本文介绍了如何在OpenHarmony移动设备上通过puppeteer库实现远程浏览器控制功能。由于移动端无法直接运行Chrome,采用Client-Server模式:在PC/云端运行Chrome并开启远程调试端口,OpenHarmony应用通过WebSocket连接进行控制。文章详细讲解了环境配置、核心API使用(包括远程连接、截图和PDF生成)以
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net

前言
puppeteer 是一个 Node.js 库的 Dart 移植版,它提供了一套高级 API 来通过 DevTools 协议控制 Chrome 或 Chromium。通常用于爬虫、生成 PDF、截图或自动化测试。
在 OpenHarmony 移动设备上,直接启动一个 Headless Chrome 进程是不现实的(受限于系统权限和架构)。但是,我们可以利用 puppeteer 的远程连接能力,让 OpenHarmony 应用控制部署在服务器或局域网 PC 上的浏览器实例,实现强大的远程自动化功能。本文将介绍如何在 OpenHarmony 环境下使用 puppeteer 连接并控制远程浏览器。
一、puppeteer 简介与适用场景
1.1 核心功能
- 生成截图与 PDF:将网页转换为图片或文档。
- 爬取内容:抓取单页应用(SPA)的动态渲染内容。
- 自动化操作:模拟键盘输入、表单提交、UI 点击。
1.2 OpenHarmony 适配策略
由于移动端无法直接运行 Chrome 二进制文件,我们采用 Client-Server 模式:
- Server (PC/云端): 运行 Chrome 并开启远程调试端口 (
--remote-debugging-port)。 - Client (OpenHarmony): 使用
puppeteer.connect连接至 Server。
二、环境准备与配置
2.1 添加依赖
在 pubspec.yaml 中:
dependencies:
puppeteer: ^3.20.0
2.2 服务端配置(PC端)
你需要在一台电脑或服务器上启动 Chrome,允许远程调试。
# macOS 示例
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome \
--remote-debugging-port=9222 \
--headless \
--disable-gpu
确保 OpenHarmony 设备能 ping 通这台机器的 IP(例如 192.168.1.100)。

三、核心 API 详解与示例
3.1 示例一:连接远程浏览器
在 OpenHarmony 应用中连接到远程 Chrome 实例。
import 'package:puppeteer/puppeteer.dart';
Future<void> connectToBrowser() async {
// 替换为你 PC 的 IP 地址
final browser = await puppeteer.connect(
browserUrl: 'http://192.168.1.100:9222',
);
print('已连接到浏览器版本: ${await browser.version}');
// 记得关闭连接,但通常不关闭远程浏览器本身
await browser.disconnect();
}

3.2 示例二:远程截图
让远程浏览器打开网页截图,并将图片数据返回给 OpenHarmony 显示。
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:puppeteer/puppeteer.dart';
Future<Uint8List> takeScreenshot(String url) async {
final browser = await puppeteer.connect(
browserUrl: 'http://192.168.1.100:9222',
);
final page = await browser.newPage();
await page.goto(url, wait: Until.networkIdle);
// 截取全屏
final screenshot = await page.screenshot(fullPage: true);
await page.close();
await browser.disconnect();
return screenshot; // 返回二进制图片数据
}

3.3 示例三:生成 PDF
类似截图,生成 PDF 并保存(需配合文件权限)。
Future<void> generatePdf(String url) async {
final browser = await puppeteer.connect(
browserUrl: 'http://192.168.1.100:9222',
);
final page = await browser.newPage();
await page.goto(url);
final pdfData = await page.pdf(format: PaperFormat.a4);
print('PDF 生成成功,大小: ${pdfData.length} 字节');
await page.close();
await browser.disconnect();
}
四、OpenHarmony 平台适配
4.1 网络权限
连接远程调试端口需要 Internet 权限。在 module.json5 中配置:
"requestPermissions": [
{
"name": "ohos.permission.INTERNET"
}
]
4.2 异常处理
移动网络不稳定,连接远程实例时极易超时。务必添加 try-catch 和超时设置。
try {
await puppeteer.connect(..., timeout: Duration(seconds: 10));
} catch (e) {
// 提示用户检查网络或服务状态
}
五、完整实战示例:网页截图查看器
本示例是一个 OpenHarmony 应用,用户输入网址,点击按钮后,应用控制局域网内的 Chrome 截图并显示在屏幕上。
5.1 示例代码
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:puppeteer/puppeteer.dart';
void main() {
runApp(const MaterialApp(home: PuppeteerDemoPage()));
}
class PuppeteerDemoPage extends StatefulWidget {
const PuppeteerDemoPage({super.key});
State<PuppeteerDemoPage> createState() => _PuppeteerDemoPageState();
}
class _PuppeteerDemoPageState extends State<PuppeteerDemoPage> {
final TextEditingController _urlController =
TextEditingController(text: 'https://www.baidu.com');
// ⚠️ 请根据实际情况修改调试地址
final String _debugUrl = 'http://192.168.1.5:9222';
Uint8List? _imageData;
bool _isLoading = false;
String _status = '准备就绪';
Future<void> _captureScreen() async {
setState(() {
_isLoading = true;
_status = '正在连接远程浏览器...';
_imageData = null;
});
try {
// 1. 连接
final browser = await puppeteer.connect(
browserUrl: _debugUrl,
timeout: const Duration(seconds: 5), // 设置超时
);
setState(() => _status = '正在加载页面...');
// 2. 打开页面
final page = await browser.newPage();
// 设置视口大小以获得更好的截图效果
await page.setViewport(const DeviceViewport(width: 375, height: 812));
await page.goto(_urlController.text, wait: Until.networkIdle);
setState(() => _status = '正在截图...');
// 3. 截图
final screenshot = await page.screenshot();
// 4. 清理
await page.close();
await browser.disconnect();
if (mounted) {
setState(() {
_imageData = screenshot;
_status = '截图成功';
});
}
} catch (e) {
if (mounted) {
setState(() => _status = '错误: $e');
}
} finally {
if (mounted) {
setState(() => _isLoading = false);
}
}
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Puppeteer 远程截图')),
body: Column(
children: [
Padding(
padding: const EdgeInsets.all(16.0),
child: Row(
children: [
Expanded(
child: TextField(
controller: _urlController,
decoration: const InputDecoration(
labelText: '输入网址',
border: OutlineInputBorder(),
),
),
),
const SizedBox(width: 16),
ElevatedButton(
onPressed: _isLoading ? null : _captureScreen,
child: _isLoading
? const SizedBox(
width: 20,
height: 20,
child: CircularProgressIndicator(strokeWidth: 2),
)
: const Text('截图'),
),
],
),
),
Text(_status, style: const TextStyle(color: Colors.grey)),
const Divider(),
Expanded(
child: _imageData != null
? SingleChildScrollView(
child: Image.memory(
_imageData!,
fit: BoxFit.contain,
),
)
: const Center(
child: Icon(Icons.image, size: 64, color: Colors.grey),
),
),
],
),
);
}
}

六、总结
虽然 OpenHarmony 移动设备无法直接运行 puppeteer 驱动的本地 Chrome,但通过远程连接模式,我们可以将繁重的网页渲染和处理任务卸载到服务端,让 OpenHarmony 应用轻松拥有“超级浏览器”的能力。
最佳实践:
- 仅在受信任的网络环境中使用远程调试,注意安全。
- 对于简单的网页展示,优先使用
webview_flutter。 puppeteer适合用于需要服务端生成复杂内容(如报表 PDF)并回传给客户端的场景。
更多推荐
所有评论(0)