最近看阿里的月饼事件深有感慨啊,嗯,身为一名有职业操守和道德的资深技术人员,我们一定不要像文中说的这样子做。我们要秉持诚信公开的原则,不能利用系统漏洞。。。好吧,开始进入正题。我们先看下用什么手段才能先人一步的抢到东西。
一般抢购或者竞拍网站。抢购网站的流程:
刷新一个页面看到是否开抢了,因为现在网站的分布式部署,一个页面对一个域名的请求数目等等的限制, 一般这个页面将会是一个链接:urlA。监控urlA的返回结果,当达到预期值的时候,调用下单的请求,或者是点击事件。竞拍网站的要稍稍的麻烦一点点:
刷新得到当前的最高报价然后设置一下期望的报价和加价幅度然后在期望值之内不停的加价,保证能够在最后抢到期望金额之下的商品咱们以京东夺宝岛为例,搞一个吧
在Chorme中打开夺宝岛网页,按F12,然后刷新页面转到Network标签,看所有的请求,研究出那个请求是拿当前价格的 方式是点击请求,看Response中的返回值:得到链接:http://dbditem.jd.com/json/current/englishquery?这个链接能够查看所有的出价记录的json字符串,第一个就是当前的报价了
然后就是设置一个加价值,心理价位, 然后提交再次获得最高价,如果不是我出的那么就再次加价,循环这个过程当然还是的通过Chrome来知道提交加价的请求应该是什么 这里直接列出结果:http://paimai.jd.com/services/bid.action?查询价,然后加价,最后提交的源代码如下:
var t,count = 1,price=0,pin = getCookie('pin'),f = function(){ $.ajax({ url:'http://paimai.jd.com/json/current/englishquery?paimaiId='+paimaiId+'&skuId=0&t=964468&start=0&end=9', async:false, success:function(data){ var currentPrice = parseFloat(data.currentPrice); console.info("第",count,"次检测商品当前拍卖价格是",currentPrice); if(data.auctionStatus == 2){ console.error("商品拍卖结束,获得者",data.currentUser); clearTimeout(t);return; } if(data.currentPrice < 1500) { if(pin != data.currentUser && price != currentPrice){ $.ajax({ url:'http://paimai.jd.com/services/bid.action?t=369168&paimaiId='+paimaiId+'&proxyFlag=0&bidSource=0&price='+(currentPrice+1), async:false, success:function(data1){ console.warn("第",count,"次加价拍,本次出价",(currentPrice+1),"出价结果",data1.message); if(data1.result == 200){ currentPrice = currentPrice+1; } else { if(data1.result == 516) {clearTimeout(t);return;} } } }); } else { console.info("商品价格未变,忽略加价"); } price = currentPrice; t = setTimeout(f,1000); } else { console.error("商品价格高于原价5折,停止加价"); clearTimeout(t); } } }); count++; } f(); //暂停 clearTimeout(t)代码还是比较简单,就不多做解释了。这里说一下有个关键的地方是网页分析的部分。就是从请求中拿到了自己想要的数据。 这样样例的请求是一个json,所以能够直接用了,如果是一个html网页应该怎么办呢? 因为现在的网页一般都用了jquery,所以可以使用jquery脚本来做。他的拾取器还是之棒的。 比如这样: var val = (‘tr:eq(2)′,html);(‘td:gt(1)’,val).html() 第二个tr的第一个td. 等等
最后咱们来说说如何防范这种做法。
让登录变难, 防止代码自动登录。 12306的网站的验证码跟高考题一样,就是为了这个,尽量只能真人用户。但是因为sessionid是放在cookie中的,可以用代码来模拟cookie来保持登录状态,所以就引入了cookie加密的方式。 但是不能解决上面说的js脚本的问题。服务器端针对每一个登录用户,限制刷新等次数。 抢华为或者P8的时候经常会遇到太繁忙了啊,请求次数过多啊,等等就是这样的, 具体可以用redis来根据用户的session来存次数,甚至于存在本地内存中。这个有机会详细的说。服务器不根据真正的请求到达顺序来决定抢购结果。 可以建立一个池,然后从最小到达的100000请求中取出部分,这样就能够防止,脚本比人快,导致大量都是用脚本抢到的,会相对公平一些。都是简单的说一下,以后咱们有机会细讲。 相关资源:ES-sql chorme插件