使用HttpWebRequest模拟登陆阿里巴巴(alibaba、httpwebrequest、login)

前言

  其实老喜欢取经,偶尔也得分享下。关于阿里巴巴国际站的登陆,过程有点复杂但是算不上难。一不小心少个东西倒也挺麻烦的。

  主要是看下请求类HttpClient基本请求封装使用,AliClient模拟浏览器的操作与数据封装

  这里只是简单说一下主要的类和注意点,主要步骤与注意点都写在代码注释里了。项目源码下载地址:http://git.oschina.net/GspringG/AliLogin

正文

  1. 主要类/方法

  • HttpClient请求模拟的基础类,也就那么个过程http header设置一下,然后模拟就行了.需要注意的地方在代码注释里

    using System;
    using System.Drawing;
    using System.IO;
    using System.Net;
    using System.Net.Security;
    using System.Security.Cryptography.X509Certificates;
    using System.Text;
    
    namespace Main.Http
    {
        public class HttpClient
        {
            const string Accept = "text/html, application/xhtml+xml, */*";
            public const string UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko";
            const int Timeout = 15000;//超时时间,但前提是请求允许超时才行。
            const string AcceptLanguage = "Accept-Language:zh-CN";
            const string AcceptEncoding = "Accept-Encoding:gzip, deflate";
            const string Contenttype = "application/x-www-form-urlencoded";
            /// <summary>
            /// 静态构造方法
            /// </summary>
            static HttpClient()
            {
                //伪造证书,验证服务器证书回调自动验证
                ServicePointManager.ServerCertificateValidationCallback = CheckValidationResult;
                //客户端系统 win7或者winxp上可能会出现 could not create ssl/tls secure channel的问题导致加载ali登陆验证码报错
                //这里必须设置
                ServicePointManager.Expect100Continue = false;//默认是true,要手动设为false
                ServicePointManager.SecurityProtocol=SecurityProtocolType.Ssl3;
    
                ServicePointManager.DefaultConnectionLimit = 1000;
            }
    
            public static string Get(string url, CookieContainer cookie, int retryCount = 3)
            {
                return Request(url, cookie, "GET", null, retryCount);
            }
            public static string Post(string url, CookieContainer cookie, string postData, int retryCount = 3)
            {
                return Request(url, cookie, "POST", postData, retryCount);
            }
    
            public static string Post(string url, CookieContainer cookie, string postData, Action<HttpWebRequest> beginRequest, int reTry = 0)
            {
                return Request(url, cookie, "POST", postData, reTry, beginRequest);
            }
    
            private static string Request(string url, CookieContainer cookie, string method, string postData, int retryCount, Action<HttpWebRequest> beginRequest = null)
            {
                string html = string.Empty;
                for (var i = 0; i <= retryCount; i++)
                {
                    try
                    {
                        html = Request(url, cookie, method, postData, beginRequest);
                        return html;
                    }
                    catch (Exception e)
                    {
                        if (i == retryCount)
                        {
                            throw new Exception(e.ToString());
                        }
                    }
                }
                return html;
            }
    
            public static bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
            {   // 伪造证书,总是接受
                return true;
            }
    
            private static string Request(string url, CookieContainer cookie, string method, string postData, Action<HttpWebRequest> beginRequestHandle = null)
            {
                var request = (HttpWebRequest)WebRequest.Create(url);
                request.Method = method;
                request.CookieContainer = cookie;
                request.AllowAutoRedirect = true;
                request.ContentType = Contenttype;
                request.Accept = Accept;
                request.Timeout = Timeout;
                request.UserAgent = UserAgent;
                request.Headers.Add(AcceptLanguage);
                request.Headers.Add(AcceptEncoding);
    
                request.AutomaticDecompression = DecompressionMethods.GZip;
    
                if (beginRequestHandle != null)
                    beginRequestHandle(request);
    
                if (!string.IsNullOrEmpty(postData))
                {
                    byte[] byteRequest = Encoding.UTF8.GetBytes(postData);
                    request.ContentLength = byteRequest.Length;
                    var stream = request.GetRequestStream();
                    stream.Write(byteRequest, 0, byteRequest.Length);
                    stream.Close();
                }
                var httpWebResponse = (HttpWebResponse)request.GetResponse();
    
                var responseStream = httpWebResponse.GetResponseStream();
                if (responseStream == null) return string.Empty;
                if (responseStream.CanTimeout)
                {
                    responseStream.ReadTimeout = 15000;
                }
                var encoding = Encoding.GetEncoding(httpWebResponse.CharacterSet ?? "UTF8");
    
                var streamReader = new StreamReader(responseStream, encoding);
    
                string html = streamReader.ReadToEnd();
                streamReader.Close();
                responseStream.Close();
                request.Abort();
                httpWebResponse.Close();
                return html;
            }
    
            public static byte[] DownloadFile(string url, CookieContainer cookie)
            {
                var webClient = new CookieWebClient { Cookie = cookie };
                byte[] data = webClient.DownloadData(url);
                return data;
            }
            public static Image DownloadImage(string url, CookieContainer cookie)
            {
                byte[] data = DownloadFile(url, cookie);
                var ms = new MemoryStream(data);
                var image = Image.FromStream(ms);
                ms.Close();
                return image;
            }
        }
    }

  • AliClient:相当于一个浏览器,存储着cookie、session、_csrf_token_、userName等信息。客户端发出的模拟请求都通过AliClient发出保证全部在一个会话中。(想想一个浏览器需要些什么,浏览器是怎么做的。就感觉很合理了)

    using System;
    using System.Collections.Specialized;
    using System.Net;
    using System.Web;
    using Main.Http;
    
    namespace Main.Ali
    {
        public class AliClient
        {
            const string _csrf_token_ = "_csrf_token_";
            public CookieContainer Cookie { get; set; }
            public string SessionId { get; set; }
    
            public string CsrfToken { get; set; }
            public AliLoginUser AliLoginUser { get; set; }
            public string DmtrackPageid { get; set; }
            public string UserName
            {
                get
                {
                    if (AliLoginUser == null) return null;
                    if (AliLoginUser.person_data == null) return null;
                    return AliLoginUser.person_data.login_id;
                }
            }
            public AliClient()
            {
                Cookie = new CookieContainer();
            }
            public string Get(string url)
            {
                return HttpClient.Get(AddCsrfTokenToUrl(url), this.Cookie, 3);
            }
            public string Post(string url, string postData)
            {
                return HttpClient.Post(AddCsrfTokenToUrl(url), this.Cookie, AddCsrfTokenToPostData(postData), 3);
            }
            //post请求时不用手动加了,默认都加上
            private string AddCsrfTokenToPostData(string postData)
            {
                NameValueCollection queryString = HttpUtility.ParseQueryString(postData);
                if (queryString[_csrf_token_] == null)
                {
                    queryString.Add("_csrf_token_", this.CsrfToken);
                }
                return queryString.ToString();
            }
            //Get请求时不用手动加了,默认都加上
            private string AddCsrfTokenToUrl(string url)
            {
    
                if (string.IsNullOrWhiteSpace(this.CsrfToken)) return url;
                UriBuilder ub = new UriBuilder(url);
                NameValueCollection queryString = HttpUtility.ParseQueryString(ub.Query);
                if (queryString[_csrf_token_] == null)
                {
                    queryString.Add("_csrf_token_", this.CsrfToken);
                }
                ub.Query = queryString.ToString();
                string newurl = ub.Uri.ToString();
                return newurl;
            }
    
        }
    }

  • AliPassporter:阿里巴巴登陆核心类(具体个注意细节点都在代码内部已注释)

    登陆过程为:从上到下依次

      1.PrepareLogin:

1         /// <summary>
2         /// 登陆前先请求一下页面获取sessionId,DmtrackPageid,初始化cookie的值,像正常访问浏览器一样
3         /// </summary>
4         /// <param name="aliClient"> AliClient当需要多账号登陆时,每个账号的cookie 各种验证id等独有的东西放到各自的Client中,相当于每个独立的浏览器</param>
5         /// <param name="isSpec">针对某种特殊情况取值方法不一样,默认false</param>
6         public static void PrepareLogin(AliClient aliClient, bool isSpec = false);

      2.DoLoginStep1:

1        /// <summary>
2         ///     登录阿里巴巴
3         /// </summary>
4         /// <param name="aliClient"> AliClient当需要多账号登陆时,每个账号的cookie 各种验证id等独有的东西放到各自的Client中</param>
5         /// <param name="account">帐户名</param>
6         /// <param name="password">密码</param>
7         /// <param name="checkCode">验证码</param>
8         /// <returns>登陆结果(true/false)</returns>
9         public static bool DoLoginStep1(AliClient aliClient, string account, string password, string checkCode);

      3.DoLoginStep2:

 1         /// <summary>
 2         ///     登录处理第二步
 3         /// </summary>
 4         /// <param name="aliClient"></param>
 5         /// <param name="userId">账户</param>
 6         /// <param name="password">密码</param>
 7         /// <param name="dmtrackPageid">令牌1</param>
 8         /// <param name="st">令牌三</param>
 9         /// <returns>登陆结果</returns>
