欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C#實(shí)現(xiàn)12306自動(dòng)登錄的方法

 更新時(shí)間:2022年02月24日 09:59:41   作者:yangyoushan  
本文介紹了C#實(shí)現(xiàn)12306自動(dòng)登錄的方法,主要方法是捕獲參數(shù)和url并補(bǔ)充參數(shù),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

依然使用IE9的捕獲參數(shù),做了一個(gè)12306的登錄功能。參照了網(wǎng)上童鞋們的做法。
其他都和前面幾篇讀取余票、票價(jià)一樣,不過登錄要用到證書的問題,這個(gè)參考了一個(gè)網(wǎng)上的例子。
不過12306會(huì)隨時(shí)變化,下面的登錄不一定一直都能成功。如果12306有變化,大家可以根據(jù)變化對(duì)代碼做修改??傊褂玫姆椒ú蛔?,就是捕獲參數(shù)和url,然后自己補(bǔ)充參數(shù)。
效果如下:

項(xiàng)目名稱:Test12306AutoLogin;
環(huán)境:.net 4.0,Visual studio 2010;
項(xiàng)目圖:

核心代碼如下,信任證書代碼:

 public class Messenger
  {
    public Messenger()
    {
    }

    public void Register(string message, Action callback)
    {
      this.Register(message, callback, null);
    }

    public void Register<T>(string message, Action<T> callback)
    {
      this.Register(message, callback, typeof(T));
    }


    void Register(string message, Delegate callback, Type parameterType)
    {
      if (String.IsNullOrEmpty(message))
        throw new ArgumentException("'message' cannot be null or empty.");

      if (callback == null)
        throw new ArgumentNullException("callback");

      this.VerifyParameterType(message, parameterType);

      _messageToActionsMap.AddAction(message, callback.Target, callback.Method, parameterType);
    }

    [Conditional("DEBUG")]
    void VerifyParameterType(string message, Type parameterType)
    {
      Type previouslyRegisteredParameterType = null;
      if (_messageToActionsMap.TryGetParameterType(message, out previouslyRegisteredParameterType))
      {
        if (previouslyRegisteredParameterType != null && parameterType != null)
        {
          if (!previouslyRegisteredParameterType.Equals(parameterType))
            throw new InvalidOperationException(string.Format(
              "The registered action's parameter type is inconsistent with the previously registered actions for message '{0}'.\nExpected: {1}\nAdding: {2}",
              message, 
              previouslyRegisteredParameterType.FullName,
              parameterType.FullName));
        }
        else
        {
          // One, or both, of previouslyRegisteredParameterType or callbackParameterType are null.
          if (previouslyRegisteredParameterType != parameterType)  // not both null?
          {
            throw new TargetParameterCountException(string.Format(
              "The registered action has a number of parameters inconsistent with the previously registered actions for message \"{0}\".\nExpected: {1}\nAdding: {2}",
              message,
              previouslyRegisteredParameterType == null ? 0 : 1,
              parameterType == null ? 0 : 1));
          }
        }
      }
    }

    public void NotifyColleagues(string message, object parameter)
    {
      if (String.IsNullOrEmpty(message))
        throw new ArgumentException("'message' cannot be null or empty.");


      Type registeredParameterType;
      if (_messageToActionsMap.TryGetParameterType(message, out registeredParameterType))
      {
        if (registeredParameterType == null)
          throw new TargetParameterCountException(string.Format("Cannot pass a parameter with message '{0}'. Registered action(s) expect no parameter.", message));
      }


      var actions = _messageToActionsMap.GetActions(message);
      if (actions != null)
        actions.ForEach(action => action.DynamicInvoke(parameter));
    }


    public void NotifyColleagues(string message)
    {
      if (String.IsNullOrEmpty(message))
        throw new ArgumentException("'message' cannot be null or empty.");


      Type registeredParameterType;
      if (_messageToActionsMap.TryGetParameterType(message, out registeredParameterType))
      {
        if (registeredParameterType != null)
          throw new TargetParameterCountException(string.Format("Must pass a parameter of type {0} with this message. Registered action(s) expect it.", registeredParameterType.FullName));
      }


      var actions = _messageToActionsMap.GetActions(message);
      if (actions != null)
        actions.ForEach(action => action.DynamicInvoke());
    }
   
    private class MessageToActionsMap
    {
      internal MessageToActionsMap()
      {
      }


      
      internal void AddAction(string message, object target, MethodInfo method, Type actionType)
      {
        if (message == null)
          throw new ArgumentNullException("message");


        if (method == null)
          throw new ArgumentNullException("method");


        lock (_map)
        {
          if (!_map.ContainsKey(message))
            _map[message] = new List<WeakAction>();


          _map[message].Add(new WeakAction(target, method, actionType));
        }
      }


      internal List<Delegate> GetActions(string message)
      {
        if (message == null)
          throw new ArgumentNullException("message");


        List<Delegate> actions;
        lock (_map)
        {
          if (!_map.ContainsKey(message))
            return null;


          List<WeakAction> weakActions = _map[message];
          actions = new List<Delegate>(weakActions.Count);
          for (int i = weakActions.Count - 1; i > -1; --i)
          {
            WeakAction weakAction = weakActions[i];
            if (weakAction == null)
              continue;


            Delegate action = weakAction.CreateAction();
            if (action != null)
            {
              actions.Add(action);
            }
            else
            {
              // The target object is dead, so get rid of the weak action.
              weakActions.Remove(weakAction);
            }
          }


          // Delete the list from the map if it is now empty.
          if (weakActions.Count == 0)
            _map.Remove(message);
        }


        // Reverse the list to ensure the callbacks are invoked in the order they were registered.
        actions.Reverse();


        return actions;
      }


      internal bool TryGetParameterType(string message, out Type parameterType)
      {
        if (message == null)
          throw new ArgumentNullException("message");


        parameterType = null;
        List<WeakAction> weakActions;
        lock (_map)
        {
          if (!_map.TryGetValue(message, out weakActions) || weakActions.Count == 0)
            return false;
        }
        parameterType = weakActions[0].ParameterType;
        return true;
      }


      readonly Dictionary<string, List<WeakAction>> _map = new Dictionary<string, List<WeakAction>>();
    }


   
    private class WeakAction
    {
      
      internal WeakAction(object target, MethodInfo method, Type parameterType)
      {
        if (target == null)
        {
          _targetRef = null;
        }
        else
        {
          _targetRef = new WeakReference(target);
        }


        _method = method;


        this.ParameterType = parameterType;


        if (parameterType == null)
        {
          _delegateType = typeof(Action);
        }
        else
        {
          _delegateType = typeof(Action<>).MakeGenericType(parameterType);
        }
      }


      internal Delegate CreateAction()
      {
        // Rehydrate into a real Action object, so that the method can be invoked.
        if (_targetRef == null)
        {
          return Delegate.CreateDelegate(_delegateType, _method);
        }
        else
        {
          try
          {
            object target = _targetRef.Target;
            if (target != null)
              return Delegate.CreateDelegate(_delegateType, target, _method);
          }
          catch
          {
          }
        }


        return null;
      }


      internal readonly Type ParameterType;
      readonly Type _delegateType;
      readonly MethodInfo _method;
      readonly WeakReference _targetRef;
    }


    readonly MessageToActionsMap _messageToActionsMap = new MessageToActionsMap();
  }

