之前开发了一个工具包 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 命令如下:
RUN apt-get update && \
apt-get -y install libnss3 xvfb gconf-service libasound2 libatk1.0-0 libc6 libcairo2 libcups2 \
libdbus-1-3 libexpat1 libfontconfig1 libgbm1 libgcc1 libgconf-2-4 libgdk-pixbuf2.0-0 libglib2.0-0 \
libgtk-3-0 libnspr4 libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcb1 \
libxcomposite1 libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 \
libxtst6 ca-certificates fonts-liberation libappindicator1 libnss3 lsb-release xdg-utils wget && \
rm -rf /var/lib/apt/lists/*
关闭沙盒模式
在 Docker 中如果直接启动 Pyppeteer,我们还需要关闭沙盒模式,否则可能会遇到如下错误:
pyppeteer.errors.BrowserError: Browser closed unexpectedly:
[0924/153706.301300:ERROR:zygote_host_impl_linux.cc(89)] Running as root without --no-sandbox is not supported. See https://crbug.com/638180
这里提示我们要关闭沙盒模式,这里只需要在启动 Pyppeteer 的时候,给 launch 方法的 args 参数多加一个 --no-sandbox 即可,写法如下:
browser = await pyppeteer.launch(options={'args': ['--no-sandbox']})
这样就不会再遇到上面的错误了。
提前安装
另外建议在打包 Docker 的时候就提前把 Pyppeteer 提前安装好,可以单独使用一句 RUN 命令安装即可。
RUN pip install -U pip && pip install pyppeteer && pyppeteer-install
这里是提前安装了一下 Pyppteer 这个 Python 库,然后利用 Python 库提供的 pyppeteer-install 命令提前下载了 Chromium 浏览器。
这样后面启动的时候就可以直接唤起 Chromium 浏览器进行爬取了。
总结
最后看下完整 Dockerfile,内容如下:
FROM python:3.7
RUN apt-get update && \
apt-get -y install libnss3 xvfb gconf-service libasound2 libatk1.0-0 libc6 libcairo2 libcups2 \
libdbus-1-3 libexpat1 libfontconfig1 libgbm1 libgcc1 libgconf-2-4 libgdk-pixbuf2.0-0 libglib2.0-0 \
libgtk-3-0 libnspr4 libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcb1 \
libxcomposite1 libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 \
libxtst6 ca-certificates fonts-liberation libappindicator1 libnss3 lsb-release xdg-utils wget && \
rm -rf /var/lib/apt/lists/*
RUN pip install -U pip && pip install pyppeteer && pyppeteer-install
WORKDIR /code
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
CMD python3 run.py
这里首先就是安装了必须的依赖库,然后安装了 Pyppeteer 并下载了 Chromium 浏览器,最后拷贝项目运行即可。
当然最后的一句 CMD 大家可以随意指定入口。
最后大家可以体验一个实例来感受下 Scrapy 和 Pyppeteer 对接后在 Docker 中的运行效果:
docker run germey/gerapy-pyppeteer-example
如果大家对 Scrapy 和 Pyppeteer 感兴趣也可以看下我写的这个库 GerapyPyppeteer,GitHub 地址为 https://github.com/Gerapy/GerapyPyppeteer,感谢支持!