10         private static bool DoLoginStep2(AliClient aliClient, string userId, string password, string dmtrackPageid, string st);

      4.DoCheckCode:

1         /// <summary>
2         /// 获取checkcode,图片验证码,其实有时候是不需要的。可以先判断一下,不行再获取验证码
3         /// </summary>
4         /// <param name="aliClient">aliClient</param>
5         /// <returns>验证码图片,如果是web应用,直接把checkCodeUrl(img src=checkCodeUrl)写进去就行了</returns>
6         public static Image DoCheckCode(AliClient aliClient);

      5.登陆过程中还会调用GetToken、GetSt、GetCsrfToken等方法提供登录所需要的get/post参数

      6.前端调用流程:登录过程关键代码(详情参见详细代码)

           //1.初始化_aliClient,相当于打开一个浏览器,并设置一个空的cookie
           AliClient  _aliClient=new AliClient {Cookie = new CookieContainer()};
           //2.无需验证码登陆时这里替换为PrepareLogin(_aliClient);
           RefreshCheckCode();
           //3.登陆系统,异步方法防止页面假死
           var data=await AliPassporter.DoLoginAsync(_aliClient, UserName, Password, CheckCode);
           if (data)
            {
                //登陆成功,登陆后其他数据就随便抓了,这里要注意,需要手机验证码的,要在网页中先把手机验证码输入了
                //我的测试账号默认写在里面,别乱玩就行了
                //进入管理个人信息页面
                var html = _aliClient.Get("http://accounts.alibaba.com/user/organization/manage_person_profile.htm");
                MessageBox.Show("登陆成功!");
                //_aliClient.Post("");
            }
            else
            {
                MessageBox.Show("登陆失败!");
            }            

总结

  以上就是阿里巴巴国际站登陆的全部过程,总体大同小异,很久之前写的了(建议先把注释看一遍再用)。现在拿出来分享一下,顺便复习一下HttpWebRequest的相关使用。

时间: 2024-10-26 11:47:00

使用HttpWebRequest模拟登陆阿里巴巴(alibaba、httpwebrequest、login)的相关文章

使用C#的HttpWebRequest模拟登陆访问人人网(转)

无论使用任何语言做模拟登陆或者抓取访问页面,无外乎以下思路:第一 启用一个web访问会话方法或者实例化一个web访问类,如.net中的HttpWebRequest:第二 模拟POST或者GET方式提交的数据:第三 模拟请求的头:第四 提交请求并获得响应,及对响应做我们所需要的处理.这里我们以人人网的登录为例,将涉及到POST以及GET两种请求方式.在之前的文章<免费网页抓包工具,火狐插件FireBug的抓包使用教程>中我们知道,登陆人人网的时候,一共做了一个POST请求以及两个GET请求,如下

使用C#的HttpWebRequest模拟登陆网站

这篇文章是有关模拟登录网站方面的. 实现步骤: 启用一个web会话 发送模拟数据请求(POST或者GET) 获取会话的CooKie 并根据该CooKie继续访问登录后的页面,获取后续访问的页面数据. 我们以登录人人网为例,首先需要分析人人网登录时POST的数据格式,这个可以通过IE9中只带的F12快捷键,调出开发人员工具.如下图: 通过开始捕获得到POST的地址和POST的数据 POST数据: [email protected]&password=111&icode=&origUR

HttpWebRequest模拟c#网站登录

