关于小米手机网站抢购的一点技术分析

news/2024/5/20 3:09:24/文章来源:https://blog.csdn.net/weixin_34128237/article/details/91953902

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

先PS一下:最近小米手机火了,看起来好像地球人已经不能阻止它的发展趋势了

其实本文论述的技术也并非小米手机专用,只是用小米手机来做借鉴,但课题起源于朋友请求帮忙购买小米手机,于是借助专业知识写了一个抢购的工具,拿出来和大家分享一下。说叫抢购工具,其实就是自动下订单而已,因为小米手机网站的订单只要在72小时内完成支付就可以,所以在第一时间完成下单以后找闲暇时间进行支付就可以了。

再PS一下:【声明】本工具原理为模拟浏览器访问和执行页面,不包含任何入侵和破坏行为。本工具的优点只是自动化处理以及节省不必要的流量耗费。

1、首先分析任务实现需要操作的步骤:

  a、登录系统,此步骤中小米商城网站使用了通行证认证模式,即需要将表单提交到passport.xiaomi.com,认证成功后通过token传递回商城网站的callback页面。

  b、清空购物车,本步骤可选。因为是工具自动购买,防止错误下单,可在每次执行操作前自动清空购物车,购物车清空后会302到购物车页面,http://order.xiaomi.com/cart,页面提示“清空购物车成功”。

  c、将商品放入购物车。此步骤小米网站没有使用post,而是get,通过url将商品id以及数量传递给服务器,并且还使用了友好url,例如 http://order.xiaomi.com/cart/add/1016-0-1 是将 小米手机M1放入购物车,其中1016为小米手机的商品id,0表示此商品为单品(非组合套装),1表示购买一个。以此类推。放入购物车以后会自动302到购物车页面,不过此时url为 http://order.xiaomi.com/cart/index,显示购物车中的商品。

  d、提交订单。本步骤同样为get方式,直接请求地址 http://order.xiaomi.com/buy/checkout 即开始将购物车中的商品作为一个订单进行提交,此时进入订单详细信息填写页面,填写收货人、收货地址、电话、发票等信息,确认订单需要post,请求的地址仍然是 http://order.xiaomi.com/buy/checkout。

2、关键技术点分析及实现

  清楚了任务要求,接下来分析技术点,鉴于本人对C#比较熟悉,故选用C#语言实现,采用了Winform项目框架。

  a、核心需求即是通过http协议下载页面,以下为本人使用的核心代码:

View Code 
                     Uri uri = rawUri;
                     HttpWebSession session = new HttpWebSession()
                     {
                         RequestUri = uri,
                     };
                     var _request = session.Request =
                       (HttpWebRequest)WebRequest.Create(uri);
                     _httpWebSessions.Add(session);
                     if (Proxy != null)
                     {
                         _request.Proxy = Proxy;
                     }
                     _request.AllowAutoRedirect = false;
                     if (Uri.UriSchemeHttps == uri.Scheme)
                     {
                         ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(RemoteCertificateValidation);//
                     }
                     if (Credentials != null)
                     {
                         _request.Credentials = Credentials;
                     }
                     if (!string.IsNullOrEmpty(Accept))
                     {
                         _request.Accept = Accept;
                     }
 
                     if (!string.IsNullOrEmpty(AcceptLanguage))
                     {
                         _request.Headers.Add("Accept-Language", AcceptLanguage);
                     }
                     if (!string.IsNullOrEmpty(AcceptCharset))
                     {
                         _request.Headers.Add("Accept-Charset", AcceptCharset);
                     }
                     _request.KeepAlive = KeepAlive;
                     if (!string.IsNullOrEmpty(RefererUrl))
                     {
                         _request.Referer = RefererUrl;
                     }
                     switch (_acceptEncoding)
                     {
                         case AcceptEncoding.GZIP:
                             {
                                 _request.Headers.Add("Accept-Encoding", "gzip");
                                 break;
                             }
                         case AcceptEncoding.DEFLATE:
                             {
                                 _request.Headers.Add("Accept-Encoding", "deflate");
                                 break;
                             }
                         case AcceptEncoding.BOTH:
                             {
                                 _request.Headers.Add("Accept-Encoding", "gzip,deflate");
                                 break;
                             }
                     }
                     if (_request.CachePolicy == null || _request.CachePolicy.Level != _cacheLevel)
                     {
                         _request.CachePolicy = new RequestCachePolicy(_cacheLevel);
                     }
                     if (_headers != null && _headers.Count > 0)
                     {
                         foreach (KeyValuePair<string, string> item in _headers)
                         {
                             try
                             {
                                 _request.Headers.Add(item.Key, item.Value);
                             }
                             catch
                             { }
                         }
                     }
                     _request.UserAgent = _userAgent;
                     _request.Referer = RefererUrl;
                     if (TimeOut != 0)
                     {
                         _request.Timeout = TimeOut;
                     }
                     if (postData == null)
                     {
                         if (postDictionary != null)
                         {
                             foreach (var item in postDictionary)
                             {
                                 postText += item.Key + "=" + item.Value + "&";
                             }
                             postText = postText.Trim('&');
                         }
                         if (!string.IsNullOrEmpty(postText))
                         {
                             postData = _encoding.GetBytes(postText);
                         }
                     }
                     if (_cookieContainer != null)
                     {
                         string strCookieHeader = _cookieContainer.GetCookieHeader(uri);
                         if (!string.IsNullOrEmpty(strCookieHeader))
                         {
                             _request.Headers["Cookie"] = strCookieHeader;
                         }
                     }
                     if (postData != null)
                     {
                         session.PostedData = postData;
                         _request.Method = "POST";
                         _request.ContentType = "application/x-www-form-urlencoded";
                         _request.ContentLength = postData.Length;
                         Stream requestStream = _request.GetRequestStream();
                         requestStream.Write(postData, 0, postData.Length);
                         requestStream.Close();
                     }
                     var _response = session.Response = (HttpWebResponse)_request.GetResponse();
                     if (_cookieContainer != null)
                     {
                         string strSetCookieHeader = _response.Headers["Set-Cookie"];
                         if (!string.IsNullOrEmpty(strSetCookieHeader))
                         {
                             _cookieContainer.SetCookies(_response.ResponseUri, strSetCookieHeader);
                         }
                     }
                     StatusCode = _response.StatusCode;
                     _requestCookieCollection = _cookieContainer.GetCookieCollection(rawUri);
                     _response.Cookies = _cookieContainer.GetCookieCollection(_response.ResponseUri);
                     if (IsEncodingAccepted(_response, AcceptEncoding.GZIP))
                     {
                         responseStream = new GZipStream(_response.GetResponseStream(), CompressionMode.Decompress);
                     }
                     else if (IsEncodingAccepted(_response, AcceptEncoding.DEFLATE))
                     {
                         responseStream = new DeflateStream(_response.GetResponseStream(), CompressionMode.Decompress);
                     }
                     else
                     {
                         responseStream = _response.GetResponseStream();
                     }
 
                     if (StatusCode == HttpStatusCode.Redirect || StatusCode == HttpStatusCode.Moved)
                     {
                         if (_allowAutoRedirect)
                         {
                             responseStream.Close();
                             string strRedirectUrl = _response.Headers["Location"];
                             var stream = GetStream(new Uri(rawUri, strRedirectUrl), true, null, null, null, null, null);
                             return stream;
                         }
                         // return GetStream(
                     }
                     else if (StatusCode == HttpStatusCode.Unauthorized)
                     {
                         string strAuthorizition = OnAuthorizition();
                         if (!string.IsNullOrEmpty(strAuthorizition))
                         {
 
                         }
                     }

