爬虫看似简单实则复杂。
老师布置了一个汉化一个json数据的任务,大概有800多条英文要翻译,哎,过年了,郁闷的事情还是交给计算机处理好一点。
一、曲折摸索之路
1.1 JavaScript来进行前端抓取
呵呵,我都不晓得我哪里来的勇气用js来做前端爬虫,添加了Jquery等组件,使用BootStrap建立了一个前端页面,还用FileSaver.js和jquery.json.js来做了保存json对象到文件的功能,好像还很6的样子。然而实现Ajax请求报错啦:
/* 保存json到文件 */
function saveAsJsonFile(object){
var jsonStr = $.toJSON(object);
var blob = new Blob([jsonStr], {type: "text/js;charset=utf-8"});
saveAs(blob, "json.js");
}
No 'Access-Control-Allow-Origin' header is present on the requested resource.'
这就是著名的js跨域错误,由于Google家的网站不是我的,所以无解。
1.2 node来进行爬虫
先写两个地址:
[1] http://translate.google.cn/#en/zh-CN/hello
[2] http://translate.google.cn/translate_a/single?client=t&sl=en&tl=zh-CN&hl=zh-
CN&dt=at&dt=bd&dt=ex&dt=ld&dt=md&dt=qca&dt=rw&dt=rm&dt=ss&dt=t&ie=UTF-8&oe=UTF-8&source=bh&ssel=0&tsel=0&kc=1&tk=846673.696795&q=hello
采用node的express,superagent,cheerio来对google的翻译地址[1]进行爬取,然而得到的没有翻译结果,只有网站的html结构,原来翻译的数据是通过Js来生成的,看来还是得去找ajax的api地址[2],正当我觉得搞定了之后,换一个单词,api就不行了,why?地址难道还要经过验证?
二、迷途知返
通过几个技术博客的搜索,找到了原因,关键在于api参数tk是动态生成的。在[1]地址返回的源码里面藏着这样一个代码:
TKK=eval('((function(){var a\x3d1394505672;var b\x3d2768463696;return 412298+\x27.\x27+(a+b)})
tk值就和这个TKK值有联系的,网上已经有人找到了生成tk值得js函数,我猜测应该就在
Google网上的那几个js里面,有时间可以自己去找找,这样就可以自己实现调用Google Api来帮我翻译喽。
三、意外惊喜
正当我要动手写代码的时候,意外发现了一个开源的翻译集项目translateSet,里面就封装好了Google翻译,百度翻译等的接口,哎呀,我的吗,为何不早点发现,花了一下午的时间啊,几行代码就OK:
注意: json文件要严格按照标准来,双引号里面用单引号,{}要在开始和结尾,json文件要选无Bom的utf-8格式
Class.forName("com.lsj.trans.GoogleDispatch");
Dispatch dispatch = Dispatch.Instance("google");
zhResult = dispatch.Trans("en", "zh", prepareEnStr); // 英文翻译为中文
所有主机检查都在{0}注册的主机上传递。注意:在未注册的{1}个主机上跳过了主机检查。
在未注册的{0}个主机上跳过主机检查。
主机检查已成功更新
主机检查更新失败
没有注册的主机
...
看见一行行的的中文输出,我笑了,不愧是Google,人工智能大法,已经超出我的翻译能力了。(翻译的文本里面不要包含
,不然会返回英文)
然而,突然间,Google把我屏蔽了。。。乐极生悲啊
四、总结
爬虫两大难题:
- js 请求的api地址的计算
- 一些网站会识别异常流量,拦截爬虫请求