几行代码搭建一个网页转 PDF 的服务 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
爱意满满的作品展示区。
chengkai
V2EX    分享创造

几行代码搭建一个网页转 PDF 的服务

  •  
  •   chengkai
    examplecode 2019-11-12 15:50:59 +08:00 5781 次点击
    这是一个创建于 2163 天前的主题,其中的信息可能已经有所发展或是发生改变。

    搭建一个网页转 pdf 的服务实际上只需几行代码,转给有需要的同学,正文如下。

    原文链接:http://doc.xbext.com/devopt/using-puppeter-convert-webpage-to-pdf-and-fullpage-screenshot/

    最近需要为x 浏览器 提供一个网页转 PDF 的服务,鉴于 X 浏览器定位是一个简洁轻便的手机浏览器产品,所以打算在服务端实现这一功能,同时为了更好的为 X 浏览器客户端服务,所以准备自己尝试搭建这么一套服务。去年的时候曾经看到过关于 Puppeteer 的相关文章,知道通过这个产品可以实现网页转 pdf 以及生成整页截图。这篇文章用来记录如何使用这组件来搭建一个网页转 pdf 的服务。

    什么是 Puppeteer

    Puppeteer 是由 GoogleChrome 团队维护的一套基于 NodeJs 的 API 用于操控HeadLess Chrome 。headless chrome 其实是一个没有 UI 界面的 Chrome 浏览器,除此之外几乎和真正的 Chrome 没有差别。这时候你可能会奇怪没有界面的 Chrome 怎么用啊?是的对于普通用户来讲 Headless Chrome 确实无法使用,但是对于一些自动化测试的场景使用 Headless Chrome 就太方便了。我们只要通过命令行就可以对 Chrome 进行操控完成普通浏览器所用使用场景,打开页面,填写表单,点击按钮,甚至模拟鼠标及触屏,都完全不在话下。

    Puppeteer 提供了一套完备的API使我们我们可以方便的操控 Chrome,我们通过 UI 界面可以完成的操作都可以通过 Puppeteer 来实现。

    下面介绍如何安装 Puppeteer 以及使用 Puppeteer 提供整页截图和生成 pdf 文件。

    在 Linux 环境下部署 Puppeteer

    为了安装部署方便,我们选择 ubutun 18.04 作为后台服务,在这之前我需要先安装 NodeJs 运行环境,Puppeteer 的一些最新特性需要在 Node v7.6.0 或更高版本中才被支持。所以我们选择安装 NodeJs 的 8.x 版本。

    curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash - sudo apt-get install -y nodejs 

    安装 Puppeteer

    mkdir puppeteer-demo cd puppeteer-demo npm i puppeteer 

    安装的过程中会自动下载 HeadlessChrom, 完整安装后我们可以通过下面的脚本测试 puppeteer 是否可以和 HeadlessChrom 一起正常工作。

    //version.js const puppeteer = require('puppeteer'); (async() => { const browser = await puppeteer.launch(); console.log(await browser.version()); await browser.close(); })(); 

    运行脚本

    node verison.js 

    工作正常的话会显示 headless chromed 的版本号

    HeadlessChrome/79.0.3945.0 

    转换网页到 pdf 格式

    下面的代码展示了使用 Puppeteer 如何把网页转换为 pdf 格式.

    const puppeteer = require('puppeteer'); (async() => { const browser = await puppeteer.launch(); const page = await browser.newPage(); await page.goto('https://www.xbext.com', {waitUntil: 'networkidle2'}); await page.pdf({path: 'page.pdf', format: 'A4'}); await browser.close(); })(); 

    生成整页网页截图

    下面代码展示了如何模仿手机作为请求,并且生成整个网页的截图

    const puppeteer = require('puppeteer'); (async () => { const browser = await puppeteer.launch(); let page = await browser.newPage(); const userAgent = "Mozilla/5.0 (Linux; Android 8.1.0; MI 8 Build/OPM1.171019.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/62.0.3202.84 Mobile Safari/537.36"; page.setUserAgent(userAgent); //await page.setViewport({ width: 1920, height: 1080 }); await page.setViewport({ width: 480, height: 800,isMobile: true}); await page.goto('https://www.xbext.com',{waitUntil: 'networkidle2'}); await page.screenshot({path: 'myscreeshot.png',fullPage: true}); //如图片过大可以通过生成.jpg 文件并且控制图标质量 //await page.screenshot({path: 'myscreeshot.jpg',fullPage: true,quality: 80}); await browser.close(); })(); 

    相关问题

    运行 puppeteer 脚本时候无法启动 Chrome ,提示如下错误

    chrome-linux/chrome: error while loading shared libraries: libasound.so.2 

    安装缺失的库即可

    sudo apt-get install libasound2 

    无法渲染中文

    生成 pdf 或截图的时候,中文字符显示为一个个小方块,是因为缺失中文字体文件,导致 chromium 无法正常渲染,使用下面的命令安装即可.

    sudo apt-get install language-pack-zh* sudo apt-get install chinese* 

    参考资料

    https://developers.google.com/web/updates/2017/04/headless-chrome

    6 条回复    2019-11-15 15:38:48 +08:00
    aisusu
        1
    aisusu  
       2019-11-12 16:10:35 +08:00
    Puppeteer 的另一个应用场景是爬虫,用于搞定 JS 渲染页面的内容抓取。
    djyde
        2
    djyde  
       2019-11-13 16:14:08 +08:00
    liuzhaowei55
        3
    liuzhaowei55  
       2019-11-14 11:39:4 +08:00
    推荐一个猜测是 wikipedia 现在在用的 PDF 渲染库:
    https://github.com/msokk/electron-render-service
    不过这个库现在 GitHub 标记 DEPRECATED,推荐了另外一个库:
    https://github.com/alvarcarto/url-to-pdf-api
    chengkai
        4
    chengkai  
    OP
       2019-11-14 15:58:57 +08:00
    @djyde 这倒是一个不错的商业模式,可以拿来收钱了。不过这个东西容易被滥用,尤其是在国内搞一些撸羊毛的活动。
    chengkai
        5
    chengkai  
    OP
       2019-11-14 16:03:51 +08:00
    @liuzhaowei55 其底层原理都是基于 HeadlessChrome , 使用 Puppeteer 更加简单。
    6IbA2bj5ip3tK49j
        6
    6IbA2bj5ip3tK49j  
       2019-11-15 15:38:48 +08:00
    这个生成的 PDF 是可编辑的吗?(可以选择里面的文字,图片,可点击)
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5477 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 28ms UTC 07:12 PVG 15:12 LAX 00:12 JFK 03:12
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86