上述代码是本人多年积累的一个类库中的一点核心代码,解决了诸多常见问题,比如cookieContainer对domain识别异常,https访问等等,如有需要本人可提供下载。

  b、逻辑处理的自动机

   鉴于web访问过程中容易出现的各种不确定性因素,经常会出现请求同一个地址却返回不一样的内容,多数为302活301。本人使用了注册处理函数的方式,每次请求完以后,根据返回的页面url找到相应的处理函数进行操作,比如登录时,发送的是指向http://passport.xiaomi.com/index.php?...的一个请求,但返回结果往往变成 http://www.xiaomi.com/,在相应的处理函数中就需要进行清空购物车或者将商品放入购物车。

View Code 
         protected virtual void ProcessHttpSessions(ProcessState state)
         {
             state.Processed = true;
             if (RunState == RunState.Pauseing)
             {
                 OnLog("==========被用户暂停==========");
                 ChangeState(RunState.Paused);
                 state.Break = true;
                 return;
             }
             if (RunState == RunState.PauseingByNetService)
             {
                 OnLog("==========被换IP服务暂停==========");
                 ChangeState(RunState.PausedByNetService);
                 state.Break = true;
                 return;
             }
             if (RunState == RunState.Stopping)
             {
                 OnLog("==========被用户停止==========");
                 ChangeState(RunState.Stoped);
                 state.Break = true;
                 return;
             }
 
             if (_httpClient == null || _httpClient.HttpWebSessions == null)
             {
                 state.Continue = true;
                 return;
             }
             int oldSessionCount = _httpClient.HttpWebSessions.Count;
             Action<ProcessState> processerAction = null;
             if (string.IsNullOrEmpty(_httpClient.RequestUrl))
             {
                 OnLogError("没有要处理的请求");
                 state.Break = true;
                 return;
             }
             if (httpSessionProcesser.ContainsKey(_httpClient.RequestUrl))
             {
                 processerAction = httpSessionProcesser[_httpClient.RequestUrl];
             }
             if (processerAction == null)
             {
                 foreach (var processer in httpSessionProcesser)
                 {
                     if (_httpClient.RequestUrl.StartsWith(processer.Key) ||
                         Regex.IsMatch(_httpClient.RequestUrl, processer.Key))
                     {
                         processerAction = processer.Value;
                         break;
                     }
                 }
             }
             if (processerAction != null)
             {
                 processerAction(state);
                 if (state.Break || state.Continue)
                 {
                     return;
                 }
                 if (!state.Processed)
                 {
                     ProcessHttpSessions(state);
                 }
                 return;
             }
             OnLogError("出错了,RequestUrl:" + _httpClient.RequestUrl);
             OnLogError("ResponseUrl:" + _httpClient.ResponseUrl);
             OnLogError("ResponseText:" + _httpClient.ResponseText);
             state.Break = true;
         }

经过实践和改进,本人已将上述部分分离成独立类库,如有需要可提供,以进行参考和交流。

 3、软件界面布局,界面截图已隐藏掉部分敏感信息


转载于:https://my.oschina.net/leeyibin/blog/84788

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_762305.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

百度云服务器网络检查,百度推出网站安全监测平台,为服务器提供安全漏洞扫描...

原标题&#xff1a;百度推出网站安全监测平台&#xff0c;为服务器提供安全漏洞扫描我无意间发现一个检查网站案例的工具&#xff1a;百度云扫描平台。可以为同学们提供网站的安全检查&#xff0c;下面将介绍如何利用这个安全平台为网站提供安全检测。网站安全性一直是互联网重…

ASP.NET网站权限设计实现(一)——使用PowerDesigner进行数据库设计

这里用PowerDesigner做一个初步的设计&#xff0c;后面可能会有修改。1、启动PowerDesigner新建物理数据模型2、工具栏3、新建表模型4、添加第一张表&#xff0c;可以双击表或右键菜单打开下面窗口别忘了把Owner选上dbo&#xff0c;然后切换到Columns选项卡完成后&#xff0c;表…

