“秒杀”心得

    本文记录对某网站A的秒杀活动编写秒杀器的经历和技术重点。

 

故事回顾



    某日早上,朋友给我说最近A网站在开展秒杀活动,有IPad、IPhone,让大家一起去秒杀。结果我们四个人一起秒,都没有别人快,没有一个人秒到。然后下午我就开始尝试分析它网站的秒杀流程,并尝试使用自动提交数据的方案来进行秒杀。结果,在晚上的时候,成功做出了第一个版本的秒杀器,然后我们一起秒杀了几个IPad(大家都想要IPad,而对IPhone没兴趣,汗)。

    当时就用网银付了帐,等待它发货。接下来我们每个人一个接一个地接到了A网站打来的电话,确定我们是不是作弊了,哈哈,我们当然打死不会承认了~

    过了半个来月,该网站又发起了新一轮的秒杀活动,但是由于之前发现有许多人作弊,所以这次全面更改了网站的流程,随机出现各种题目让会员回答,回答成功才能继续秒杀。这样,难度就大了些,一开始以为它们是题库,后来发现原来所有的题目都是自动生成的。元旦也没闲着,花了几天时间,改出了第二个版本的秒杀器,智能解题。经测试,目前没有失败过。

 

第一版本



    以下简明扼要地描述所有的分析流程

    分析网站秒杀流程,得出“入口页面”的地址。但是尝试登录此页面失败,返回活动等待页面,并提示:“活动未开始”。

    写了一个简单的控制台程序,在活动开始时立刻运行此程序,快速地打开了20-40个入口页面。此时,发现有一半左右的页面进入成功,到达“提交页面”。提交页面中需要填写一些必要的个人信息,最下面是一个提交按钮。估计这是A网站秒杀的最后一道关。

    把提交页面的客户端源代码全部保存下来,尝试进行分析。发现表单中需要填写的是:一些固定信息、一些隐藏域(HiddenField)、图片验证码。

    隐藏域中需要提交一些如:当时秒杀活动Id、用户Id等的信息。这些信息只要在网站中多分析一下就能得出。

    验证码:这个目前并没有什么好的办法能自动识别验证码,网上虽然有此类程序,不过我懒得去下载了,直接把验证码的图片显示在程序中,人工录入就好了。这样做的原因是,以我的经验,他们的验证码十有八九存储在服务端Session中,也有可能是客户端Cookie中,也就是说,验证码是可以提前获取的,并不一定需要等等活动开始后再获取。所以只要在临近活动开始的前2分钟获取并录入验证码就行了。

    这样,所有的数据都准备好了,接下来就是如何让程序自动填写数据并提交到网站上。这是重点,也是难点。如果纯粹使用后台代码模拟提交的话,就需要保证后台代码拥有已经被网站验证通过后的Cookie。之前我做过类似的提交程序,但是准备假Cookie的工作一直没有成功过,也比较麻烦。由于这次时间比较紧,没法再试验这种纯正的方案。所以静下心来想别的方案。后来灵机一动决定使用控制浏览器的方案来试试:在秒杀程序中嵌入一个浏览器,在浏览器中执行登录操作。这样,登录成功后的Cookie,就由浏览器自己来维护,而我要做的就是控制浏览器中页面的运行,让它以我的方式加载页面、填写数据、提交数据。在提交数据时,浏览器也会自动把Cookie一并提交。这样就可以在登录的状态下,把前面准备好的数据直接自动提交给服务器。

    最后一个问题,让浏览器先访问A网站的页面,登录并拿到登录成功的凭证后,如何让浏览器运行我的代码来提交数据呢?我试了一下在WPF应用程序中直接使用WPF自带的浏览器控件,并研究它的API。在WebBrowser类的API列表中,我发现以下方法:

public void NavigateToString(string text);
public object InvokeScript(string scriptName);

这正是我想要的啊,先构造一个模拟的页面,使用NavigateToString到这个页面上,然后使用InvokeScript方法来调用javascript提交表单到表单上指定的网站的地址就行了!

    OK,至此,全部设计完成。由于验证码已经在活动前就准备好了,所以整个过程基本上是完全自动化的,速度当然比人快多了,IPad自然也就手到擒来!

 

