puppeteer是谷歌出的一个用于操控无头浏览器的框架,用来做爬虫的页面下载模块是非常不错的选择。
如果你写的是针对某一网站的专用爬虫,那么完全使用nodejs实现就行,如果你写的是爬取所有类型网站的通用爬虫,那么我建议你用一个熟悉的语言写爬虫引擎,Nodejs仅仅作为页面下载器。这和nodejs底层的实现和其特性有关。
使用方法
将puppeteer放到koa中,从而使得Node提供页面下载的接口,实现模块间的松耦合
部署后的问题
内存问题
对于web2.0页面下载,每个页面都会加载所有的内容,会导致一个连接占用大量的内存。对此,可以针对内存问题做以下优化
- 减少支持的最大连接数
- 对页面中png/jpg/gif等请求进行拦截中止
- 对puppeteer的Page限制跳转最长等待时间,避免出现一直等待
socket hang up (连接被挂断)
nodejs服务似乎会产生内存泄漏的问题(目前没有找到原因),所以随着任务的增多,内存似乎会产生堆积,造成任务响应整体变慢。所以此时容易造成大部分页面都有比较长的等待时间,此时也可以利用上文中的 对puppeteer的Page限制跳转最长等待时间,避免出现一直等待
。同时需要定期对页面下载模块的任务做重启的操作。
由于不清楚nodejs和npm如何实现定期重启任务的功能,所以针对该服务,可以使用注册该服务到systemctl中的方法,利用systemctl管理工具来管理服务的打开关闭。然后利用crontab来做定期重启的服务
具体实践如下:
# the puppeteer of node service
[Unit]
Description=puppeteer
[Service]
TimeoutStartSec=180
TimeoutStopSec=30
# exec
ExecStart=/usr/bin/node bin/www
ExecStop=/usr/bin/pkill node
# log
StandardOutput=syslog
StandardError=syslog
cron中设置两小时重启一次
1 */2 * * * /bin/systemctl restart puppeteer.service
这样就可以简单粗暴的解决内存泄漏带来的性能降低的问题