提高您的网站UX的10个有用的jQuery插件

结合jQuery有效在自己的网站建立良好的界面是一个伟大的方式&#xff0c;使用jQuery插件&#xff0c;帮助用户更加直观和互动显示内容。在这篇文章中&#xff0c;我会告诉你一个jQuery插件插件&#xff0c;提高你的用户体验。 Nivo Slider NIVO Slider是一个jQuery滑块插件&…

百度地图API 学习网站

2019独角兽企业重金招聘Python工程师标准>>> 官方示例&#xff1a;http://developer.baidu.com/map/jsdemo.htm#a1_2 &#xff08;注意&#xff1a;此网页可能由于浏览器问题&#xff0c;源代码编辑器中的代码不能看到。火狐亲测有效&#xff09; http://developer.…

十大好网站(转自豆瓣)

2019独角兽企业重金招聘Python工程师标准>>> 1、礼物街 http://www.giftjie.com/ 还在为送礼发愁吗?在这里和你一起发现礼物.分享礼物.收藏礼物 2、心理网-改变从这里开始 http://www.xinli001.com/        一个简单、温暖的心理网站&#xff0c;心理学爱好者…

奇奇seo优化软件_广东seo自动优化软件

广东seoxaa0c1自动优化软件&#xff0c;这个互联网时代&#xff0c;谁也不愿意在网络上缺席&#xff0c;企业商家更不愿意放弃网络这个巨大的宣传渠道&#xff0c;他们纷纷在网络上建立自己的企业网站&#xff0c;并且对网站进行多种优化&#xff0c;获取更多的流量&#xff0c…

如何使用lamp架构快速部署Opensns微博网站

文章目录MySQL服务器常见概念MySQL服务概述MySQL官方网站技术背景MariaDB官网&#xff1a;实验环境搭建lamp架构部署opensns微博网站使用LOIC 对新搭建的网站进行DDOS攻击总结MySQL服务器常见概念 MySQL服务概述 MySQL是一个关系型数据库管理系统&#xff0c;由瑞典MySQL AB公…

python最新官网图片_Python轻松爬取Rosimm写真网站全部图片

RosimmImage有图有真相def main_start(url): """ 爬虫入口&#xff0c;主要爬取操作 """ try: r requests.get(url.html, headersHEADERS, timeout10).text print(url.html) name_index 0 # 套图名&#xff0c;也作为文件夹名 folder_name Be…

Windows 8.1——将网站固定到开始菜单,自定义图标、颜色和Windows推送通知

记得在IE 9和Windows 7刚出来那会儿我写过一篇文章来介绍如何自定义网站将其固定到Windows的任务栏上&#xff0c;同时自定义图标及任务内容。那个功能在IE 9中被称之为JumpList。http://www.cnblogs.com/jaxu/archive/2010/11/17/1879617.html Windows 8对该功能进行了增强&am…

万字长文带你 搞定 linux BT 宝塔面板 之外网上快速搭建苹果CMS电影网站

文章目录万字长文带你搞定宝塔面板一、本地搭建宝塔面板及安装ecshop1.1前言1.2面板特色功能1.3安装环境说明1.4安装BT面板1.5常用管理命令1.6 BT面板一键安装LAMP/LNMP 环境1.7 BT 面板建站及使用技巧二、阿里云上部署高清电影网站2.1. 如何购买阿里云服务器2.2.快速优化阿里云…

ubuntu 忘记密码_WordPress建站:使用宝塔Linux面板,忘记宝塔面板密码的解决方案...

越来越多的人使用宝塔Linux面板来管理我们的服务器网站&#xff0c;最主要他是可视化的操作方式更加符合我们的一般用户习惯&#xff0c;同时对于没有技术知识的人来说就算是解决了大大的问题了。Linux面板那么其实网上关于Linux面板的工具还是有好多的&#xff0c;但笔者使用觉…