登錄的所有方法類:

public class Login12306Manager
  {
    private static readonly Messenger s_messenger = new Messenger();

    public static Messenger SMessenger { get { return s_messenger; } }

    public const string APPEND_MESSAGE = "append_message";

    public static string afterLoginCookie;

    private static string beforLoginCookie;

    static Login12306Manager()
    {
      SetCertificatePolicy();
    }

    /// <summary>
    /// 登 錄
    /// </summary>
    public static string Login(string userName,string password, string randomCode)
    {
      string resultHtml = string.Empty;

      try
      {
        string loginRand= DoGetLoginRand();

        HttpWebRequest request = (HttpWebRequest)WebRequest.Create
          (@"https://dynamic.12306.cn/otsweb/loginAction.do?method=login");

        request.Accept = @"text/html, application/xhtml+xml, */*";

        request.UserAgent = @"Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)";

        request.Referer = @"https://dynamic.12306.cn/otsweb/loginAction.do?method=init";

        request.ContentType = @"application/x-www-form-urlencoded";

        request.Headers[HttpRequestHeader.Cookie] = beforLoginCookie;

        request.Method = "POST";

        byte[] buffer = new byte[0];
        string parameter =
@"loginRand={0}&refundLogin=N&refundFlag=Y&isClick=&form_tk=null&loginUser.user_name={1}&nameErrorFocus=&user.password={2}&passwordErrorFocus=&randCode={3}&randErrorFocus=&NDU0NzY4NA%3D%3D=Nzg4ZDAxMGNkYTZlMTRjZA%3D%3D&myversion=undefined";

        parameter = string.Format(parameter, loginRand, userName, password, randomCode);

        buffer = Encoding.UTF8.GetBytes(parameter);

        request.ContentLength = buffer.Length;
        using (Stream writer = request.GetRequestStream())
        {
          writer.Write(buffer, 0, buffer.Length);

          writer.Flush();
        }

        using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
        {
          afterLoginCookie = response.GetResponseHeader("Set-cookie");


          using (StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8))
          {
            resultHtml = reader.ReadToEnd();


            resultHtml = ProcessLoginResult(resultHtml);
          }
        }
      }
      catch{ }

      return resultHtml;
    }

    /// <summary>
    /// 刷新驗(yàn)證碼
    /// </summary>
    public static string RefreshCode()
    {
      string randImageUrl = string.Empty;

      try
      {
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(string.Format(@"https://dynamic.12306.cn/otsweb/passCodeNewAction.do?module=login&rand=sjrand&{0}",

          new Random().Next(10000, 1000000)));

        request.Accept = @"image/png, image/svg+xml, image/*;q=0.8, */*;q=0.5";

        request.UserAgent = @"Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)";

        request.Referer = @"https://dynamic.12306.cn/otsweb/loginAction.do?method=init";
 
        request.Method = "GET";

        using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
        {
          beforLoginCookie = response.GetResponseHeader("Set-cookie");

          beforLoginCookie = Regex.Replace(beforLoginCookie, "path(?:[^,]+),?", "", RegexOptions.IgnoreCase);
 
          using (Stream reader = response.GetResponseStream())
          {
            string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, new Random().Next(10000, 99999) + @"loginRandCode.JPEG");


            using (FileStream file = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write))
            {
              reader.CopyTo(file);
            }

            randImageUrl = path;
          }
        }
      }
      catch { }

      return randImageUrl;
    }

    private static string DoGetLoginRand()
    {
      string loginRand=string.Empty;

      try
      {
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(@"https://dynamic.12306.cn/otsweb/loginAction.do?method=loginAysnSuggest");

        request.Accept = @"application/json, text/javascript, */*";

        request.UserAgent = @"Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)";
 
        request.Referer = @"https://dynamic.12306.cn/otsweb/loginAction.do?method=init";

        request.Headers[HttpRequestHeader.Cookie] = beforLoginCookie;

        request.Method = "POST";

        byte[] buffer = new byte[0];

        buffer = Encoding.UTF8.GetBytes(string.Empty);

        request.ContentLength = buffer.Length;

        using (Stream writer = request.GetRequestStream())
        {
          writer.Write(buffer, 0, buffer.Length);

          writer.Flush();
        }

        using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
        {
          using (StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8))
          {
            string result = reader.ReadToEnd();

            var loginRandContent = JsonConvert.DeserializeObject<BeforLoginRnad>(result);

            loginRand = loginRandContent.loginRand;
          }
        }
      }
      catch {}

      return loginRand;
    }
    /// <summary>
    /// 處理登錄結(jié)果
    /// </summary>
    /// <param name="html">登錄后返回的html文本</param>
    private static string ProcessLoginResult(string html)
    {
      string m_msgPattern = "message[^\"]+\"(?'message'[^\"]+)\";";

      string m_isLoginPatter = "isLogin\\s*=\\s*(?<val>.+)\n";

      string m_loginUserNamePattern = "u_name\\s*=\\s*['\"](?<name>.+)['\"]";

      if (html.Contains("請(qǐng)輸入正確的驗(yàn)證碼"))
      {
        return "驗(yàn)證碼錯(cuò)誤";
      }
      else if (html.Contains("當(dāng)前訪問用戶過多"))
      {
        return "當(dāng)前訪問用戶過多,請(qǐng)稍后再試...";
      }
      else
      {
        var match0 = Regex.Match(html, m_msgPattern, RegexOptions.Compiled);

        if (match0.Success)
        {
          string text = match0.Groups["message"].Value;

          if (text.Contains("密碼") || text.Contains("登錄名不存在"))
          {
            return "用戶名或者密碼錯(cuò)誤";
          }
          else
          {
           return text;
          }
        }

        var match = Regex.Match(html, m_isLoginPatter, RegexOptions.Compiled);

        if (match.Success && (match.Groups["val"].Value.Trim().ToLower() == "true"))
        {
          match = Regex.Match(html, m_loginUserNamePattern, RegexOptions.Compiled);
          if (match.Success)
          {
            string name = match.Groups["name"].Value;


            return "登錄成功:" + name;
          }
          else
          {
            return "登錄失敗,未知錯(cuò)誤";
          }
        }
        else
        {
          return "登錄失敗!!!";
        }
      }
    }

    /// <summary>
    /// Sets the cert policy.
    /// </summary>
    private static void SetCertificatePolicy()
    {
      ServicePointManager.ServerCertificateValidationCallback
            += RemoteCertificateValidate;
    }


    /// <summary>
    /// Remotes the certificate validate.
    /// </summary>
    private static bool RemoteCertificateValidate(
      object sender, X509Certificate cert,
      X509Chain chain, SslPolicyErrors error)
    {
      SMessenger.NotifyColleagues(APPEND_MESSAGE, "信任任何證書...");
      return true;
    }
  }

  public class BeforLoginRnad
  {
    public string loginRand { get; set; }


    public string randError { get; set; }
  }

