挖井

类库大魔王的挖井日记

挖一口属于自己的井


Go微信公众号爬虫踩坑实录

用Go开发微信公众号爬虫,踩到一些坑,记录如下。

  • 爬虫必然会开启大量http.Client去抓取内容,于是使用sync.Pool来管理这些http.Client,但是马上就会遇到sync.Pool返回一个nil出来,尝试换成自己写一个简单的Pool实现,仍然有相同问题,后来才发现原来在下面把变量改成nil然后放回pool去了。
  • 文章主体的HTML文本下载是很快的,内嵌的图片资源下载很花时间,尤其是有些文章会内嵌很多图片,所以要把下载HTML和下载图片的semaphore并发量按比例调整。比如说平均观察下来一个HTML内有10个图片资源,那么假设下载HTML的semaphore设成15个并发量,下载图片的semaphore则设成150个并发量。
  • 看情况调整http.Client的各个参数,比如Timeout,可以根据当前的网络情况和下载内容长度来设置,以提高http.Client的快速响应能力。
  • 在mac上运行时很快就遇到了进程打开fd数量限制,看了一下mac上才256,Linux桌面版或没调整过的服务器版默认可能是1024,确实很容易碰到,用lsof看了一下,原来是很多socket都打开着。http.Client得到response后,官方示例都是defer resp.Body.Close()在作用域退出时关闭,其实可以在读出response所有内容后立即关闭,但这并不能解决问题。后来发现是keep alive特性导致的,把http.Transport中的DisableKeepAlives设置成true即可。
  • sync.WaitGroup的记数器要尽早设置,以免还没来得及设置,Wait()就返回了。
  • 我用PhantomJS把抓下来的HTML文档转换为PDF格式,另一个方案是wkhtmltopdf,前者有更高的保真度,更多的可控性,但更慢更占内存,胜在最终效果好。
  • PhantomJS对本地路径的字符编码比较挑剔,比如在Windows上有中文字符的路径就不能正常工作,我的解决办法是找了个汉字转拼音的package,但这个package并不处理非中文的字符,所以要自己写些代码处理全英文或中英文混合的情况。
  • 之前我的实现是先把所有HTML和图片下载完,再一个个全部转换成PDF,这样很浪费时间,后来改成下载完一个HTML和它包含的所有图片资源就将其转换为PDF。

本文地址:

https://minidump.info/blog/2018/01/go-wxmp-crawler-develop-memoir/

上一篇

抓取微信公众号文章

一直想要抓取微信公众号文章,目前终于可以一半手动一半自动地抓取指定公众号的所有文章了。现在主流的大概是两种方法,一种是从搜狗那里抓取,另一种是通过中间人攻击的方式从客户端直接抓取,我是用的第二种,各有优缺点吧。从搜狗抓,需要绕开验证码,而且只能抓最新的10篇文章,有些公众号并没有被收录,等等。...…

Coding 全文阅读
下一篇

Go微信公众号爬虫踩坑实录(二)

过去一周仍然花了些时间更新微信公众号爬虫,又踩到些坑,记录一下。 之前是用semaphore来控制并发下载的goroutine数,后来发现这种方法看起来比较粗放,于是改成固定数量的goroutine池,比如固定30或50个goroutine一直跑着只用于下载HTML,固定15个gorouti...…

Coding 全文阅读