作为一个 20 年 Ruby 老粉,这篇文章主要分享一下我一开始觉得 4 周就能搞定的项目,是如何拖延到 4 个月的一些经验和教训。如果对产品有兴趣,请看文末的链接。
系统分析时,后端分 Web Server 和爬虫两块,作为 RSS 服务,对标 Feedly free plan 无可挑剔;社交部分对标 weibo,那就包括了:
数据 model 如下:
Web Server 这块也就是这些 model 的 CRUD 嘛,对于一个 CRUD 老男孩来说这有何难?
爬虫这几年积累了好几种,分别是:
逻辑就是爬完了用统一的 http post 发到 Web Server 的接收 api 就齐活儿。
Python/JavaScript/Ruby的爬虫都使用JSON进行数据汇总,基本的参数比如title/created_at/content/html/summary/author都没什么问题,一旦Web Server 端进行了 migration——比如 Atom 和 RSS 格式有用 published_at 的,newspaper3K 也有支持,表示文章的原始发布时间,更多爬来的文章没有这一项,会 fallback 到 created_at 上。published_at 这 column 本来没有,可以 migrate 一下吧?
Migrate 之后,发现要去 4 个爬虫进行修改,还是语言异构的——简直求生不得——直到某天一位爬虫界高人一语点醒:不应该使用任何 Headless Chrome 类的工具,如果是无需登录的资源,必然可以通过分析页面,而获得爬取方法。
我尝试了一下,某些要先下载 js 执行后再渲染的网站,手工进行 requests.get 和 parse 也很方便,这一步还可以数据化,在配置文件里写一段代码进行邪恶的 eval(配置文件里的代码都是自己准备的,不会有被黑的风险,没那么邪恶...吧)
关键是:省内存啊!为了无脑进行 DOM 生成和渲染需要加载 Headless Chrome 的 V8 引擎,连带这网站上所有的广告——最多我见过消耗 300M 内存的 Chrome 进程,而且如果不进行超时限制,4G 内存的豪华服务器也会被几个僵尸 worker 消耗到崩溃;设了超时吧,有些内容又加载不上——好吧,又得到人生一课:Headless Chrome 就不是拿来做生产爬虫用的。
我的 Huginn 是跑在 Docker 里,只负责监视 URL,有动静了就按照预定义的规则扒下来 post 出去——用 Python 改造一下也可以嘛!那些 Huginn 自带的 DOM 操作,Python 用 selectolax.parser 也可以做。干掉 Huginn 之后,省了不少装 Docker Image 的硬盘空间。
每篇文章都要生成 summary 和 tags,原来的 Ruby 和 JavaScript 爬虫不能做,得靠 crontab 从 Web Server 里拿出来进行二次处理 (蛋疼到无以复加),把异构的爬虫重构以后,现在同构了,都遵循如下步骤:
只考虑 API only 的 Rails 服务和上述爬虫的确如此,但涉及到洗爬来的数据和反复重构,理论上的活儿也不少——还没到实战呢:
基本功能上线后,先拿 V2EX 月经贴:“诸位大佬平时写博客吗”里收集来的博客地址进行测试。
为了易用性,可以直接输入博客的首页 HTML 地址而不是 RSS URL 添加源,这就需要在 Rails 里用 Ruby 对 HTML/RSS 进行预处理,一百多个博客录入下来:有超时的,有没提供 RSS/Atom 的,有拒绝除了 Webkit 之外 Agent 的(那你干嘛还出 RSS?),还有输出 RSS 格式不对的......还好 Feedjira 和 Nokogiri 够给力!
作为全(hen)周(cha)期(qian)开发者,锅当然推到前端的 Vue/Element UI/Buefy一家三口身上了!不过那就是另一个故事了...
阅读器已经做好上线了,产品逻辑在这篇文章里说了,有兴趣可以去体验一下: