Flutter自动化控制插件puppeteer的使用
Flutter自动化控制插件puppeteer的使用
Puppeteer in Dart简介
Puppeteer in Dart 是一个用于通过 DevTools 协议自动控制 Chrome 浏览器的 Dart 库。它是基于Node.JS版本的Puppeteer库移植到Dart语言上的。
功能介绍
你可以使用 Puppeteer 实现大多数在浏览器中手动完成的任务,例如:
- 生成页面的截图和 PDF。
- 爬取单页应用(SPA)并生成预渲染内容(即“SSR”(服务器端渲染))。
- 自动化表单提交、UI 测试、键盘输入等操作。
- 创建一个最新的测试环境。直接在最新版本的 Chrome 中运行测试,利用最新的 JavaScript 和浏览器特性。
API 文档
- 完整的API文档
- Dart Doc 包文档
- Dart 版本的 Puppeteer 与原始的 Javascript 代码非常相似,几乎所有 Node.JS 的 Puppeteer 示例都可以轻松转换为 Dart。
示例代码
以下是几个简单的示例,展示了如何使用 Puppeteer in Dart 来执行各种任务:
启动Chrome
import 'package:puppeteer/puppeteer.dart';
void main() async {
// 下载Chrome二进制文件,启动它并连接到"DevTools"
var browser = await puppeteer.launch();
// 打开一个新标签页
var myPage = await browser.newPage();
// 跳转到一个网页并等待完全加载
await myPage.goto('https://dart.dev', wait: Until.networkIdle);
// 截图
await myPage.screenshot();
// 获取PDF
await myPage.pdf();
// 执行JavaScript获取标题
await myPage.evaluate<String>('() => document.title');
// 平滑关闭浏览器进程
await browser.close();
}
生成页面的PDF
import 'dart:io';
import 'package:puppeteer/puppeteer.dart';
void main() async {
// 启动浏览器并跳转到一个网页
var browser = await puppeteer.launch();
var page = await browser.newPage();
await page.goto('https://dart.dev', wait: Until.networkAlmostIdle);
// 强制设置屏幕媒体类型
await page.emulateMediaType(MediaType.screen);
// 捕获PDF并保存到文件
await page.pdf(
format: PaperFormat.a4,
printBackground: true,
pageRanges: '1',
output: File('example/_dart.pdf').openWrite(),
);
await browser.close();
}
截取整个HTML页面的截图
import 'dart:io';
import 'package:puppeteer/puppeteer.dart';
void main() async {
// 启动浏览器并跳转到一个网页
var browser = await puppeteer.launch();
var page = await browser.newPage();
// 设置特定手机的尺寸和用户代理
await page.emulate(puppeteer.devices.pixel2XL);
await page.goto('https://dart.dev', wait: Until.networkIdle);
// 截取页面的截图
var screenshot = await page.screenshot();
// 保存到文件
await File('example/_github.png').writeAsBytes(screenshot);
await browser.close();
}
截取页面中特定节点的截图
import 'dart:io';
import 'package:puppeteer/puppeteer.dart';
void main() async {
// 启动浏览器并跳转到一个网页
var browser = await puppeteer.launch();
var page = await browser.newPage();
await page.goto(
'https://pub.dev/documentation/puppeteer/latest/',
wait: Until.networkIdle,
);
// 选择页面中的元素
var form = await page.$('input[id="search-box"]');
// 截取元素的截图
var screenshot = await form.screenshot();
// 保存到文件
await File('example/_element.png').writeAsBytes(screenshot);
await browser.close();
}
交互页面并抓取内容
import 'package:puppeteer/puppeteer.dart';
void main() async {
var browser = await puppeteer.launch();
var page = await browser.newPage();
await page.goto(
'https://developers.google.com/web/',
wait: Until.networkIdle,
);
// 在搜索框中输入文本
await page.type('.devsite-search-field', 'Headless Chrome');
// 等待建议层出现并点击"显示所有结果"
var allResultsSelector = '.devsite-suggest-all-results';
await page.waitForSelector(allResultsSelector);
await page.click(allResultsSelector);
// 等待结果页面加载并显示结果
const resultsSelector = '.gsc-results .gsc-thumbnail-inside a.gs-title';
await page.waitForSelector(resultsSelector);
// 从页面中提取结果
var links = await page.evaluate<List<dynamic>>(
r'''resultsSelector => {
const anchors = Array.from(document.querySelectorAll(resultsSelector));
return anchors.map(anchor => {
const title = anchor.textContent.split('|')[0].trim();
return `${title} - ${anchor.href}`;
});
}''',
args: [resultsSelector],
);
print(links.join('\n'));
await browser.close();
}
创建单页应用的静态版本
import 'package:puppeteer/puppeteer.dart';
void main() async {
var browser = await puppeteer.launch();
var page = await browser.newPage();
await page.goto('https://w3c.github.io/');
// 使用辅助函数获取页面内容
var pageContent = await page.content;
print(pageContent);
// 或者直接执行JavaScript获取页面内容
var pageContent2 = await page.evaluate<String>(
'document.documentElement.outerHTML',
);
print(pageContent2);
await browser.close();
}
捕获页面的屏幕录制
import 'dart:convert';
import 'dart:io';
import 'package:image/image.dart' as image;
import 'package:puppeteer/puppeteer.dart';
import 'package:shelf/shelf_io.dart' as io;
import 'package:shelf_static/shelf_static.dart';
void main() async {
// 启动本地Web服务器并打开页面
var server = await io.serve(
createStaticHandler('example/html'),
'localhost',
0,
);
var browser = await puppeteer.launch();
var page = await browser.newPage();
await page.goto('http://localhost:${server.port}/rubiks_cube/index.html');
// 每一帧解码图像并使用image包创建动画GIF
image.Image? animation;
page.devTools.page.onScreencastFrame.listen((event) {
var frame = image.decodePng(base64.decode(event.data));
if (frame != null) {
if (animation == null) {
animation = frame;
} else {
animation!.addFrame(frame);
}
}
});
// 改变CSS动画速度
await page.devTools.animation.setPlaybackRate(240);
// 开始屏幕录制
await page.devTools.page.startScreencast(maxWidth: 150, maxHeight: 150);
// 等几秒后停止屏幕录制
await Future.delayed(Duration(seconds: 3));
await page.devTools.page.stopScreencast();
// 将所有帧编码为动画GIF文件
File(
'example/_rubkis_cube.gif',
).writeAsBytesSync(image.GifEncoder().encode(animation!));
await browser.close();
await server.close(force: true);
}
启动带有可见窗口的浏览器
import 'package:puppeteer/puppeteer.dart';
void main() async {
var browser = await puppeteer.launch(headless: false);
// 进行某些操作...
await browser.newPage();
await browser.close();
}
执行JavaScript代码
import 'package:puppeteer/puppeteer.dart';
void main() async {
var browser = await puppeteer.launch();
var page = await browser.newPage();
// 函数声明语法
await page.evaluate('function(x) { return x > 0; }', args: [7]);
// 简写语法
await page.evaluate('(x) => x > 0', args: [7]);
// 多行简写语法
await page.evaluate(
'''(x) => {
return x > 0;
}''',
args: [7],
);
// 带有异步的简写语法
await page.evaluate(
'''async (x) => {
return await x;
}''',
args: [7],
);
// 表达式
await page.evaluate('document.body');
await browser.close();
}
Flutter中的限制
此库的功能分为两部分:
- 下载 Chrome 二进制文件并启动 Chrome 进程。
- 通过 Websocket 连接到此进程,并发送 JSON 命令来控制浏览器。
由于移动平台(iOS 和 Android)的限制,在 iOS 和 Android 上无法启动外部 Chrome 进程。因此,第一步在移动设备上不可用。
你仍然可以在以下环境中使用 puppeteer-dart
:
- Flutter 桌面版(macOS, Windows, Linux)
- Flutter 移动端,但实际的 Chrome 实例需要在服务器上运行,并通过
puppeteer.connect
从移动端应用程序访问
相关工作
以上就是关于Flutter中使用Puppeteer进行自动化控制的相关内容,希望对你有所帮助!
更多关于Flutter自动化控制插件puppeteer的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter自动化控制插件puppeteer的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
在Flutter项目中,虽然直接使用Puppeteer(一个Node库,用于自动化控制Chrome或Chromium浏览器)进行自动化测试或控制并不常见,因为Puppeteer本质上是针对Web应用的,而Flutter主要是用于构建跨平台的移动和桌面应用。然而,你可以通过一些间接的方法将Puppeteer集成到你的Flutter开发流程中,例如,使用Puppeteer进行Web端的自动化测试,同时Flutter应用可能包含一个WebView组件来加载和展示Web内容。
以下是一个简化的示例,展示了如何在Flutter项目中调用Node.js脚本(该脚本使用Puppeteer),以便对某个Web页面进行自动化控制。这只是一个概念验证,实际项目中可能需要更复杂的设置。
1. 设置Node.js和Puppeteer环境
首先,确保你的开发环境中已经安装了Node.js和npm。然后,你可以通过npm安装Puppeteer:
npm install puppeteer
2. 编写Node.js脚本(使用Puppeteer)
创建一个名为script.js
的文件,并添加以下代码:
const puppeteer = require('puppeteer');
(async () => {
// 启动浏览器
const browser = await puppeteer.launch();
const page = await browser.newPage();
// 访问网页
await page.goto('https://example.com');
// 执行一些自动化操作,比如截图
await page.screenshot({ path: 'example.png' });
// 关闭浏览器
await browser.close();
})();
这个脚本将启动一个浏览器实例,访问https://example.com
,并截取屏幕截图保存为example.png
。
3. 在Flutter中调用Node.js脚本
为了在Flutter中调用这个Node.js脚本,你可以使用process_run
包来执行命令行命令。首先,在你的pubspec.yaml
文件中添加依赖:
dependencies:
flutter:
sdk: flutter
process_run: ^0.12.0 # 请检查最新版本号
然后,在你的Flutter项目中,例如在一个按钮点击事件中,执行以下代码:
import 'package:flutter/material.dart';
import 'package:process_run/cmd_run.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Flutter Puppeteer Example'),
),
body: Center(
child: ElevatedButton(
onPressed: () async {
// 执行Node.js脚本
var result = await runCmd('node script.js');
print(result.stdout);
print(result.stderr);
},
child: Text('Run Puppeteer Script'),
),
),
),
);
}
}
注意:runCmd
函数是一个简化的示例,实际使用中你可能需要根据process_run
包的API进行调整。process_run
包提供了更丰富的功能来处理进程执行和结果处理。
注意事项
-
跨平台兼容性:直接在Flutter应用中调用Node.js脚本在iOS上可能不可行,因为iOS设备通常不运行Node.js。这种方法更适合在开发机器或服务器上进行自动化测试。
-
安全性:确保你的Node.js脚本和Flutter应用之间的交互是安全的,特别是当处理敏感信息时。
-
性能:在Flutter应用中启动一个完整的浏览器实例可能会消耗较多资源,影响应用性能。
通过上述方法,你可以在Flutter项目中间接地使用Puppeteer进行Web端的自动化控制。然而,对于Flutter应用本身的自动化测试,建议使用专为Flutter设计的工具,如Flutter Driver或Integration Testing。