前两天,我打算下载点图片。用fiddler分析了下,结果那个网页大量使用js来操作cookie,弄得我头大。
go倒是有V8引擎的封装包,可是必须还得编译这个引擎,挺麻烦的。
想起来还有selenium-python可以用。就决定这个了。因为selenium没有python3.4的版本,不得不重装了python2.7。
多说一句,python3确实比python2的组织等各个方面改进很多,写起来感觉更好。可惜第三方库稀少是硬伤。
当时我的思路是这样的,用python和selenium来操作浏览器,提取网页图片地址和标题,传递给go,由go下载。
之所以由go下载,是因为python2的urllib等网络库有问题,经常会下载资源失败却不返回错误。相比之下,go的net库可以保证只要错误值是nil,下载必然完整。
我写了个python脚本,该python脚本会从标准输入接受一个网址,然后返回标题,之后,会依次访问每个漫画页面并返回图片网址。最后会输出一个结束标志。下载完毕后,可以再次接受网址进行下一次下载。
可以用go的exec.Command启动python脚本,然后用*Cmd类型返回值的StdinPipe()、StdoutPipe()方法的返回值来实现与子进程的交互,使用Start()方法启动命令就行了。
其实是个很简单的程序,算上go程,log,加锁,监视剪贴板等等部分也不到80行。
戏肉来了。我发现当标题中包含汉字时,程序就会出问题。主程序没有获得标题,子命令挂掉了。
检查了一下,我认为有两种可能的原因:
1)汉字编码问题。python会将汉字编码为本地编码(ansi,gbk)输出到标准输出;但是go会把它们当作utf-8编码的。
2)这种调用外部命令并进行交互的情况,就不支持非ASCII码。
最后我的解决方案是在python脚本里将unicode字符串编码为utf-8字节串然后用base64编码,go里采用base64解码。这样不管是哪个原因肯定都没问题了。因为主要耗时在下载上,这点不便无所谓。
不过具体是哪种原因,我就不清楚了。