我是一个Web Crawler , 有时候称为Spider , 你们经常说的爬虫就是我。
我想我是遇到了好时代,感谢IT政府,提供了简单的HTTP协议,还有HTML,CSS, JavaScript这一系列开放的技术, 原来的桌面应用,局域网应用都被搬到了网络上,形成了一个个的网站, 网站互联起来,形成了一个覆盖全世界的大网。
在这个大背景下,我应运而生,开始在这个大网上爬来爬去,收集、分析各种网页的数据。
我有几个亲戚在搜索引擎公司工作,听说他们的目标是把全世界的网页都给爬下来,形成索引,让人类搜索, 想想全世界网页的数量,这几位亲戚的工作实在是让人敬畏。
我的工作原理非常简单, 给我一个URL,我就可以通过HTTP协议把HTML页面下载下来。然后分析一下这个页面中有哪些元素,比如说,表单,表格,链接等等。
反正这个HTML页面是纯文本的,我想怎么折腾都可以,我可以把它形成一颗DOM树,也可以用正则表达式去获得一段我想要的内容,总之方法多得很呢!
最重要的是,我要拿到这个页面中的其他链接, 然后再拿到这些链接对应的HTML页面,继续我的分析,如此循环下去,就能把所有的页面给找出来了,所有的内容都尽在掌握!
有时候,有些HTML页面是受到保护的,必须登陆以后才能够访问,这也难不住我,人类早已经申请了很多的账号。我把这些用户名和密码拿过来,找到对应的登录框,向服务器端发送一个请求,就可以顺利登录了, 访问受保护网页的大门就敞开了。
所以说我有两个最基本的能力, 第一,通过HTTP协议访问网页; 第二,分析HTML网页。
所谓“爬亦有道”, 我们爬虫界也是有一定规范的,比如说,你在你的网站的根目录下放一个robots.txt文件,里边定义好那些内容对爬虫开放,那些内容不希望爬虫访问, 那我们就不会去爬这些内容了。
当然这只是个约定俗成的规范,而不是标准, 所以总是有一些爬虫完全不遵守规则,置这些规范于不顾。
作为程序,我们访问起网络来, 要远远比人类快得多,人类还需要在界面上移动鼠标点击,我们则是拿到URL后直接、迅速、毫不犹豫地访问, 这样一来,如果爬虫很多,常常给一些网站带来非常大的流量,给服务器带来很大的压力,影响了正常用户的访问, 从而影响了网站的收入。
断人财路,网站就急眼了, 肯定要反击, 于是他们网站便提出了各种各样的办法,成为反爬虫。 他们有反爬虫, 我们便反反爬虫,于是便引发了一场波澜壮阔,反复拉锯的战争。
首先他们得把我们给识别出来才行。最早爬虫在发出HTTP请求的时候,不注意伪装自己,不会修改User Agent ,相当于告诉对方说: 我是爬虫。
于是这些网站轻轻松松的就把我们识别出来,返回一个错误码,或者干脆禁止我们访问。
什么? 你还不知道什么是User Agent ?
User Agent其实就是HTTP Header 中的一个字符串,让服务器端能识别客户端的操作系统及版本,浏览器及版本,浏览器引擎,语言等等信息。 这样可以针对性地做一些处理,例如发送桌面版或者手机版的网页。
比如: User-Agent:Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0)
后来我们也学精了,把这个User Agent 设置得和人类的浏览器一模一样,对方就不好识别了。
有时候我们还可以伪装成Google的爬虫,百度的爬虫, 各个网站自然希望百度和Google去对自己的网页做索引的,所以对这样的User Agent不会下狠手拒绝。
但是他们也有别的办法,比如分析我们的行为,利用我们速度快的特点, 比如说,一秒之内有多少次请求,就认为是爬虫。
我们也得斗智斗勇,访问一会儿就休眠几秒钟,然后接着再访问,让他们的策略失效。
但是我们也不能老是休息呀,如果休息得太多,那我们就会人类的速度差不多了,爬虫还有什么意义?
有些网站会采取一些非常“恶劣”的手段,我最难以防范的就是陷阱。
具体来说,就是在网站发回的HTML页面中,包含一些人类肉眼看不到的链接,比如弄个一个像素大小的图片,上面有个链接。
人类看不到,是绝对不会点击的,但是我们爬虫是程序啊,能分析所有的链接并访问之。 但是以我们的智商,并不知道这是一个陷阱啊!
这些陷阱就像漂浮在网页中的幽灵, 只要我们一访问这些链接,服务器立刻就会知道,哼哼,又来一个爬虫,立刻启动大杀招:封IP!
他们还有一招就是验证码, 如果一段时间内访问的次数超过了某个阈值,立刻显示一个图形验证码,输入验证码以后才能继续,这实在是太讨厌了, 因为验证码是个图片, 人类肉眼轻松识别,可是我想识别还得靠别的软件或者系统,比如OCR。
但是验证现在搞得越来越复杂,什么滑块验证,什么数学题…… 单纯的OCR都不够了。
不过我也不怕,我可以做分布式,反正机器多,让每个机器上的爬虫运行得稍微慢一点,不要触发服务器端的各种讨厌的封锁策略。
我还可以用代理,让IP不断变换,封了一个IP, 就用另外一个,子子孙孙无穷匮也。
我最烦的就是“投毒”,这一招最损, 网站识别出来我是爬虫以后,并不会把我的IP关到小黑屋,而是很阴险地发送一些假数据,和真实数据混在一起,让我喜滋滋地取走,不知道过了多少天,主人用数据做分析时才发现: 嗯,这数据有点不对头啊! 到底是怎么回事!!! 于是我被拖出去打了50大板,真是冤枉啊。
最近的日子有点不大对头儿,访问一个URL后,返回的HTML特别少,JS特别多,我从HTML中几乎找不到什么有用的东西。
主人看到我干活效率骤然降低,赶紧亲自上手研究了一番,他用Chrome打开网站,按F12, 查看源代码和网络请求, 叹了一口气说: “原来的办法都不管用了,这些网站都在用JavaScript在浏览器端渲染了!”
不过他接着又兴奋地说:“这也许是一件好事情,这些JavaScript通过AJAX的方式访问后端网站的API,返回的数据都是JSON,我分析下,只要弄清楚这些API的输入和输出, 直接调用API就可以拿到数据了。”
其实都是分析,只不过原来分析HTML结构,从中取出内容,现在是分析后端服务器提供的API,直接获取到了数据,似乎更加方便。
但时候直接调用这些API也是有点小麻烦,比如很多时候,都需要进行认证,比如发个token什么的给服务器,要不然人家就不让调用。
后来主人说,算了,实在是麻烦,我给我的爬虫升级下装备吧。
新装备其实就是一个内嵌的浏览器,这个浏览器不需要界面显示, 可以在程序中静悄悄地执行,主人把他叫做无界面浏览器,或者无头浏览器。
(码农翻身注: 例如selenium,phantomjs等)
有了全功能的内嵌浏览器,相当于一个真正的人类在请求网页了,把JavaScript下载下来,不是要在浏览器中做渲染吗?等的就是你! 管你什么AJAX, token ,加密, 这里统统可以执行。
这个无头浏览器渲染完以后,我就可以拿到HTML做后续的分析了。
一切尽在掌握,这种感觉实在美妙。
不过缺点也是有的: 慢! 没办法,有得必有失嘛, 我们还可以采用分布式运行的利器,多跑一些爬虫的实例,人多力量大。
我们爬虫界的终极目标就是和人类的行为保持一致,这样就网站就无法识别了,只不过路漫漫其修远兮,双方的争斗估计会一直持续下去。
在斗争中,建议大家遵循一个原则:“斗而不破”, 不能砸网站的饭碗,要不然人家一怒之下把功能下线了,那大家彻底玩完。
(完)