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('<div class="nodeCompleted"></div>')


对应的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的一点小小心得,欢迎大家一起交流交流。地址

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容