“只要你敢露我就敢抓。”多么霸气的一句话,是多少男人梦寐以求的事,特别是看到美女的时候,哈哈,开个玩笑。我们言归正传,目前抓站越来越难,特别是现在很多内容是通过js加载或者是乱起八糟的东西拼凑出来,酷炫是酷炫,但是用后端程序越来越难以抓取。经常有人搜索”如何等js执行完再抓取内容等等”(其实我也搜过)。下边我们来看看如何“以js之道还至js之身”。让你的js跑到任何一个你看到的网页,抓取任何你想要的内容。
直觉上打开网页的正确姿势是浏览器,没错,这次我们就是在浏览器上做文章,毕竟用其他方式打开网页都没有浏览器那么流行。也许你听说过浏览器插件这么个东西,如果你没听说过也没啥问题,毕竟下边要说的就是这个东西。下边我们先从开发一款chrome插件说起。
预备知识
写插件很简单,只需要你有一个chrome浏览器,你就可以写chrome插件了,当然如果你对js一点都不懂,那就学习一下吧, 毕竟也不难。当然如果你稍微懂点CSS就更好了,不过,不懂也无所谓。
起步
下边我们来开发我们的第一个插件。
- 首先准备一个目录,用于存放插件。
- 然后建配置文件manifest.json,这是唯一必须用的文件,内容如下。
{ "manifest_version": 2, "name": "FOREVERNULL", "version": "1.0" }
到此,不管你信不信,我们的插件写完了,哈哈。
加载运行
点击右上角【设置】按钮,就是那个三道杠,然后选择【更多工具】中的【扩展程序】,看到如下界面。而后点击【开发者模式】、【加载已解压的扩展程序】, 选择你的插件目录就OK了。看看是不是有了你的插件,虽然现在我们什么都没干。
如果你修改了扩展程序,只需要刷新这个页面或者点一下【重新加载】就OK了。接下来,我们需要给我们的插件添加个图标。
添加图标
如果你安装过chrome插件,可能你会知道chrome会在扩展程序页面和浏览器地址栏的右侧显示一些小的图标。下边我们为我们的插件添加图标。
- 首先,我们下载一个图标文件,png或者ico,放到我们的插件目录。
- 而后,在配置文件中添加这么一行:
"icons": { "48": "icon.png" }
这里需要注意格式,目前你的配置文件应该长这样,特别注意icons前边的逗号,其实说白了就必须是符合JSON格式的规范:
{ "manifest_version": 2, "name": "FOREVERNULL", "version": "1.0", "icons": { "48": "icon.png" } }
现在我的就长这样了,是不是比刚才好看点了呢。
这样我们的扩展程序在右上角还是没有图标,咋整呢?添加下边的配置,将会有惊喜:
"browser_action": { "default_icon": "icon.png" }
变化请看浏览器的右上角,地址栏的右侧。图标OK了,你就知道在上述界面中如何添加属性了,你还可以添加描述、作者等,这些都是附属品,我们就不讲了。
做点小事
讲了半天,我们的chrome插件还是个摆设,只能玩一玩,怎么给它添加功能呢。接下来我们先写个简单的,先预热一下:
- 首先, 在我们的插件目录创建一个js文件,比如helloworld.js
- 然后,我们在配置文件中加载这个js文件,添加如下配置:
"content_scripts":[{ "js": [ "helloworld.js" ], "matches": [ "
" ] }] 这个配置稍微有点牛X,它是在所有页面都可以执行helloworld.js。这个match属性用于配置你插件作用的范围,这里我们配置为全部url都起效。
这里content_scripts的意思就是这段代码是插入到浏览的页面中的,chrome插件假设页面有这么几种,一种是background就是在后台执行的;另一种是popup弹出类型的,比如右上角的图标点击后可以弹出一个页面来,用于设置等;另一种是contents类型的,这种是在当前浏览的页面。并且他们直接可以互相通信,这里我们先不研究这种比较复杂,主要是还用不到的东西。我们只需要了解这个contents_script就是能够操纵当前浏览的页面的代码就好了。
下边我们在helloworld.js
中稍微添加点js代码,比如:
alert("Hello, world!");
这句话的本意是打印一句话:Hello, world!
。但是我们由于是一个插件,并且作用于任何url,那么无论打开哪个页面,都会弹出一个弹窗显示Hello, world!。
友情提示:修改完代码后,要去【扩展程序】重新刷新一下我们的插件,由于我们改动的是js文件,可能会报错或者需要重新勾选“启用”。
现在无论你打开什么页面或者刷新页面,都会看见一个弹窗了。到此为止,我们已经给我们的插件添加了行为,我们的chrome插件开发就到此为止了,其他的插件也不外乎这么写。
抓站
有了上一步小小的例子,我们就有了思路:通过js获取DOM元素并取其中的值,然后组织数据并提交到远程服务器即可。
下边我们稍微加强一下咱们的插件,引入jQuery帮我们处理DOM并提供方便的ajax调用。当然如果你不用jQuery也行,这里只是图方便。
- 首先下载jquery到我们的插件目录。
- 而后修改配置文件,给content_scripts添加jquery这个js。
"content_scripts":[{ "js": [ "jquery-1.11.3.min.js","helloworld.js" ], "matches": [ "
" ] }]
下边我们假设我们的任务是抓取内推网的招聘数据(只用于做实验,你抓啥都行,看见了这个网址就打开了,就抓你来做实验吧,哈哈)网址:http://www.neitui.me/?name=neitui&handle=lists&kcity=&keyword=PHP。
我们开始写js代码,和平时写代码一样,这里我给出一个示例,大家稍微感受一下:
$(function(){ jobs = []; $(".jobinfo").each(function(){ jobs.push($(this).find('strong').text());//获取所有标题 }); //异步提交数据 $.ajax({ url : "http/// ", dataType:"jsonp", data:{ jobs : jobs }, success:function(){} }); });
这个代码唯一注意的问题就是提交数据的时候由于存在跨域问题,所以需要使用jsonp提交数据。
写在最后
看到这里,你基本上会开发你自己的插件了,现在你可以让浏览器帮你做你想做的事,所以机械的点击动作,都可以通过插件完成。并且我们展示了使用插件抓取数据的基本思路和示例。
用这种抓取数据,基本可以做到想要什么就抓什么,并且可以自动提交表单等等,最主要这种基本不会被屏蔽,还可以开多个窗口多进程抓。但也存在一些问题,比如网页加载缓慢会造成抓取效率不高等。但是我们已经实现了“只要你敢露我就敢抓”这个目标,另一种所见即所得,再放一句豪言壮语,“只有你想不到的办法,没有抓不到的数据”。