注意登錄時(shí),主要的正文是:

               string parameter =
@"loginRand={0}&refundLogin=N&refundFlag=Y&isClick=&form_tk=null&loginUser.user_name={1}&nameErrorFocus=&user.password={2}&passwordErrorFocus=&randCode={3}&randErrorFocus=&NDU0NzY4NA%3D%3D=Nzg4ZDAxMGNkYTZlMTRjZA%3D%3D&myversion=undefined",它有三個(gè)參數(shù),登錄時(shí)的隨機(jī)碼,用戶名,密碼和驗(yàn)證碼組成。

調(diào)用如下:

前臺(tái)wpf代碼:

 

<Window x:Class="Test12306AutoLogin.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow">
  <StackPanel>
    <Grid>
      <Grid.Resources>
        <Style TargetType="TextBlock">
          <Setter Property="FontFamily" Value="Microsoft YaHei"/>
          <Setter Property="FontSize" Value="20"/>
          <Setter Property="VerticalAlignment" Value="Center"/>
        </Style>


        <Style TargetType="TextBox">
          <Setter Property="FontSize" Value="20"/>
          <Setter Property="MinWidth" Value="300"/>
          <Setter Property="Height" Value="50"/>
          <Setter Property="VerticalAlignment" Value="Center"/>
        </Style>


        <Style TargetType="PasswordBox">
          <Setter Property="FontSize" Value="20"/>
          <Setter Property="MinWidth" Value="300"/>
          <Setter Property="Height" Value="50"/>
          <Setter Property="VerticalAlignment" Value="Center"/>
        </Style>
      </Grid.Resources>
      <Grid.RowDefinitions>
        <RowDefinition Height="auto"/>
        <RowDefinition Height="auto"/>
        <RowDefinition Height="auto"/>
        <RowDefinition Height="auto"/>
      </Grid.RowDefinitions>


      <Grid.ColumnDefinitions>
        <ColumnDefinition Width="auto"/>
        <ColumnDefinition Width="auto"/>
      </Grid.ColumnDefinitions>


      <TextBlock Grid.Row="0" Grid.Column="0" Text="用戶名:"/>
      <TextBox Grid.Row="0" Grid.Column="1" x:Name="txtUserName"/>


      <TextBlock Grid.Row="1" Grid.Column="0" Text="密 碼:"/>
      <PasswordBox Grid.Row="1" Grid.Column="1" x:Name="txtPassword"/>


      <TextBlock Grid.Row="3" Grid.Column="0" Text="驗(yàn)證碼"/>
      <StackPanel Grid.Row="3" Grid.Column="1" Orientation="Horizontal"
            VerticalAlignment="Center">
        <TextBox x:Name="txtRandCode" Width="150"/>
        <Image x:Name="imageRandCode" Width="70"/>
        <Button Content="刷新驗(yàn)證碼" Height="30" Width="80" Click="ButtonRefreshRandCode_Click" />
      </StackPanel>
    </Grid>


    <Button Content="登 錄" Width="150" Height="50" Click="ButtonLogin_Click" />


    <RichTextBox x:Name="rtxResultContent" MinHeight="200"/>


  </StackPanel>
