之前开发了一个工具包 GerapyPyppeteer,GitHub 地址为 https://github.com/Gerapy/GerapyPyppeteer,这个包实现了 Scrapy 和 Pyppeteer 的对接,利用它我们就可以方便地实现 Scrapy 使用 Pyppeteer 爬取动态渲染的页面了。 另外,很多朋友在运行爬虫的时候可能会使用到 Docker,想把 Scrapy 和 Pyppeteer 打包成 Docker 运行,但是这个打包和测试过程中大家可能会遇到一些问题,在这里对 Pyppeteer 打包 Docker 的坑简单做一下总结。
概述
Pyppeteer 打包 Docker 主要是有这么几个坑点:
- 依赖没有安装,导致无法正确安装和启动 Pyppeteer。
- 没有关闭沙盒模式,导致可能出现 Browser closed unexpectedly 错误
- 没有提前安装好 Pyppeteer,导致每次启动时都要重新安装
下面我们分别对三个问题做下简单的 Troubleshooting。
安装依赖
首先说第一个,安装依赖。 因为 Docker 大部分都是基于 Linux 系统的,比如我常用的基础镜像就是 python:3.7
,剩余 Debian 系列,当然还有很多其他的版本,具体可以查看 https://hub.docker.com/_/python 了解下。 但是对于 Pyppeteer 来说,python:3.7
内置的依赖库并不够,我们还需要额外进行安装,安装完毕之后还需要清空下 apt list,一句 Dockerfile 命令如下:
1 |
RUN apt-get update && |
关闭沙盒模式
在 Docker 中如果直接启动 Pyppeteer,我们还需要关闭沙盒模式,否则可能会遇到如下错误:
1 |
pyppeteer.errors.BrowserError: Browser closed unexpectedly: |
这里提示我们要关闭沙盒模式,这里只需要在启动 Pyppeteer 的时候,给 launch 方法的 args 参数多加一个 \--no-sandbox
即可,写法如下:
1 |
browser = await pyppeteer.launch(options={'args': ['--no-sandbox']}) |
这样就不会再遇到上面的错误了。
提前安装
另外建议在打包 Docker 的时候就提前把 Pyppeteer 提前安装好,可以单独使用一句 RUN 命令安装即可。
1 |
RUN pip install -U pip && pip install pyppeteer && pyppeteer-install |
这里是提前安装了一下 Pyppteer 这个 Python 库,然后利用 Python 库提供的 pyppeteer-install 命令提前下载了 Chromium 浏览器。 这样后面启动的时候就可以直接唤起 Chromium 浏览器进行爬取了。
总结
最后看下完整 Dockerfile,内容如下:
1 |
FROM python:3.7 |
这里首先就是安装了必须的依赖库,然后安装了 Pyppeteer 并下载了 Chromium 浏览器,最后拷贝项目运行即可。 当然最后的一句 CMD 大家可以随意指定入口。 最后大家可以体验一个实例来感受下 Scrapy 和 Pyppeteer 对接后在 Docker 中的运行效果:
1 |
docker run germey/gerapy-pyppeteer-example |
如果大家对 Scrapy 和 Pyppeteer 感兴趣也可以看下我写的这个库 GerapyPyppeteer,GitHub 地址为 https://github.com/Gerapy/GerapyPyppeteer,感谢支持!