Windows Azure 网站上的 WordPress 3.8

&#xfeff;&#xfeff;编辑人员注释&#xff1a;本文章由 Windows Azure 网站团队的项目经理 Sunitha Muthukrishna 和 Windows Azure 网站开发人员体验合作伙伴共同撰写。 WordPress 3.8 的代号“Parker”是为了纪念bebop创新者Charlie Parker&#xff0c;现已在 Windows A…

基于mysql的许愿墙网站的搭建

首先需要两个服务器&#xff08;也可以用一台&#xff0c;但不推荐&#xff09; 1服务器用yum安装Apachephpphp-mysql 2服务器用yum安装mysql 1服务器 用yum安装Apache和phpphp-mysql yum install httpd -y yum install php -y yum install php -mysql 完成后必须关闭防火墙和…

ffmpeg视频网站 php,Linux+php+ffmpeg搭建视频网站

最近用Linuxphpffmpeg搭建视频网站&#xff0c;这过程中遇到很多难道&#xff0c;查了很多资料&#xff0c;现在来总结一下。1、Linuxphp实现大文件上传php配置文件默认上传最大为2M&#xff0c;可是为了上传大文件怎么办呢&#xff0c;下面就来说一下具体的修改的方法。打开ph…

如何在ASP.NET 网站项目中使用C# 6?

https://www.zhihu.com/question/48864375 .NET框架版本是4.6.1&#xff0c;Visual Studio版本是2015&#xff0c;系统是Window 7&#xff0c;为什么在使用C# 6语法的时候得到如下提示&#xff1f;其他C# 6语法也是同样的问题。请问如何切换到C# 6&#xff1f;在Visual Studio里…

陕西省计算机证书查询官方网站,陕西省专业技术人员资格证书查询系统正式上线...

原标题&#xff1a;陕西省专业技术人员资格证书查询系统正式上线近日&#xff0c;陕西省人社厅发布了专业技术人员资格证书查询系统正式上线的相关资讯&#xff0c;资讯指出&#xff0c;为加快推进“互联网政务服务”工作&#xff0c;进一步简化办事流程&#xff0c;陕西省专业…

非服务端渲染页面如何做SEO

前段时间对公司的社区h5网站&#xff0c;进行改版&#xff08;整站重写&#xff09;。老版本的网站是在一套古老的php框架下开发的&#xff0c;包含很多模板文件&#xff0c;大部分页面都是后端模板渲染&#xff0c;前端开发时要与后端沟通模板逻辑的编写&#xff0c;前后端耦合…

全球钓鱼网站调查报告:近半恶意注册域名针对国内银行企业

本文讲的是全球钓鱼网站调查报告&#xff1a;近半恶意注册域名针对国内银行企业&#xff0c;据最新报告显示&#xff0c;黑客越来越多地开始滥用那些高度分散的网络域名注册系统来购买可用于网络钓鱼攻击的互联网地址了。 他们所设计的骗局往往会使用合法获取的地址来设置模仿银…

知名网站的 404 页面长啥样?你的404长啥样?

每天浏览各大网站&#xff0c;难免会碰到404页面啊。你注意过404页面么&#xff1f;猿妹搜罗来了下面这些知名网站的404页面&#xff0c;以供大家欣赏&#xff0c;看看哪个网站更有创意&#xff1a; 新浪 新浪微博 优酷 腾讯 网易 淘宝 京东 搜狐 知乎 美团 饿了么 segmentfaul…

200个化工网站批量爬取

Python爬虫视频教程零基础小白到scrapy爬虫高手-轻松入门 https://item.taobao.com/item.htm?spma1z38n.10677092.0.0.482434a6EmUbbW&id564564604865 顺利100网站64秒 200网站570秒就搞不懂了&#xff0c;差距太大了。。 # -*- coding: utf-8 -*- """ Cre…