puppeteer的简单使用

介绍一下用puppeteer的背景,因为公司产品开发需要,在移动端上需要去预览一些网页,并且能把它转换成pdf的模式,正好又接触到了google开源的puppeteer,所以顺势可以写一个node的中间件。

 技术选型这块,我用的是koa2来接受移动端的请求,因为网页的配置是需要注入一些cookie进去,不然ajax请求会失败,本身网页 和 iOS 都是我开发的,所以一个人做起来,不用去沟通,比较省事,那么下面进入正题,具体来讲解一下操作过程。

什么是puppeteer?

Puppeteer is a Node library which provides a high-level API to control headless Chrome or Chromium over the DevTools Protocol. It can also be configured to use full (non-headless) Chrome or Chromium.

以上是github的一段介绍,用我的理解就是,你可以不用打开chrome页面,也能来操作网页,并且还附带了一些I/O操作。

基于koa2的配置

   我最近是比较喜欢用koa2来做web服务的,大势所趋吧,如果要图方便,可以直接用狼叔的koa脚手架来搞,这个GitHub地址 koa2脚手架,根据教程创好文件之后,安装puppeteer。

npm install puppeteer --save


ok,基本的配置都搞定了,那么接下来就可以撸代码。我贴一点核心的代码,然后配上注释,大家应该就能理解,这个不难,仅需一点node的知识就可以。

准备一个接口,localhost:3000/api/pdf  ,这个api接口呢,是接受前端或者移动端的请求,并相应的做出响应的。代码如下。

router.post('/pdf',pdfView.save)

router.prefix('/api') router.post('/pdf',pdfView.save)


在vc里对应的开始写核心方法,引用pupp,引入一个对象存储,为了方便生成好的pdf,我偷懒用了leancloud,把数据上传上去,然后回调的pdf url 传给请求端。

const puppeteer = require('puppeteer');

var AV = require('leancloud-storage');


然后准备开始撸核心代码,下面的是处理事务的核心代码,里面有几个注意事项,首先用的是async awit语法糖 await返回的都是promise,puppeteer的api返回的都是promise,这个你们可以仔细读他的api,一般网站都是需要cookie,因为在http请求的,header总得拼点东西,然后你需要和你的前端沟通好,到底需要传什么东西给你,这样的话也利于调试。

async (ctx,next) => {

    let req = ctx.request.body

    const browser = await puppeteer.launch();

    const page = await browser.newPage();

//放一些你们网页的cookie

    page.setCookie({

        name: 'token',

        value: req.token,

        path: '/',

        domain: '.xxxx.com',

        httpOnly:false,

        secure:true,

    })

//设置js enabled

    await page.setJavaScriptEnabled(true)

//跳转网页

    await page.goto(`${这里写你们要的网址}`);

//生成pdf

    var pdfData = await page.pdf({path: `${生成名字}.pdf`, format: 'A4'});

//上传pdf数据

    var fileResult = await new AV.File(`${req.guid}.pdf`,pdfData).save()

//关闭browser

await browser.close();

//返回pdf 地址

    return ctx.body = fileResult.attributes.url

}


接下来,讲最最重要的东西!

如何去判断这个网页加载完成!!!我这里提供一个做法,做一个watchdog,比如用ajax或者axios 请求完数据之后,拼装好网页,让前端去生成一个节点,总之,一定要做一个告诉puppeteer网页已经加载完了!可以去生成pdf了。

$('body').append('

')


对应的node 代码是这样的,要写在page.goto()之前。

await page.waitForSelector('.nodeCompleted')


ok,大致的都讲完了,page.pdf() return的是buffer 接下来你可以做一些你们自定义的操作,比如把pdf存到服务器啥的,最后把这个pdf的链接回调给移动端,我再贴一点iOS的代码吧,方便理解,iOS 在线预览pdf 你可以用webview 也能用三方库,我用的是pdf reader。我贴点移动端与node交互的代码 ,仅供参考娱乐下哈。

[EdmHttpsManager POST:@"http://localhost:3100/api/pdf"params:dict ShowSVProgressHUD:YES success:^(idresponse,NSString*result) {

        [self addPdfReader:[response mj_JSONString]];

    }failure:^(NSError*error) {

    }];


等node端回调给你url之后,移动端下载进行保存

- (void)addPdfReader:(NSString*)url{

    NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];

    AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];

    NSURL*URL = [NSURLURLWithString:url];

    NSURLRequest *request = [NSURLRequest requestWithURL:URL];

    [EdmHttpsManager showProgressLoadingView];

    NSURLSessionDownloadTask*downloadTask = [managerdownloadTaskWithRequest:requestprogress:nildestination:^NSURL*(NSURL*targetPath,NSURLResponse*response) {

        NSURL *documentsDirectoryURL = [[NSFileManager defaultManager] URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:NO error:nil];

        return[documentsDirectoryURLURLByAppendingPathComponent:[responsesuggestedFilename]];

    }completionHandler:^(NSURLResponse*response,NSURL*filePath,NSError*error) {

        [EdmHttpsManager hideProgressLoadingView];

        ReaderDocument*doc = [[ReaderDocumentalloc]initWithFilePath:filePath.pathpassword:@""];

        ReaderViewController *rederVC = [[ReaderViewController alloc] initWithReaderDocument:doc];

        rederVC.delegate=self;

        rederVC.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;

        rederVC.modalPresentationStyle = UIModalPresentationOverFullScreen;

        [self presentViewController:rederVC animated:YES completion:nil];

    }];

    [downloadTaskresume];

}


ok,大致的都讲完了,这是我使用puppeteer的一点小小心得,欢迎大家一起交流交流。地址

你可能感兴趣的:(puppeteer的简单使用)