模拟登录asp.net开发的网站.POST数据相对来说比较简单.如何触发事件?一个页面可能有多个post按钮,如修改.删除,按钮,页面提交后,会进入对应的事件中.通过什么机制触发事件一直没有找到满意的答案. 之前在博问中寻求过帮助,也许是没有彻底理解热心园友的回复,问题一直没有解决,但依然感谢走过.路过的朋友. 博问链接:1.c#模拟网页登陆   2. HttpWebRequest 模拟登录 知道看到了这篇博文才实现了c#网站的登录. 对于asp.net开发的网站,需要将__VIEWSTATE和

HttpWebRequest 模拟登录响应点击事件(开源自己用的HttpHelper类)

平时也经常采集网站数据,也做模拟登录,但一般都是html控件POST到页面登录:还没有遇到用户服务器控件button按钮点击事件登录的,今天像往常一样POST传递参数,但怎么都能登录不了:最后发现还有两个参数需要传,__EVENTVALIDATION和__VIEWSTATE 在传的过程中需要对参数值进行URL编码 System.Web.HttpUtility.UrlEncode(value) 模拟登录代码:在本地写的一个测试的网站来模拟登录,原理都一样: Request request = ne

博客园的模拟登陆(Simulated Login)

查看正常情况下登录博客园时本地浏览器向博客园的服务器发送的数据 依据上一步得到的由本地浏览器发送给博客园服务器的数据包内容进行模拟登陆 scrapy模拟登陆博客园 Reference 1.查看正常情况下登录博客园时本地浏览器向博客园的服务器发送的数据 首先打开博客园登录界面,填入登录用户名和密码,按快捷键 Ctrl+Alt+I 打开开发者管理器,然后点击登录 按钮,则可以在开发者管理器里看到发送的数据包内容. 数据包内容的查看位置如下图所示. 下面贴出了该数据包的内容 1. General 1.

C#后台HttpWebRequest模拟跨域Ajax请求,注册Windows服务到服务器上

项目需求,暂且叫A.B公司吧.我们公司需要从A公司哪里读取机器上的数据,放到我们数据库中.然后再将数据库中存的数据,提供一个接口,B公司来调用,大概这个意思. 好了,言归正传.这个是之前做好的界面,用户需要手动点击“开始”,然后写了个定时器,不停的来回调用 部分源码(5秒调用后台处理) 1 function refreshCount() { 2 if (prj.is_port_state_1 == false) { 3 var grid_down = query_panel.grid_down;

使用C#发送Http 请求实现模拟登陆(以博客园为例)

原文:使用C#发送Http 请求实现模拟登陆(以博客园为例) 模拟登陆的原理很简单,就是发送一个Http 请求服务器获得响应,然后客户端获取到cookie即可实现模拟登陆,比如一些抢票软件的原理无非也是这样模拟客户端的cookie 然后发送请求去抢票,然后12306 本文将演示如何用C# 来实现模拟登陆的,推荐一款工具Fiddler,这是一款监听http 请求的利器.废话不多说,我就以博客园为例来实现模拟登陆.首先我登陆博客园 http://passport.cnblogs.com/login.

如何模拟登陆添加了CSRF保护的网站

上次写了篇文章,内容是如何利用WebClient模拟登陆CSRF控制的网站,回复中有人还是不理解,现在另开一篇,打算说说用Python如何来登陆. 开写之前,先说下为什么webrequest不行,常规情况下,我们在利用webrequest的时候,都是如下的形式: 1 string url = "loginurl"; 2 StringBuilder sb = new StringBuilder(); 3 sb.Append("username=un"); 4 sb.A

如何利用WebClient模拟登陆CSRF控制的网站

一般我们都是利用WebRequest这个类来向服务器进行数据的POST,不过很多情况下相应的服务器都有验证,看你是不是登陆,是不是来自同一个域,这些都简单,我们可以更改其属性来达到欺骗服务器.不过如果服务器做了CSRF控制,那我们怎么办? 不熟悉CSRF的可以问下G哥此为何物,这里简单介绍下.CSRF常规来讲是在表单页里放一个隐藏域,然后在表单提交的时候服务器验证POST过来的NAVEVALUE里面是不是包含此域,同时如果包含验证其值. 问题来了,在这种情况下我们POST到服务器的数据怎么写,虽