首页 > 其他分享 >异步框架tornado下使用pyppeteer将动态html转化为pdf

异步框架tornado下使用pyppeteer将动态html转化为pdf

时间:2022-11-04 11:56:11浏览次数:66  
标签:google 浏览器 tornado pyppeteer chrome html pdf

项目背景:

云上服务器存储html,前端通过传递给后端html_url, 由后端服务器获取html文件进行渲染,生成pdf,

然后将pdf上传云上服务器。

 

使用的框架/库:

tornado/ pyppeteer/docker

选择pyppeteer, 有如下依据: python官方库如xhtml2pdf只能处理类似富文本类的静态页面,而html需要js渲染, 

故借助浏览器是一种可行的实现方式; tornado是异步框架,pyppeteer是异步库,匹配。

 

实现过程:

1、选用pyppeteer的版本

tornado==5.1.1

pyppeteer==1.0.2

  

2、使用docker部署服务, 安装浏览器, dockerfile 如下:

FROM python:3.7-slim
COPY ./requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt -i http://mirrors.aliyun.com/pypi/simple --trusted-host mirrors.aliyun.com

# ===== 安装chrome浏览器, 配置 --no-sandbox =================
RUN apt-get update && apt-get install -y wget && \
    wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb && \
    apt-get install -y -f ./google-chrome-stable_current_amd64.deb && \
    sed -e '/chrome/ s/^#*/#/' -i /opt/google/chrome/google-chrome && \
    echo 'exec -a "$0" "$HERE/chrome" "$@" --user-data-dir="$HOME/.config/chrome" --no-sandbox --disable-dev-shm-usage' >> /opt/google/chrome/google-chrome
# ========================================================


# ========= 处理pyppeteer引起的僵尸进程问题 =================
ADD https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64 /usr/local/bin/dumb-init RUN chmod +x /usr/local/bin/dumb-init
# =======================================================
ADD . /project WORKDIR /project

 

3、实现模块

注意两个点: 下面两处注释处

    async def get_pdf_file2(self, opts):

        html_url = opts.get("html_url")

        browser = await pyppeteer.launch(
            {
                "executablePath": "/opt/google/chrome/google-chrome",  # docker配置的浏览器路径
                "timeout": 160000
            })
        page = await browser.newPage()

        # waitUntil参数: 直到 http 连接为 0,即页面加载完成
     # 这一步不配置, 会导致数据加载不完全,或数据未加载完毕浏览器关闭而导致报错 await page.goto(html_url, { 'waitUntil': 'networkidle0' }) pdf_file = await page.pdf({"format": 'A4'}) await browser.close() return pdf_file

  

第一次构建镜像会比较慢,耗时53分钟,之后就利用了docker的缓存, 速度就比较快了。

 

总结:

1、在实现过程中,遇到无法加载浏览器的原因,因为pyppeteer自身有下载headerless浏览器chrumium的实现,但由于docker中缺乏启动该浏览器的依赖,会导致无法启动浏览器,而安装依赖则亦是一个耗时较大的过程,而且中间会存在配置依赖的过程,故选择直接安装稳定版的浏览器,并将其配置成为非沙箱模式。

2、测试过程中发现会出现大量僵尸进程,原因是每一次访问,浏览器都会启动一次,并且产生浏览器的子进程,而browser.close()只能关闭浏览器主进程,子进程交给操作系统的init进程来处理,而docker的init进程是无法像正常操作系统一样处理这些子进程,导致他们无法被处理,形成僵尸进程。如果该问题不处理,最终将导致内存、端口被挤爆。

3、数据加载不完全,且出现运行异常

pyppeteer.errors.NetworkError: Protocol error Target.sendMessageToTarget: Target closed.

 原因是浏览器渲染过程中, 去服务器取动态数据,由于是异步过程,数据还未加载完全,浏览器就被程序关闭了。查看源码,先尝试了延迟时间,但依旧无法处理,而且增加耗时,用户体验变差。后来查看文档,配置了'waitUntil': 'networkidle0', 成功解决了这个问题。

 

4、一个使用比较广泛的库,一定会考虑得比较完善,所以遇到问题一定要仔细查看文档和源码,一般能找到解决方法。当然,也可以上网查看他人解决方法,他山之石,可以攻玉。

 

5、方案确定后,遇到这种问题,一定要深挖,解决问题总是在山重水复的时候,不经意间就豁然开朗了。而带来的收获可不止是工作上的、知识领域的,经历过的都会明白。

标签:google,浏览器,tornado,pyppeteer,chrome,html,pdf
From: https://www.cnblogs.com/wolfstark/p/16857263.html

相关文章

  • 微信小程序-wxParse插件的使用转化HTML到小程序识别的插件
    优点:目前已知唯一可以转化HTML到小程序识别的插件缺点:转换一个HTML标签可能需要大量的微信小程序标签还有样式配置:第一步,下载https://github.com/icindy/wxParse第二步......
  • CSS: Clip Or Crop Images In HTML CSS
     <!doctypehtml><html><head><metacharset="utf-8"> <metaname="viewport"content="width=device-width,initial-scale=1,maximum-scale=1"><metan......
  • html上传文件
    效果: 代码:<formaction="/"method="post"enctype="multipart/form-data"><div><inputclass="layui-btn"type="file"multiple="multiple"accept=......
  • html实现全选/取消全选
    效果: js://checkbox全选/取消全选functioncheckAll(){//1.获取编号前面的复选框varcheckAllEle=document.getElementById("box");......
  • html套用layui实现页面弹出层
    效果: 代码:<buttonid="add"onclick="useradd()"class="layui-btn"><iclass="layui-icon">评估</i></button>/*==========添加弹出层父页面button事件=......
  • html套用layui选择日期
    效果: 代码:layui.use('laydate',function(){varlaydate=layui.laydate;//执行一个laydate实例laydate.render({......
  • 导航栏下拉列表/vue/scss/html
    效果   scss样式 html 源码<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metahttp-equiv="X-UA-Compatible"content="IE=......
  • 网安——HTML学习
    一、HTML概述及发展史HTML全称(hypertextmarkuplanguage)译为超文本标记语言,其译文代表了HTML的含义,它和其他编程语言不同的是,HTML不是一门真正意义上编程语言,而是一种标......
  • htmlunit设置支持js和 ajax
    免责声明:不要拿爬虫在法律边缘试探简单的说,就是进行如下设置:webclient.getOptions().setUseInsecureSSL(true);//禁用css,一般来说css没啥用webclient.getOptions().setCs......
  • 2022-11-03 v-html will override element children.
    v-htmlwilloverrideelementchildren. v-html将覆盖元素子级。源代码:<divv-html="title"class="title">{{title}}</div>原因:使用了v-html的标签,该标签里面不能......