第二版本



    上面已经说过,网站改版后的秒杀活动,已经使用随机出现的题目来防止作弊。所以这次我的主要任务就是如何自动答题!其次,分析网站的提交页面中的表单,发现有很多的隐藏域是一连串随机的数字,没有任何规律,估计这些数据是每次活动都不一样的,所以再使用第一版中静态的模拟页面提交数据的方法不行了,必须使用动态的页面,把这些随机的数据都保留下来,并一起提交,或者直接在A网站发回来的页面中填写数据再提交。

    首先,第一直觉就是获取大量的提交页面,提取出获取到的所有题目,存储在题目库中。答题时,直接在题库中进行匹配,如果找到相同的题目,则直接使用题目库中的答案进行回答。

    当时,简单地画了一个流程的设计:

    后来在该次活动的最后一轮秒杀时,程序开发完成,并开始使用。结果,发现没有一题匹配成功,都找不到答案,全部都显示到了右边的窗口中人为回答,结果我还答错了!!!活动结束!!!

    很气人啊,这样的方案根本不行。后来分析了半天,发现原来所有的题目都是程序自动生成的,只是模式固定而已。所以改了设计方案,遵循设计模式写了一些类来自动回答题目,类结构如下:

这里,只贴一个子类的代码,展示一下解答的模式。这个子类的逻辑也是所有题目中最复杂的一个:

 

class TallerAlgorithm : SelectionQuestionAlgorithm
{
	internal override void TryComplete(SelectionQuestion question)
	{
		var match = Regex.Match(question.Content, @"小(?<a>.)比小(?<b>.)(?<abUnit>.),小(?<c>.)比小(?<d>.)(?<cdUnit>.),请问他们当中谁最(?<finalUnit>.)?");
		if (match.Success)
		{
			var a = match.Groups["a"].Value;
			var b = match.Groups["b"].Value;
			var c = match.Groups["c"].Value;
			var d = match.Groups["d"].Value;

			var abUnit = match.Groups["abUnit"].Value;
			var cdUnit = match.Groups["cdUnit"].Value;
			var finalUnit = match.Groups["finalUnit"].Value;

			var winner1 = abUnit == finalUnit ? a : b;
			var loster1 = abUnit == finalUnit ? b : a;
			var winner2 = cdUnit == finalUnit ? c : d;
			var loster2 = abUnit == finalUnit ? d : c;

			string champion = null;

			if (winner1 == winner2) champion = winner1;
			else if (winner1 == loster2) champion = winner2;
			else if (winner2 == loster1) champion = winner1;

			if (!string.IsNullOrWhiteSpace(champion))
			{
				question.RightAnswer = question.Answers
					.SingleOrDefault(an => an.Text.Contains(champion));
			}
		}
	}
}

 

    其次,是动态的页面的整理:把里面的题目都提取出来,自动答题之后,填写答案,插入一些提交的Javascript代码。然后继续使用NavigateToString、InvokeScript来提交数据。过程中,有两点心得:

1. 在一开始控制浏览器导向提交页面后,发现无法获取Html源代码,花了些时间研究,没搞出来。查了半天网页,最后使用WinForm中的WebBrowser来解决了这个问题。WinForm中WebBrowser不象WPF中的WebBrowser,它拥有着强大的API,DocumentText属性就取到了源代码。

2. 这次我使用了LinqToXml来维护Html Dom中的所有内容,发现XLinq的API实在是太方便了,查找某个元素,更改某个属性。如果没有XLinq,相同的功能,我可能需要3-5倍的时间来完成。

 

总结



    这次秒杀器编写的过程,让我的一个心结给解了。一直以来,就想完全控制网页客户端程序的运行:大四在电信的时候,老总让我给领导刷票;再后来有要人给我给论坛自动提交数据。这些需求都需要持有客户端的用户凭证,然后用这个身份给服务端自动发送一些请求。一直使用纯后台代码的方式提交,没有成功过。这次,使用控制浏览器的方案,使得真正做到了一直想做到的:“完全控制客户端”。

时间: 2024-10-31 00:15:25

&ldquo;秒杀&rdquo;心得的相关文章

如何实现进程间数据通讯技术

1.引言 在Windows程序中,各个进程之间常常需要交换数据,进行数据通讯.WIN32 API提供了许多函数使我们能够方便高效地进行进程间的通讯,通过这些函数我们可以控制不同进程间的数据交换,就如同在WIN16中对本地进程进行读写操作一样. 典型的WIN16两进程可以通过共享内存来进行数据交换:(1)进程A将GlobalAlloc(GMEM_SHARE...)API分配一定长度的内存:(2)进程A将GlobalAlloc函数返回的句柄传递给进程B(通过一个登录消息):(3)进程B对这个句柄调用