</Window>

后臺(tái)代碼:

public partial class MainWindow : Window
  {
    public MainWindow()
    {
      InitializeComponent();


      this.Loaded += new RoutedEventHandler(MainWindow_Loaded);
    }


    void MainWindow_Loaded(object sender, RoutedEventArgs e)
    {
      DoRefreshRandCode();
    }


    private void DoRefreshRandCode()
    {
      string imageRandUrl = Login12306Manager.RefreshCode();


      if (File.Exists(imageRandUrl))
      {
        ImageSource src = (ImageSource)(new ImageSourceConverter().ConvertFromString(imageRandUrl));


        this.imageRandCode.Source = src;
      }


      this.txtRandCode.Text = string.Empty;
    }


    /// <summary>
    /// 登錄
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void ButtonLogin_Click(object sender, RoutedEventArgs e)
    {
      string userName = this.txtUserName.Text;


      string password = this.txtPassword.Password;


      string randCode = this.txtRandCode.Text;


      if (string.IsNullOrEmpty(userName) || string.IsNullOrEmpty(password) || string.IsNullOrEmpty(randCode))
      {
        MessageBox.Show("請(qǐng)?zhí)顚懲暾畔?);


        return;
      }

      string html = Login12306Manager.Login(userName, password, randCode);


      System.Windows.Documents.FlowDocument doc = this.rtxResultContent.Document;


      doc.Blocks.Clear();


      this.rtxResultContent.AppendText(html); 
    }


    /// <summary>
    /// 刷新驗(yàn)證碼
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void ButtonRefreshRandCode_Click(object sender, RoutedEventArgs e)
    {
      DoRefreshRandCode();
    }
  }

以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助。

相關(guān)文章

  • C#寫入對(duì)象或集合類型數(shù)據(jù)到xml文件的方法

    C#寫入對(duì)象或集合類型數(shù)據(jù)到xml文件的方法

    這篇文章主要介紹了C#寫入對(duì)象或集合類型數(shù)據(jù)到xml文件的方法,涉及C#針對(duì)XML文件的相關(guān)操作技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-07-07
  • 簡介C#讀取XML的兩種方式

    簡介C#讀取XML的兩種方式

    在程序中訪問進(jìn)而操作XML文件一般有兩種模型,分別是使用DOM(文檔對(duì)象模型)和流模型,使用DOM的好處在于它允許編輯和更新XML文檔,可以隨機(jī)訪問文檔中的數(shù)據(jù),可以使用XPath查詢
    2013-03-03
  • C#中的yield關(guān)鍵字的使用方法介紹

    C#中的yield關(guān)鍵字的使用方法介紹

    yield這個(gè)關(guān)鍵字是和迭代器掛鉤的,而且是與return一起以yield return的形式合用的,用來返回迭代器中的條目。
    2013-04-04
  • C#圖形編程GDI+基礎(chǔ)介紹

    C#圖形編程GDI+基礎(chǔ)介紹

    這篇文章介紹了C#中的圖形編程GDI+,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-02-02
  • C#判斷三角形的類型

    C#判斷三角形的類型

    這篇文章主要介紹了C#判斷三角形的類型的方法,通過輸入三角形的三條邊長,判斷是否能構(gòu)成一個(gè)三角形,感興趣的小伙伴們可以參考一下
    2015-11-11
  • CAD2008+VS2008開發(fā)ObjectARX加載失敗問題(推薦)

    CAD2008+VS2008開發(fā)ObjectARX加載失敗問題(推薦)

    這篇文章主要介紹了CAD2008+VS2008開發(fā)ObjectARX加載失敗問題,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-04-04
  • C# 排序算法之堆排序

    C# 排序算法之堆排序

    這里是指一種數(shù)據(jù)結(jié)構(gòu),而不是我們?cè)贑#中提到的用于存儲(chǔ)引用類型對(duì)象的地方。它可以被當(dāng)成一棵完全二叉樹。
    2010-09-09
  • C#清除WebBrowser中Cookie緩存的方法

    C#清除WebBrowser中Cookie緩存的方法

    這篇文章主要介紹了C#清除WebBrowser中Cookie緩存的方法,涉及C#針對(duì)WebBrowser控件的操作技巧,非常簡單實(shí)用,需要的朋友可以參考下
    2016-05-05
  • LINQ(語言集成查詢)使用案例

    LINQ(語言集成查詢)使用案例

    這篇文章介紹了LINQ(語言集成查詢)的使用案例,文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-04-04
  • C#異步調(diào)用實(shí)例小結(jié)

    C#異步調(diào)用實(shí)例小結(jié)

    這篇文章主要介紹了C#異步調(diào)用的方法,實(shí)例分析了C#同步調(diào)用及異步調(diào)用的常用技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-08-08

最新評(píng)論