前言

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

  主要是看下请求类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 = ;//超时时间,但前提是请求允许超时才行。
    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 = ;
    } public static string Get(string url, CookieContainer cookie, int retryCount = )
    {
    return Request(url, cookie, "GET", null, retryCount);
    }
    public static string Post(string url, CookieContainer cookie, string postData, int retryCount = )
    {
    return Request(url, cookie, "POST", postData, retryCount);
    } public static string Post(string url, CookieContainer cookie, string postData, Action<HttpWebRequest> beginRequest, int reTry = )
    {
    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 = ; 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, , byteRequest.Length);
    stream.Close();
    }
    var httpWebResponse = (HttpWebResponse)request.GetResponse(); var responseStream = httpWebResponse.GetResponseStream();
    if (responseStream == null) return string.Empty;
    if (responseStream.CanTimeout)
    {
    responseStream.ReadTimeout = ;
    }
    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, );
    }
    public string Post(string url, string postData)
    {
    return HttpClient.Post(AddCsrfTokenToUrl(url), this.Cookie, AddCsrfTokenToPostData(postData), );
    }
    //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:

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

      2.DoLoginStep1:

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

      3.DoLoginStep2:

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

      4.DoCheckCode:

         /// <summary>
/// 获取checkcode,图片验证码,其实有时候是不需要的。可以先判断一下,不行再获取验证码
/// </summary>
/// <param name="aliClient">aliClient</param>
/// <returns>验证码图片,如果是web应用,直接把checkCodeUrl(img src=checkCodeUrl)写进去就行了</returns>
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的相关使用。

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

  1. c# 使用 HttpWebRequest模拟登陆

    c# 使用 HttpWebRequest模拟登陆(附带验证码) 分类: C# .net2010-06-04 00:50 35647人阅读 评论(43) 收藏 举报 c#exceptionstreams ...

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

    无论使用任何语言做模拟登陆或者抓取访问页面,无外乎以下思路:第一 启用一个web访问会话方法或者实例化一个web访问类,如.net中的HttpWebRequest:第二 模拟POST或者GET方式提交 ...

  3. c# 使用 HttpWebRequest模拟登陆(附带验证码)

    在C#中,可以使用HttpWebRequest进行相关的模拟登陆,登陆后进行相关的操作,比如抓取数据,页面分析,制作相关登陆助手等等. 先说下流程 1.使用httpwebrequest先进入你要登录的 ...

  4. 使用C#的HttpWebRequest模拟登陆访问人人网

    使用任何语言做模拟登陆或者抓取访问页面,无外乎以下思路: 第一 启用一个web访问会话方法或者实例化一个web访问类,如.net中的HttpWebRequest:第二 模拟POST或者GET方式提交的 ...

  5. 转:使用C#的HttpWebRequest模拟登陆网站

    这篇文章是有关模拟登录网站方面的. 实现步骤: 启用一个web会话 发送模拟数据请求(POST或者GET) 获取会话的CooKie 并根据该CooKie继续访问登录后的页面,获取后续访问的页面数据. ...

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

    很久没有写新的东西了,今天在工作中遇到的一个问题,感觉很有用,有种想记下来的冲动. 这篇文章是有关模拟登录网站方面的. 实现步骤: 启用一个web会话 发送模拟数据请求(POST或者GET) 获取会话 ...

  7. HttpWebRequest模拟登陆,存储Cookie以便登录请求后使用

    [一篮饭特稀原创,转载请注明出自http://www.cnblogs.com/wanghafan/p/3284481.html] PostLogin :登录,并保存Cookie 1 public st ...

  8. C#如何HttpWebRequest模拟登陆,获取服务端返回Cookie以便登录请求后使用

    public static string GetCookie(string requestUrlString, Encoding encoding, ref CookieContainer cooki ...

  9. 通过HttpWebRequest实现模拟登陆

    1>通过HttpWebRequest模拟登陆 using System; using System.Collections.Generic; using System.Linq; using S ...

随机推荐

  1. nagios 安装和配置(含有nrpe结束)所有 (两)

    二.ndoutils 安装: 1.mysql安装(若未安装) #apt-get install mysql-servermysql-client 2.DBI安装(若未安装) #cd /usr/loca ...

  2. android 实现分享功能两种方法

    当我想做一个智能的记事本的时候,我就在尝试自己写一组分享功能.后来才知道,原来每个社交软件中都有自己的分享接口. 这就大大减少了我们的代码量了. 第一种方法:特点--简单 package com.ex ...

  3. .NET 相依性注入

    发布<.NET 依賴注入>电子书 beta 版 书籍进度 本书目前已经开始发行 beta 版,完成进度约 70%.(我希望这本书不要超过 200 页,目前看起来应该没问题.) 简介 本书内 ...

  4. .NET MVC通过反射获取数据修

    .NET MVC通过反射获取数据修 折磨了我一个晚上的问题,奈何对物理的反射印象太深了,整天去想着物理的反射.折射怎么解.感谢少将哥哥给我的指点,经过一个晚上对反射的恶补,最终搞定了.纪念一下. 1. ...

  5. NPOI 2.0 Excel读取显示

    NPOI 2.0 Excel读取显示   最近接到需求,需要把excel表格里的数据原样展示到web页面,主要是满足随意跨行跨列. 之前用过一点NPOI,不过接触的不太多,趁这次机会再熟悉一下.由于操 ...

  6. 对student进行增删改

    drop package TechEd_pkg_Student; CREATE OR REPLACE PACKAGE TechEd_pkg_Student AS FUNCTION F_CREATE(p ...

  7. iOS基础 - UIDynamic

    一.UIKit动力学 UIKit动力学最大的特点是将现实世界动力驱动的动画引入了UIKit,比如重力,铰链连接,碰撞,悬挂等效果,即将2D物理引擎引入了UIKit 注意:UIKit动力学的引入,并不是 ...

  8. .NET里的行为驱动开发

    BDD (Given - When - then) Ruby Cucumber, Java FitNesse , Python RoboFramework, C# specflow nspec .NE ...

  9. POJ 1002 UVA 755 487--3279 电话排序 简单但不容易的水题

    题意:给你许多串字符串,从中提取电话号码,输出出现复数次的电话号码及次数. 以下是我艰难的AC历程:(这题估计是我刷的题目题解次数排前的了...) 题目不是很难理解,刚开始想到用map,但stl的ma ...

  10. vijos1060 隔板法

    排列组合问题 之前没有学过隔板法,随便学习了一下 其实挺好理解的 附上题解: 先只考虑一种球:因为有n个盒子每个盒子可以放任意多球,还可以空出来任意多球.所以可以考虑为n+1个盒子,最后一个盒子里面是 ...