C#:异步编程和线程的使用(.NET 4.5 )

  异步编程和线程处理是并发或并行编程非常重要的功能特征.为了实现异步编程,可使用线程也可以不用.将异步与线程同时讲,将有助于我们更好的理解它们的特征.   本文中涉及关键知识点   1. 异步编程 2. 线程的使用 3. 基于任务的异步模式 4. 并行编程 5. 总结   异步编程   什么是异步操作?异步操作是指某些操作能够独立运行,不依赖主流程或主其他处理流程.通常情况下,C#程序从Main方法开始,当Main方法返回时结束.所有的操作都是按顺序执行的.执行操作是有序列的,一个操作必须等到

PHP教程:如何实现301重定向

什么是301重定向?301重定向就是当你的网站地址发生变化时,例如更换域名,网站改版等等,你希望访客或者搜索引擎跳到新的地址上访问网站,这时就需要你做301重定向了.实现301重定向有很多方法,本文主要介绍PHP程序怎么实现301重定向.     实现301重定向PHP代码     <?php     $the_host = $_SERVER['HTTP_HOST'];  //标记取得当前域名     $request_url = isset($_SERVER['REQUEST_URI'])?$

premiere cs6快捷键大全

  Adobe premiere Pro cs6是一款编辑画面质量比较好的软件,有较好的兼容性,且可以与adobe公司推出的其他软件相互协作.想要软件熟练使用,常用快捷键是必须记住的.西西今天整理了premiere cs6工作中会使用到的快捷键. Premiere Pro CS6 默认键盘快捷键 结果 Windows Mac OS 文件     新建     项目... Ctrl+Alt+N Opt+Cmd+N 序列... Ctrl+N Cmd+N 来自剪辑的序列     素材箱   Cmd+/

linux安装oracle11g数据库步骤详解

1.安装开发包组 yum groupinstall "Development Libraries" "Development Tools"   2.安装其他软件包 yum install -y libaio glibc compat-libstdc++-33.x86_64 elfutils-libelf-devel\* gcc-c++ libaio-devel unixODBC\* readline\* glibc-2.12-1.80.el6.i686 libXex

[置顶].NET平台开源项目速览(13)机器学习组件Accord.NET框架功能介绍

    Accord.NET Framework是在AForge.NET项目的基础上封装和进一步开发而来.因为AForge.NET更注重与一些底层和广度,而Accord.NET Framework更注重与机器学习算法以及提供计算机视频.音频.信号处理以及统计应用相关的解决方案.该项目使用C#语言编写,项目主页:http://accord-framework.net/     说明:该文章只是一个基本介绍,主要内容是翻译的官方文档和介绍,部分英文表述个人能力有限,不太熟悉,所以直接照搬原文,有比较

制作简单启动兼容性好的U盘维护工具

       这款U盘启动工具盘是本人使用syslinux启动工具,选用其他人出的工具盘映像文件制作而成,已使用三年多了,兼容性非常好,目前还没有遇到不能启动的机器,感兴趣的朋友可以试用一下. 启动信息由syslinux制作,解决了之前使用DOS启动再调动dos4grub和直接使用grub启动方式时,一些机器不能启动的问题. 包括的工具说明: 1.DOS工具使用了深度出的DOS工具.PM8.05 DOS版以及MAXDOS7.1工具盘的img映像文件: 2.WINPE使用的是深度4.0 U盘工具中

Win10系统电脑怎么设置DNS地址?

1.谷歌全球通用DNS地址: 首选DNS地址:8.8.8.8备选DNS地址:8.8.4.4 2.国内知名的114 DNS地址 首选DNS地址:114.114.114.114备选DNS地址:114.114.115.115114DNS 3.阿里云公共DNS地址 首选DNS地址:223.5.5.5备选DNS地址:223.6.6.6 4.百度公共DNS地址 首选DNS地址:180.76.76.76备选DNS地址:暂时(设置的时候,可以使用上面的其他DNS地址,替代一些备选) Win10设置DNS地址教程

企业平均每年遭遇9起有针对性攻击

本文讲的是 :  企业平均每年遭遇9起有针对性攻击  , 高级持续性攻击( APT )可能比想象的更普遍:最新研究发现,在过去12个月中,企业平均遭遇9起这种有针对性的攻击.根据Ponemon研究所名为“高级持续性攻击的现状”的报告(由Trusteer委托)显示,近一半的企业称,攻击者成功地从他们的内部网络窃取了机密或者敏感信息.Ponemon对曾经有过预防和检测有针对性攻击经验的755名IT和IT安全专业人士进行了调查. Ponemon发现受害企业需要很长一段时间才能发现他们已经遭受这种攻击.