碰到老大提了一个吐血的需求,想要给公司的图片服务器加上反爬虫处理减少带宽消耗。
我了解到的反爬虫策略有几种判断referer,判断user-agent,使用cookie。
但是做为一个写过各种爬虫的做死程序猿,我知道这几种方法都有伪造的策略可以绕过,而且很难防范。
现在老大给我扔了一个链接,说这个网站的反爬虫策略就做得很好,浏览器无referer,无cookie的情况下可以正常打开,但是如果用程序模拟、wget、curl之类的伪造user-agent就只能下载到一个大小正常但是不能打开的图片文件。
我看服务器标识是:Server:grid-cache/1.4.4
莫非是专用的图片服务端?
想请教这样的反爬虫处理是用什么策略做的?
图片链接是这样的: http://www.lady8844.com/h042/h28/img201501281600230.jpg
1
binux 2015-02-03 01:57:08 +08:00 1
谁告诉你 curl 不能伪造的
curl 'http://www.lady8844.com/h042/h28/img201501281600230.jpg' -H 'Pragma: no-cache' -H 'DNT: 1' -H 'Accept-Encoding: gzip, deflate, sdch' -H 'Accept-Language: en,zh-CN;q=0.8,zh;q=0.6' -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.17 Safari/537.36' -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8' -H 'Cache-Control: no-cache' -H 'Connection: keep-alive' --compressed 学业不精 |
2
jjit 2015-02-03 02:00:19 +08:00 1
只不过用 zip 之类的压缩了
下载下来 改后缀名为 .zip 解压后 有个无后缀名的文件 自己加个后缀名 .jpg 就可以打开了 |
3
ryd994 2015-02-03 02:01:15 +08:00 1
只是强制返回gzip内容而已。
你用curl --compressed 就能让curl自动解压 或者你先保存然后用gunzip解压也行 客户端没设置Accept-Encoding的情况下返回压缩内容确实不符合规范。不过至少有设置Content-Encoding,多少还算客气(不客气的话浏览器就显示不出来了……) |
5
9hills 2015-02-03 02:04:14 +08:00 1
话说直接chrome触发下下载,然后copy as curl就好了。。1l一看就是这么搞的。。
现在搞爬虫方便多了。。chrome神器不解释 |
6
yegle 2015-02-03 02:25:30 +08:00 1
一个IP过来,只读图片不读CSS/JS/HTML的,直接封IP。哪那么多废话?
|
7
lecher OP @binux
感谢你提供的建议,关于强制返回gzip这个策略之前没有想到,确实是学艺不精。 @jjit 感谢提供关于解压的思路 @ryd994 感谢讲解强制返回压缩包内容的解答 @yegle 感谢提供ip请求处理的策略,不过这个只读图片不读css、js、html的请求判断似乎比较耗费资源。这样的策略需要按ip处理请求资源消耗会因为请求数量膨胀吧。 刚才查了不考虑向下兼容的问题,还可以返回图片转base64的内容让浏览器解析。这个策略有用的吗?我统计过图片服务器目前的图片平均大小在150k左右,返回base64的内容,会消耗客户端的资源,目前还没测试前端这样处理的负载怎么样,想知道这个非主流做法科学吗? |
8
9hills 2015-02-03 03:36:58 +08:00 1
|
9
lecher OP @9hills
异步处理日志封ip防抓取这个思路不错,不过因为图片服务器是单独的,我自己做爬虫的时候也是会爬取html页面之后再去分析图片来爬图片。 按yegle提供的思路,就是每天异步分析图片服务器的请求,完全没有css请求的ip就封掉。这个策略似乎可行。 目前已经做的就是隐藏图片地址,图片地址列表都是ajax请求拿的,这个地址列表接口已经加了referer,cookie标志位,效果似乎不明显,现在爬图片的伪造确实太难分辨了。 |
11
babyname 2015-02-03 05:50:49 +08:00
没有办法的
|
12
ryd994 2015-02-03 07:37:06 +08:00 via Android 1
1限制请求频率这是基本,限制好请求频率不至于浪费太多,或者要求注册,验证邮箱
2连这点带宽都要唧唧歪歪的老板,炒掉算了 |
14
sohoer 2015-02-03 08:48:02 +08:00 1
直接暴露图片的源地址是防不住的,防IP也不行,多路ADSL+加自动重拔轻松解决
如果对图片地址做动态处理对服务器压力就大了 |
15
heaton_nobu 2015-02-03 09:22:26 +08:00
@binux 高手,请问curl怎么设置发送参数的编码格式,请赐教~
|
16
l555iu 2015-02-03 10:05:52 +08:00
你不要想着有什么神奇的方法能够一下有效防扒了,所有安全方面的事都是持久战,你所要做到的是增加爬取的难度,比如你提到的referer检查之类的,其实你都可以加上,能破解是一回事,你用不用又是另一回事了,至少你加上了增加了爬取的难度。其实我好奇你们是什么图片呀,很受欢迎么,好图要分享呀。
|
17
linzy 2015-02-03 10:16:48 +08:00 1
异步处理日志封ip,以前我爬虫,在本机攫取是非常累的一个过程,一般爬虫都是放在服务器的,服务器ip一般是固定,能防大部分的爬虫。
|
19
binux 2015-02-03 10:48:00 +08:00
@heaton_nobu 什么是『发送参数的编码格式』?
|
20
lecher OP |
22
heaton_nobu 2015-02-03 13:30:14 +08:00
@binux 我曾经用curl调用一个接口,传中文时那边数据会出现乱码,可是我不知道怎么指定utf8格式。。。
|
23
lecher OP @heaton_nobu
curl 指定utf8格式是在发送的header里面指定的。 "content-type: application/x-www-form-urlencoded; charset=UTF-8" 这样服务器会收到返回utf8格式的header。 当然接收的时候也要记得处理。curl不会帮你做字符串转换的处理,还是要自己处理接收数据。 |
24
binux 2015-02-03 14:48:36 +08:00 1
@heaton_nobu curl 不处理编码,只要你正确地把你需要的编码数据传给 curl 就行了。仔细读这句话,看你是否做到了。
|
25
ryd994 2015-02-03 17:33:46 +08:00 via Android
|
26
lecher OP @ryd994
说实话 做爬虫的人都不在乎水印,打多大的水印都一样,要抓取的还是会抓取,毕竟用户硬需还是有的。 老大也不指望能完全禁掉,只希望能爬的慢一点。 现在能做的也只是定期更新一下隐藏获取图片地址列表的js参数,但是效果不理想,不知道有没有人做这方面的。对于做js加密,有没有好一点的办法?随机返回不同的js获取图片地址列表的代码给客户端执行这个貌似比较伤用户体验。 |