コード例 #1
0
        public void testXls()
        {
            SBillTaskResult result = new SBillTaskResult();
            SBillTaskInfo   info   = new SBillTaskInfo();

            parseXlsContent($"D:\\code\\FKCashier\\FKCashierBank\\bin\\x86\\Debug\\test\\detailabc20170727.xls", ref result, info);
        }
コード例 #2
0
        /// <summary>
        /// 解析流水页面
        /// </summary>
        /// <param name="html"></param>
        /// <param name="result"></param>
        /// <returns></returns>
        private bool ParseAutoBillHtmlPage(HtmlDocument html, ref SBillTaskResult result, SBillTaskInfo info)
        {
            try
            {
                var nodes = html.DocumentNode.SelectSingleNode("./table/tbody");
                if (nodes == null)
                {
                    LOGGER.INFO("未找到有效流水数据,可能已经查到最后一页");
                    return(false);
                }
                var items = nodes.SelectNodes("./tr");
                if (items == null)
                {
                    LOGGER.INFO("未找到有效流水数据,可能已经查到最后一页");
                    return(false);
                }
                if (items.Count == 0)
                {
                    LOGGER.INFO("未找到有效流水数据,可能已经查到最后一页");
                    return(false);
                }

                foreach (var node in nodes.SelectNodes("./tr"))
                {
                    SBillTaskResult.SBankBillInfo billItem = new SBillTaskResult.SBankBillInfo();
                    // 解析单一流水对象
                    if (ParseOneBillHtmlPage(node, ref billItem) == false)
                    {
                        continue;
                    }
                    // citic明细没有时间,一律不过滤

                    /*if (ResultFilter.TimeFilter(info, billItem.submitTime))
                     * {
                     *  result.billsList.Add(billItem);
                     * }*/

                    result.billsList.Add(billItem);
                }

                result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_Successed;
            }
            catch (Exception e)
            {
                result.msg    = "CITIC解析返回html错误";
                result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_AutoProcessFailed;
                LOGGER.WARN($"CITIC解析返回html错误:{e.Message}");
                return(false);
            }
            return(true);
        }
コード例 #3
0
        /// <summary>
        /// 处理流水查询任务
        /// </summary>
        private void HandleBillTask()
        {
            try
            {
                SBillTaskInfo info = m_BillTasksList.Peek();    // 取出消息,不删除

                LOGGER.INFO($"Handle a new bill task:\n {info.ToLogString()} \n, still left {m_BillTasksList.Count - 1} tasks in queue.");

                SBillTaskResult dealResult = new SBillTaskResult();
                dealResult.taskID = info.taskID;
                dealResult.nodeID = GetCurCashierNodeID();
                dealResult.bankId = info.bankId;

                // 记录当前在处理的任务ID
                SetCurTaskID(info.taskID);

                // 开始处理
                AutomationBill(info, ref dealResult);

                LOGGER.WARN($"Auto get bill task is done. Now ready to send msg to server. TaskID = {info.taskID}.", info.taskID);

                // 发送回馈消息给服务器完毕
                HttpSendResult SendResult = RequestSender.SendRequestToServer(dealResult);
                if (SendResult.IsSendSuccessed())
                {
                    SetLastTaskID(info.taskID);
                    SetCurTaskID(INVALID_TASK_ID);
                    LOGGER.INFO($"Send get bill result successed. TaskID = {info.taskID}. \n {SendResult.ToLogString()}");
                }
                else
                {
                    // result = null; 无论是否发送给服务器成功,只要执行成功,就不允许清除
                    SetLastTaskID(INVALID_TASK_ID);
                    SetCurTaskID(INVALID_TASK_ID);
                    LOGGER.ERROR($"Send get bill result failed. TaskID = {info.taskID}. \n {SendResult.ToLogString()}", info.taskID);
                }
                LOGGER.WARN($"Get bill task deal over. TaskID = {info.taskID}.", info.taskID);
            }
            catch (Exception e)
            {
                LOGGER.ERROR($"HandleBillTask exception.msg: {e.Message}.");
            }
            finally
            {
                SetCurTaskID(INVALID_TASK_ID);
                m_BillTasksList.Dequeue();       // 无论如何,该任务必须删除
            }

            return;
        }
コード例 #4
0
        private bool QueryAutoBill(SBillTaskInfo info, ref SBillTaskResult result)
        {
            //return true;
            if (!s_bIsLogining)
            {
                // 未登录
                return(false);
            }
            result.taskID = info.taskID;
            try
            {
                // 实际测试过程中发现这个链接是随着账号改变,需要在首页中获取
                string postUrl = $"https://pbank.95559.com.cn/personbank/account/acTranRecordQuery.stream";
                if (string.IsNullOrEmpty(postUrl))
                {
                    result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_AutoProcessFailed;
                    result.msg    = "BCM Post url获取失败";
                    return(false);
                }
                // 构造post content
                var postContentString = GetAutoBillPostContent(info);
                if (string.IsNullOrEmpty(postContentString))
                {
                    result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_AutoProcessFailed;
                    result.msg    = "BCM Post content构造失败";
                    return(false);
                }
                // 构造post header
                var postHeader = GetAutoBillPostHeader();

                // POST获取文件
                string tmpFile = System.IO.Path.GetTempFileName();
                FKHttp.FKHttpClient.POST(postUrl, postContentString, postHeader, 300000, tmpFile);

                parseXlsContent(tmpFile, ref result, info);
            }
            catch (Exception e)
            {
                result.msg = $"QueryAutoBill抛出异常[{e.Message}]";
                return(false);
            }
            return(true);
        }
コード例 #5
0
        /// <summary>
        /// 解析流水页面
        /// </summary>
        /// <param name="html"></param>
        /// <param name="result"></param>
        /// <returns></returns>
        private bool ParseAutoBillHtmlPage(HtmlDocument html, ref SBillTaskResult result, SBillTaskInfo info)
        {
            try
            {
                var nodes = html.DocumentNode.SelectSingleNode("//body/form").SelectSingleNode("//table");
                var items = nodes.SelectNodes("//tr[@class='td_span']");
                // 当获取的数据为空时仍然有一个td_span 但是里面的数据为空
                if (items.Count == 1)
                {
                    if (items[0].GetAttributeValue("zcsr", "") == "|")
                    {
                        return(false);
                    }
                }
                foreach (var node in nodes.SelectNodes("//tr[@class='td_span']"))
                {
                    SBillTaskResult.SBankBillInfo billItem = new SBillTaskResult.SBankBillInfo();
                    // 解析单一流水对象
                    if (ParseOneBillHtmlPage(node, ref billItem) == false)
                    {
                        continue;
                    }
                    if (ResultFilter.TimeFilter(info, billItem.submitTime))
                    {
                        result.billsList.Add(billItem);
                    }
                }

                result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_Successed;
            }
            catch (Exception e)
            {
                result.msg    = "CCB解析返回html错误";
                result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_AutoProcessFailed;
                LOGGER.WARN($"CCB解析返回html错误:{e.Message}");
                return(false);
            }
            return(true);
        }
コード例 #6
0
        /// <summary>
        /// 自动查询核心函数
        /// </summary>
        /// <param name="nTaskID"></param>
        /// <param name="info"></param>
        /// <param name="result"></param>
        /// <returns></returns>
        public override bool AutoBill(int nTaskID, SBillTaskInfo info, ref SBillTaskResult result)
        {
            // 判断当前是否是同一个账号
            if (!IsSameAccount(info))
            {
                FKWebDriver.GetInstance.Close();
                ForceShutdownIE();
                s_bIsLogining = false;
            }
            // 先尝试进行登录
            string logPrefix = $"银行代码[ABC]获取明细,TaskID[{info.taskID}],";

            LOGGER.INFO($"{logPrefix}正在尝试登录 ...");

            s_bIsLogining = TryLogin(info, ref result);
            if (!s_bIsLogining)
            {
                LOGGER.INFO($"{logPrefix}登录失败,失败原因[{result.msg}]");
                FKWebDriver.GetInstance.Close();
                ForceShutdownIE();
                return(false);
            }

            LOGGER.INFO($"{logPrefix}登录成功,开始获取明细");
            // 查询
            bool ret = QueryAutoBill(info, ref result);

            if (!ret)
            {
                LOGGER.INFO($"{logPrefix}获取明细失败,失败原因[{result.msg}]");
            }
            else
            {
                LOGGER.INFO($"{logPrefix}获取明细成功");
            }
            return(ret);
        }
コード例 #7
0
        /// <summary>
        /// 查询流水
        /// </summary>
        /// <param name="info"></param>
        /// <param name="result"></param>
        /// <returns></returns>
        private bool QueryAutoBill(SBillTaskInfo info, ref SBillTaskResult result)
        {
            if (!s_bIsLogining)
            {
                // 未登录
                result.msg = "查流水前未登录";
                return(false);
            }
            result.taskID = info.taskID;
            try
            {
                // 实际测试过程中发现这个链接是随着账号改变,需要在首页中获取
                string postUrl = GetAutoBillPostUrl();
                //LOGGER.WARN($"===========================postUrl is {postUrl}");
                if (string.IsNullOrEmpty(postUrl))
                {
                    result.msg    = "获取流水url错误";
                    result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_AutoProcessFailed;
                    return(false);
                }

                for (int i = 1; true; i++)
                {
                    // 构造post header
                    var postHeader = GetAutoBillPostHeader();

                    // 构造post content
                    var postContentString = GetAutoBillPostContent(info, i);
                    //LOGGER.WARN($"============================postContentString is {postContentString}");
                    if (string.IsNullOrEmpty(postContentString))
                    {
                        result.msg    = "构造流水postContent错误";
                        result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_AutoProcessFailed;
                        return(false);
                    }

                    //string header = string.Join("\r\n", postHeader.Select(x => x.Key + ": " + x.Value).ToArray());
                    //LOGGER.INFO($"============================postHeader is {header}");


                    // 使用string的方式获取httpresponse
                    string postResult = FKHttp.FKHttpClient.POST(postUrl, postContentString, postHeader, 300000);
                    //LOGGER.INFO($"response is {postResult}");
                    // post response是一个Html页面
                    var doc = new HtmlDocument();
                    doc.LoadHtml(postResult);

                    /*
                     * string tmpFile = System.IO.Path.GetTempFileName();
                     * string postResult = FKHttp.FKHttpClient.POST(postUrl, postContentString, postHeader, 300000, tmpFile);
                     * //LOGGER.INFO($"response is {postResult}");
                     * // post response是一个Html页面
                     * var doc = new HtmlDocument();
                     * doc.Load(tmpFile,System.Text.Encoding.UTF8);
                     */
                    // 解析post response的Html页面
                    bool bRet = ParseAutoBillHtmlPage(doc, ref result, info);
                    LOGGER.INFO($"第{i}次获取流水之后条数{result.billsList.Count}");
                    if (bRet == false)
                    {
                        break;
                    }
                }
            }
            catch (Exception e)
            {
                result.msg = $"QueryAutoBill抛出异常{e.Message}";
                LOGGER.WARN($"Parse CCB bill html page failed. Error = {e.ToString()}");
                return(false);
            }
            return(true);
        }
コード例 #8
0
        /// <summary>
        /// 解析XLS文件
        /// </summary>
        /// <param name="filename"></param>
        /// <param name="result"></param>
        /// <returns></returns>
        private bool parseXlsContent(string filename, ref SBillTaskResult result, SBillTaskInfo info)
        {
            ExcelReader reader = ExcelReader.CreateReader(filename);

            try
            {
                List <object> recordList = new List <object>();
                int           i          = 0;
                while (reader.Read(1, ++i, ref recordList))
                {
                    // 跳过前三行(标题 本账号信息 列表头)
                    if (i <= 3)
                    {
                        recordList.Clear();
                        continue;
                    }

                    /*
                     * 交易日期	交易时间	交易金额	本次余额	对方户名	对方账号	        交易行	            交易渠道	交易类型	交易用途	交易摘要
                     * 20160828	102524	    +270.00	    284.91	    罗春波	    6228270921220010475	江西省分行9999行	网上银行	转账		            网银转账
                     */

                    SBillTaskResult.SBankBillInfo billItem = new SBillTaskResult.SBankBillInfo();
                    string date = (string)recordList.ElementAt(0);
                    string time = (string)recordList.ElementAt(1);
                    if (string.IsNullOrEmpty(time))
                    {
                        time = "000000";
                    }

                    string dateTime = $"{date}-{time}";
                    billItem.submitTime = GetTradeTime(dateTime);

                    // 时间不为空的需要过滤 为空总是返回 防止漏掉
                    if (!string.IsNullOrEmpty((string)recordList.ElementAt(1)))
                    {
                        if (!ResultFilter.TimeFilter(info, billItem.submitTime))
                        {
                            recordList.Clear();
                            continue;
                        }
                    }
                    //billItem.amount = Double.Parse($"{(string)recordList.ElementAt(2)}");
                    //billItem.balance = Double.Parse($"{(string)recordList.ElementAt(3)}");
                    billItem.amount            = ($"{(string)recordList.ElementAt(2)}");
                    billItem.balance           = ($"{(string)recordList.ElementAt(3)}");
                    billItem.accountName       = $"{(string)recordList.ElementAt(4)}";
                    billItem.accountNumber     = $"{(string)recordList.ElementAt(5)}";
                    billItem.accountBankName   = $"{(string)recordList.ElementAt(6)}";
                    billItem.tradeChannel      = $"{(string)recordList.ElementAt(7)}";
                    billItem.digest            = $"{(string)recordList.ElementAt(10)}";
                    billItem.tradeType         = TransformTradeTypeFromSummary($"{(string)recordList.ElementAt(10)}", $"{(string)recordList.ElementAt(2)}");
                    billItem.tradeUsage        = $"{(string)recordList.ElementAt(9)}";
                    billItem.additionalComment = $"{(string)recordList.ElementAt(10)}";
                    // 明细未提供
                    // billItem.currency = ?

                    result.billsList.Add(billItem);
                    recordList.Clear();
                }
            }
            catch (Exception e)
            {
                LOGGER.ERROR($"解析 XLS 文件失败, Error = {e.ToString()}");
                result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_AutoProcessFailed;
                result.msg    = "解析 XLS 文件失败.";
                return(false);
            }
            finally
            {
                reader.Close();
            }
            result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_Successed;
            result.msg    = "Successed";
            return(true);
        }
コード例 #9
0
        /// <summary>
        /// 尝试登录
        /// </summary>
        /// <param name="info"></param>
        /// <param name="result"></param>
        /// <returns></returns>
        private bool TryLogin(SBillTaskInfo info, ref SBillTaskResult result)
        {
            if (s_bIsLogining)
            {
                return(true);
            }

            bool isOCRPass = false;

            try
            {
                //FKWebDriver webDriver = FKWebDriver.GetInstance;
                string loginUrl = FKConfig.ABCLoginUrl;
                // 此部分代码根据现有网银官网的页面设计
                // 如果个人银行网页改版,此处可能需要根据新页面做相应调整
                FKWebAutomatic.FKWebDriver.GetInstance.OpenUrl(loginUrl);

                // 等待出现登录界面
                var element = FKWebAutomatic.FKWebDriver.GetInstance.WaitUntilVisibleByXPath("//*[@id=\"username\"]", 30000);
                if (element == null)
                {
                    result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_WaitElementTimeout;
                    result.msg    = "等待登录账号元素超时,可能页面未正常打开";
                    return(false);
                }

                // 填充登录账号
                FKWebAutomatic.FKWebDriver.GetInstance.SetTextByID("username", info.username);
                // 填充密码
                LoginPassword(info.password);
                // 填充验证码,由于验证码可能识别失败,所以需要重试
                int retryCount = 20;
                for (int i = 0; i < retryCount; i++)
                {
                    string ocr = GetVerificationCodeString();

                    // 如果识别个数都不对 没必要输入了 重刷验证码再识别
                    if (ocr.Length == 4)
                    {
                        FKWebAutomatic.FKWebDriver.GetInstance.SetTextByID("code", ocr);
                        //移走焦点
                        FKWebAutomatic.FKWebDriver.GetInstance.ClickByID("username");
                        // 填充完成后等待识别验证码打钩
                        Thread.Sleep(5000);
                        // 第一次此元素为隐藏,等待出现
                        FKWebAutomatic.FKWebDriver.GetInstance.WaitUntilVisibleByXPath("//*[@id=\"imgError\"]", 10000);
                        // 识别结果获取
                        string successString = FKWebAutomatic.FKWebDriver.GetInstance.GetAttributeByXPath("//*[@id=\"imgError\"]", "class");
                        if (successString == "v-code-error right")
                        {
                            // 点击登录
                            FKWebAutomatic.FKWebDriver.GetInstance.ClickByID("logo");
                            bool isInput = false;
                            // 用户名提示为空 重新输入
                            if (FKWebAutomatic.FKWebDriver.GetInstance.IsElementVisiableByXPath("//*[@id=\"username-error\"]"))
                            {
                                LOGGER.INFO("用户名为空,重新输入");
                                FKWebAutomatic.FKWebDriver.GetInstance.SetTextByID("username", info.username);
                                isInput = true;
                            }
                            // 密码提示为空 重新输入
                            if (FKWebAutomatic.FKWebDriver.GetInstance.IsElementVisiableByXPath("//*[@id=\"powerpass_ie_dyn_Msg\"]"))
                            {
                                LOGGER.INFO("密码为空或者不正确,重新输入");
                                LoginPassword(info.password, true);
                                isInput = true;
                            }

                            // 多次输入验证码失败后 银行重新清空用户名密码,重填
                            if (FKWebAutomatic.FKWebDriver.GetInstance.IsElementVisiableByXPath("/html/body/div[2]/div[5]/div/div[1]/div[5]/form/div[5]"))
                            {
                                FKWebAutomatic.FKWebDriver.GetInstance.SetTextByID("username", info.username);
                                LoginPassword(info.password, true);
                                isInput = true;
                            }
                            if (isInput)
                            {
                                // 输入后需要重新点击登录
                                FKWebAutomatic.FKWebDriver.GetInstance.ClickByID("logo");
                            }
                            isOCRPass = true;
                            break;
                        }
                        Console.WriteLine($"successString = {successString}");
                    }
                    // 失败 重新刷新验证码
                    FKWebAutomatic.FKWebDriver.GetInstance.ClickByID("vCode");
                    Thread.Sleep(1000);
                }

                if (!isOCRPass)
                {
                    result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_WaitElementTimeout;
                    result.msg    = "验证码超过重试次数";
                    return(false);
                }

                // 超时等待登陆成功
                element = FKWebAutomatic.FKWebDriver.GetInstance.WaitUntilVisibleByXPath("//*[@id=\"intro4-1\"]", 30000);
                if (element != null)
                {
                    LOGGER.INFO("成功获取登录element,登录成功");
                    return(true);
                }
                else
                {
                    result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_LoginFailed;
                    result.msg    = $"等待首页超时";
                    return(false);
                }
            }
            catch (Exception e)
            {
                result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_LoginFailed;
                result.msg    = $"TryLogin抛出异常[[{e.Message}]";
                return(false);
            }
        }
コード例 #10
0
        /// <summary>
        /// 查询流水(在已登录成功后)
        /// </summary>
        /// <param name="info"></param>
        /// <param name="result"></param>
        /// <returns></returns>
        private bool QueryAutoBill(SBillTaskInfo info, ref SBillTaskResult result)
        {
            /** 完整的获取明细curl命令,此命令最终返回的是一个标准xls的文件,需要进一步解析文件才能提取出明细
             * ----------------------------------------------------------------------------------
             * curl 'https://perbank.abchina.com/EbankSite/AccountTradeDetailDownloadAct.do'
             * -H 'Accept:	text/html, application/xhtml+xml, *\/*'
             * - H 'Referer: https://perbank.abchina.com/EbankSite/AccountTradeDetailQueryInitAct.do'
             * - H 'Accept-Language: zh-CN'
             * - H 'User-Agent:	Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko'
             * - H 'Content-Type: application/x-www-form-urlencoded'
             * - H 'Accept-Encoding: gzip, deflate'
             * - H 'Host: perbank.abchina.com'
             * - H 'Content-Length: 136'
             * - H 'Connection: Keep-Alive'
             * - H 'Cookie:	WT_FPC=id=10.235.177.249-2296909152.30606638:lv=1500978056097:ss=1500977553848; ASP.NET_SessionId=elwlscn2t0puisyczziuwwdt; _ABCPerbankLogonCookie__=; BIGipServerpool_perbank_EbankSite=!Q5CBtVY5fUNWSa38cCqlIAZb8CxfUQboxPynXFLAUdu31cHrqqE7Bl6NuLXg8tH9gLUKWOZc2cVc9J8='
             * --data 'acctId=6228482568556511677&acctOpenBankId=34905&acctType=401&provCode=12&acctCurCode=156&oofeFlg=0&trnStartDt=20160804&trnEndDt=20170727'
             *
             * ----------------------------------------------------------------------------------
             * --data参数解释
             * acctId           卡号 从传入参数中获取
             * acctOpenBankId   开户行 需要从页面提取
             * acctType         不懂 但是应该是账户相关 需要从页面提取
             * provCode         省份code 页面提取
             * acctCurCode      不懂 页面提取
             * oofeFlg          不懂 传0
             * trnStartDt       开始日期
             * trnEndDt         结束日期
             * **/
            if (!s_bIsLogining)
            {
                // 未登录
                return(false);
            }
            result.taskID = info.taskID;
            try
            {
                // 实际测试过程中发现这个链接是随着账号改变,需要在首页中获取
                string postUrl = FKConfig.ABCBillUrl;
                if (string.IsNullOrEmpty(postUrl))
                {
                    result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_AutoProcessFailed;
                    result.msg    = "ABC Post url获取失败";
                    return(false);
                }
                // 构造post content
                var postContentString = GetAutoBillPostContent(info);
                if (string.IsNullOrEmpty(postContentString))
                {
                    result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_AutoProcessFailed;
                    result.msg    = "ABC Post content构造失败";
                    return(false);
                }
                // 构造post header
                var postHeader = GetAutoBillPostHeader();

                // POST获取文件
                string tmpFile    = System.IO.Path.GetTempFileName();
                string postResult = (string)FKHttp.FKHttpClient.POST(postUrl, postContentString, postHeader, 300000, tmpFile);

                if (File.Exists(tmpFile))
                {
                    bool bRet       = parseXlsContent(tmpFile, ref result, info);
                    int  nBillCount = 0;
                    if (result.billsList != null)
                    {
                        nBillCount = result.billsList.Count;
                    }
                    LOGGER.INFO($"XLS Tmp file = {tmpFile} InfoLen = {nBillCount}");
                    //delFile(tmpFile); // TODO: 前期测试不要删除,文件不太大的话,不会引发过多问题,之后版本删除
                    return(bRet);
                }
                else
                {
                    result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_AutoProcessFailed;
                    LOGGER.INFO($"Can't find XLS Tmp file = {tmpFile}");
                    return(false);
                }
            }
            catch (Exception e)
            {
                result.msg = $"QueryAutoBill抛出异常[{e.Message}]";
                return(false);
            }
        }
コード例 #11
0
 public void testXls()
 {
     SBillTaskResult result = new SBillTaskResult();
     SBillTaskInfo   info   = new SBillTaskInfo();
 }
コード例 #12
0
        private bool TryLogin(SBillTaskInfo info, ref SBillTaskResult result)
        {
            if (s_bIsLogining == false)
            {
                try
                {
                    //FKWebDriver webDriver = FKWebDriver.GetInstance;
                    string loginUrl = FKConfig.BCMLoginUrl;
                    // 此部分代码根据现有交行的页面设计
                    // 如果交行个人银行网页改版,此处可能需要根据新页面做相应调整

                    FKWebAutomatic.FKWebDriver.GetInstance.OpenUrl(loginUrl);

                    // 等待出现登录界面
                    var element = FKWebAutomatic.FKWebDriver.GetInstance.WaitUntilVisibleByXPath("/html/body/div[2]/div/div/div[2]/input", 10000);
                    if (element == null)
                    {
                        result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_WaitElementTimeout;
                        result.msg    = $"等待登录页面超时";
                        return(false);
                    }

                    // 填充登录账号
                    FKWebAutomatic.FKWebDriver.GetInstance.SetTextByID("alias", info.username);

                    // 填充密码
                    LoginPassword(info.password);
                    // FKWebAutomatic.FKWebDriver.GetInstance.SetTextByID("password", info.password);

                    if (FKWebAutomatic.FKWebDriver.GetInstance.IsElementVisiableByID("input_captcha"))
                    {
                        int retryCount = 20;
                        for (int i = 0; i < retryCount; i++)
                        {
                            string ocr = GetVerificationCodeString();

                            // 如果识别个数都不对 没必要输入了 重刷验证码再识别
                            if (ocr.Length == 5)
                            {
                                FKWebAutomatic.FKWebDriver.GetInstance.SetTextByID("input_captcha", ocr);
                                //移走焦点
                                FKWebAutomatic.FKWebDriver.GetInstance.ClickByID("alias");
                                // 填充完成后等待识别验证码打钩
                                Thread.Sleep(5000);
                                // 第一次此元素为隐藏,等待出现
                                FKWebAutomatic.FKWebDriver.GetInstance.WaitUntilVisibleByXPath("//*[@id=\"captchaFlg\"]", 10000);
                                // 识别结果获取
                                string successString = FKWebAutomatic.FKWebDriver.GetInstance.GetAttributeByXPath("//*[@id=\"captchaFlg\"]", "class");
                                if (successString == "right-cpt")
                                {
                                    break;
                                }
                                Console.WriteLine($"successString = {successString}");
                            }
                            // 失败 重新刷新验证码
                            FKWebAutomatic.FKWebDriver.GetInstance.ClickByXPath("//*[@class=\"captchas-img-bg\"]");
                            Thread.Sleep(1000);
                        }
                    }

                    // 点击登录
                    FKWebAutomatic.FKWebDriver.GetInstance.ClickByID("loginBtn");
                    element = FKWebAutomatic.FKWebDriver.GetInstance.WaitUntilVisibleByXPath("//*[@id=\"prepareForm\"]", 6000);
                    if (element != null)
                    {
                        var url = FKWebAutomatic.FKWebDriver.GetInstance.GetAttributeByXPath("//*[@id=\"prepareForm\"]", "action");
                        LOGGER.INFO($"当前url:{url}");
                        if (url.Contains("syVerifyCustomerNewControl.do") == true)
                        {
                            LOGGER.INFO($"U盾未绑定:{url}");
                            result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_WaitElementTimeout;
                            result.msg    = $"U盾未绑定";
                            return(false);
                        }
                    }

                    // 超时
                    element = FKWebAutomatic.FKWebDriver.GetInstance.WaitUntilVisibleByXPath("//*[@id=\"frameMain\"]", 60000);
                    if (element == null)
                    {
                        result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_WaitElementTimeout;
                        result.msg    = $"等待主页超时";
                        return(false);
                    }
                    LOGGER.INFO("登录成功");

                    Thread.Sleep(1000);
                    if (FKWebAutomatic.FKWebDriver.GetInstance.SwitchToFrameByID("frameMain") == false)
                    {
                        LOGGER.INFO("切换iframe到frameMain失败");
                        result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_WaitElementTimeout;
                        result.msg    = $"切换iframe失败";
                        return(false);
                    }
                    string PSessionId = FKWebAutomatic.FKWebDriver.GetInstance.GetAttributeByXPath("//*[@name=\"PSessionId\"]", "value");
                    LOGGER.INFO($"切换iframe到frameMain成功,PSessionId is {PSessionId}");
                    //string ReqSafeFields = FKWebAutomatic.FKWebDriver.GetInstance.GetAttributeByXPath("//*[@name=\"ReqSafeFields\"]", "value");
                    //LOGGER.INFO($"切换iframe到frameMain成功,ReqSafeFields is {ReqSafeFields}");
                    s_bIsLogining = true;
                }
                catch (Exception e)
                {
                    result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_LoginFailed;
                    result.msg    = $"TryLogin error [{e.Message}]";
                    return(false);
                }

                return(true);
            }
            return(s_bIsLogining);
        }
コード例 #13
0
 /// <summary>
 /// 银行执行自动查流水任务入口函数
 /// </summary>
 /// <param name="nTaskID">任务ID</param>
 /// <param name="info">信息详细情况:例如登录密码,收款时间限制等</param>
 /// <param name="result">过程中捕获的详细信息:例如流水情况等</param>
 /// <returns></returns>
 public abstract bool AutoBill(int nTaskID, SBillTaskInfo info, ref SBillTaskResult result);
コード例 #14
0
        /// <summary>
        /// 实际自动处理一次流水查询
        /// </summary>
        /// <param name="info"></param>
        /// <param name="result"></param>
        /// <returns></returns>
        private bool AutomationBill(SBillTaskInfo info, ref SBillTaskResult result)
        {
            // 检查是否支持该银行
            int nBankTypeID = GetBillBankTypeIDByName(info.bankCode);

            if (nBankTypeID <= 0)
            {
                LOGGER.ERROR($"Auto bill failed: Unknown bank code - {info.bankCode}");
                result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_UnsupportBankCode;
                return(false);
            }
            // 检查重要参数是否合法
            if (string.IsNullOrEmpty(info.accountNumber) ||
                string.IsNullOrEmpty(info.username) ||
                string.IsNullOrEmpty(info.password))
            {
                result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_ArgumentInvalid;
                LOGGER.ERROR($"Auto bill failed: account info invalid");
                return(false);
            }
            // 先进行清理
            // 为保持长期登录状态,现不进行清理 - added by Frankie.W 2017-07-19
            //{
            //    FKWebAutomatic.FKWebDriver.GetInstance.FKClose();
            //    ForceShutdownIE();
            //    Thread.Sleep(1000);
            //}

            DateTime startTime = DateTime.Now;

            bool             bSuccessed = false;
            BankAutoBillBase imp        = null;

            try
            {
                switch (nBankTypeID)
                {
                case 1:
                    imp = new CCB_AutoBill();
                    break;

                case 2:
                    imp = new BCM_AutoBill();
                    break;

                case 3:
                    imp = new CMB_AutoBill();
                    break;

                case 4:
                    imp = new ABC_AutoBill();
                    break;

                case 5:
                    imp = new CITIC_AutoBill();
                    break;

                default:
                    break;
                }

                if (imp == null)
                {
                    LOGGER.ERROR($"Auto bill failed: imp not found");
                    result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_UnknownError;
                    bSuccessed    = false;
                }
                else
                {
                    LOGGER.INFO($"Auto bill start: id = {info.taskID}");
                    imp.Init();
                    bSuccessed = imp.AutoBill(info.taskID, info, ref result);
                    imp.Clear();
                    LOGGER.INFO($"Auto bill finish: id = {info.taskID}");
                }
            }
            catch (Exception e)
            {
                LOGGER.ERROR($"Auto bill error occured. Error = {e.ToString()}");
                result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_UnknownError;
                bSuccessed    = false;
            }
            DateTime endTime = DateTime.Now;
            TimeSpan span    = endTime - startTime;

            if (!bSuccessed)
            {
                //LOGGER.ERROR($"Auto bill failed: imp.AutoBill() return false");
                // 执行失败
                result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_AutoProcessFailed;
            }

            // 无论成功与否,都要进行清理
            // 为保持长期登录状态,现不进行清理 - added by Frankie.W 2017-07-19
            //{
            //    FKWebAutomatic.FKWebDriver.GetInstance.FKClose();
            //    ForceShutdownIE();
            //}

            // 并记录到日志时间数据库,以便日志查询
            FKLog.FKSQLiteLogMgr.GetInstance.AddTaskTimeLog(info.taskID, DateTime.Now);

            return(bSuccessed);
        }
コード例 #15
0
        private bool ParseAutoBillRegex(string content, ref SBillTaskResult result, SBillTaskInfo info)
        {
            Regex reg = new Regex($"\\{{stdessvldt=(?<date>.*?), " +
                                  $"stdes2bref=(?<sumary>.*?), " +
                                  $"stdes1opna=(?<stdes1opna>.*?), " +
                                  $"stdsumtrsq=(?<serialnumber>.*?), " +
                                  $"equipmentNO=(?<ignore2>.*?), " +
                                  $"stdessrvfg=(?<stdessrvfg>.*?), " +
                                  $"std400desc=(?<std400desc>.*?), " +
                                  $"stdesstrno=(?<stdesstrno>.*?), " +
                                  $"stdes2opid=(?<stdes2opid>.*?), " +
                                  $"stdessdcfg=(?<stdessdcfg>.*?), " +
                                  $"stdes2bfcd=(?<stdes2bfcd>.*?), " +
                                  $"stdessctfg=(?<stdessctfg>.*?), " +
                                  $"stdes2opna=(?<stdes2opna>.*?), " +
                                  $"stdesstrdt=(?<stdesstrdt>.*?), " +
                                  $"stdoppacna=(?<username>.*?), " +
                                  $"stdesstram=(?<amount>.*?), " +
                                  $"stdessfnfg=(?<stdessfnfg>.*?), " +
                                  $"stdes1bfcd=(?<stdes1bfcd>.*?), " +
                                  $"stdessacbl=(?<balance>.*?), " +
                                  $"stdesstrtm=(?<time>.*?), " +
                                  $"stdes1opid=(?<stdes1opid>.*?), " +
                                  $"stdesstrcd=(?<stdesstrcd>.*?), " +
                                  $"fndoppacno=(?<cardnumber>.*?), " +
                                  $"stdoppbrna=(?<bankname>.*?)" +
                                  $"\\}}" +
                                  $"");


            var matches = reg.Matches(content);

            if (matches.Count == 0)
            {
                LOGGER.INFO("未找到有效流水数据,可能已经查到最后一页");
                return(false);
            }

            foreach (Match one in matches)
            {
                SBillTaskResult.SBankBillInfo billItem = new SBillTaskResult.SBankBillInfo();
                // 解析单一流水对象
                billItem.submitTime = GetRegexTradeTime($"{one.Groups["date"].Value}-{one.Groups["time"].Value}");
                billItem.serialNo   = one.Groups["serialnumber"].Value;
                if (billItem.serialNo == "null")
                {
                    billItem.serialNo = "";
                }
                billItem.accountBankName = one.Groups["bankname"].Value;
                if (billItem.accountBankName == "null")
                {
                    billItem.accountBankName = "";
                }
                billItem.accountName = one.Groups["username"].Value;
                if (billItem.accountName == "null")
                {
                    billItem.accountName = "";
                }
                billItem.additionalComment = one.Groups["sumary"].Value;
                if (billItem.additionalComment == "null")
                {
                    billItem.additionalComment = "";
                }
                billItem.balance = one.Groups["balance"].Value;
                if (billItem.balance == "null")
                {
                    billItem.balance = "";
                }
                billItem.amount = one.Groups["amount"].Value;
                if (billItem.amount == "null")
                {
                    billItem.amount = "0.0";
                }
                billItem.accountNumber = one.Groups["cardnumber"].Value;

                var inOrOut = one.Groups["stdessdcfg"].Value;

                if (inOrOut == "C")
                {
                    billItem.amount = "+" + billItem.amount;
                }
                else if (inOrOut == "D")
                {
                    billItem.amount = "-" + billItem.amount;
                }
                else
                {
                    LOGGER.ERROR($"未知存取类型[{inOrOut}]");
                    continue;
                }
                billItem.tradeType = TransformTradeTypeFromSummary(one.Groups["stdes2bfcd"].Value, inOrOut);
                if (ResultFilter.TimeFilter(info, billItem.submitTime))
                {
                    result.billsList.Add(billItem);
                }
            }
            return(true);
        }
コード例 #16
0
        /// <summary>
        /// 尝试进行登录
        /// </summary>
        /// <param name="info"></param>
        /// <param name="result"></param>
        /// <returns></returns>
        private bool TryLogin(SBillTaskInfo info, ref SBillTaskResult result)
        {
            // 已经处於登录状态
            if (s_bIsLogining)
            {
                return(true);
            }

            try
            {
                string loginUrl = FKConfig.CITICLoginUrl;
                // 此部分代码根据现有CITIC的页面设计
                // 如果CITIC个人银行网页改版,此处可能需要根据新页面做相应调整
                FKWebDriver.GetInstance.OpenUrl(loginUrl);

                // 等待出现登录界面
                var element = FKWebDriver.GetInstance.WaitUntilVisibleByXPath("/html/body/form[1]/div[2]/div[3]/div[1]/ul/li[4]", 20000);
                if (element == null)
                {
                    result.msg    = "等待登录页超时";
                    result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_WaitElementTimeout;
                    return(false);
                }


                if (FKWebDriver.GetInstance.IsElementVisiableByXPath("//*[@id=\"type2\"]"))
                {
                    LOGGER.INFO($"检测到U盾,跳过用户名输入");
                }
                else
                {
                    // 填充登录账号
                    FKWebDriver.GetInstance.SetTextByName("logonNoCert", info.accountNumber);
                }


                // 填充密码
                LoginPassword(info.password);

                var isOcrEnable = FKWebDriver.GetInstance.IsElementVisiableByXPath("//*[@class=\"loginInputVerity\"]");

                Console.WriteLine($"isOcrEnable {isOcrEnable}");
                var isOcrPass = false;
                // 处理验证码
                if (isOcrEnable)
                {
                    // 填充验证码
                    // 由于验证码可能识别失败,所以需要重试
                    int retryCount = 20;
                    for (int i = 0; i < retryCount; i++)
                    {
                        // 获取ocr
                        string ocr = getOCR();
                        // 如果识别个数都不对 没必要输入了 重刷验证码再识别
                        if (ocr.Length == 4)
                        {
                            FKWebAutomatic.FKWebDriver.GetInstance.SetTextByName("verifyCode", ocr.Replace("*", ""));
                            // 填充完成后等待识别验证码打钩
                            Thread.Sleep(1000);
                            EnterOCRErrorDialog();
                            // 识别结果获取
                            string rightSrc = FKWebAutomatic.FKWebDriver.GetInstance.GetAttributeByXPath("//*[@class=\"imgVeritySign\"]", "src");
                            // 判断验证码是否通过
                            if (rightSrc.Contains("images/default/start_button.gif"))
                            {
                                isOcrPass = true;
                                break;
                            }
                            Console.WriteLine($"src is [{rightSrc}]");
                        }

                        // 失败 重新刷新验证码
                        FKWebDriver.GetInstance.ClickByID("pinImg");
                        Thread.Sleep(1000);
                    }
                    if (!isOcrPass)
                    {
                        result.msg    = "验证码超过重试次数";
                        result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_WaitElementTimeout;
                        return(false);
                    }
                }

                bool logButton = FKWebDriver.GetInstance.DoubleClickByID("logonButton");
                // 点击登录
                Console.WriteLine($"log button {logButton}");

                // 中信银行最近改版,未通过手机绑定的用户会跳转到手机绑定页面 这里处理此页面直接跳过
                element = FKWebDriver.GetInstance.WaitUntilVisibleByXPath("//*[@class=\"tradingCon\"]", 30000);
                if (element == null)
                {
                    LOGGER.INFO($"未检测出验证页面");
                }
                else
                {
                    var a = element.FindElement(OpenQA.Selenium.By.TagName("a"));

                    if (a != null && a.Text == "跳过")
                    {
                        LOGGER.INFO($"检测出手机验证页面,点击跳过");
                        a.Click();
                        Thread.Sleep(2000);
                        FKWebDriver.GetInstance.ClickByID("jump");
                    }
                }

                // 超时
                element = FKWebDriver.GetInstance.WaitUntilVisibleByXPath("//*[@class=\"index_page\"]", 30000);
                if (element == null)
                {
                    result.msg    = "等待主页超时";
                    result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_WaitElementTimeout;
                    return(false);
                }

                // 到了这里,将认为是成功了
                return(true);
            }
            catch (Exception e)
            {
                result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_LoginFailed;
                result.msg    = $"TryLogin抛出异常[{e.Message}]";
                return(false);
            }
        }
コード例 #17
0
        /// <summary>
        /// 查询流水
        /// </summary>
        /// <param name="info"></param>
        /// <param name="result"></param>
        /// <returns></returns>
        private bool QueryAutoBill(SBillTaskInfo info, ref SBillTaskResult result)
        {
            if (!s_bIsLogining)
            {
                // 未登录
                return(false);
            }
            result.taskID = info.taskID;
            try
            {
                for (int i = 1; true; i++)
                {
                    string postUrl = $"{FKConfig.CITICBillUrl}?EMP_SID={getEMPSID()}";
                    if (string.IsNullOrEmpty(postUrl))
                    {
                        result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_AutoProcessFailed;
                        return(false);
                    }
                    // 构造post content
                    var postContentString = GetAutoBillPostContent(info, i);
                    if (string.IsNullOrEmpty(postContentString))
                    {
                        result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_AutoProcessFailed;
                        return(false);
                    }
                    // 构造post header
                    var    postHeader       = GetAutoBillPostHeader();
                    string postHeaderString = string.Join(";", postHeader.Select(x => x.Key + "=" + x.Value).ToArray());
                    string tmpFile          = System.IO.Path.GetTempFileName();
                    // 获取post response
                    string postResult = (string)FKHttp.FKHttpClient.POST(postUrl, postContentString, postHeader, 300000, tmpFile);
                    Console.WriteLine(postResult);
                    var doc = new HtmlDocument();
                    doc.Load(tmpFile);
                    var titleNode = doc.DocumentNode.SelectSingleNode("//title");
                    if (titleNode != null && titleNode.InnerHtml.Trim().Contains($"超时"))
                    {
                        result.msg = "刷新功能正常,获取链接出现主页超时";
                        LOGGER.WARN(result.msg);
                        s_bIsLogining = false;
                        result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_AutoProcessFailed;
                        return(false);
                    }
                    //bool bRet = ParseAutoBillHtmlPage(doc, ref result, info);

                    var  content    = File.ReadAllLines(tmpFile, System.Text.Encoding.GetEncoding("gb2312"));
                    var  allContent = String.Join(" ", content);
                    bool bRet       = ParseAutoBillRegex(allContent, ref result, info);
                    LOGGER.INFO($"第{i}次获取流水之后条数{result.billsList.Count}");
                    if (bRet == false)
                    {
                        break;
                    }
                }
            }
            catch (Exception e)
            {
                result.msg    = $"QueryAutoBill抛出异常{e.Message}";
                result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_AutoProcessFailed;
                LOGGER.WARN($"Parse CCB bill html page failed. Error = {e.ToString()}");
                return(false);
            }

            if (result.billsList.Count == 0)
            {
                result.msg = $"未获取到流水数据";
                LOGGER.WARN(result.msg);
                result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_AutoProcessFailed;
                return(false);
            }
            result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_Successed;
            return(true);
        }
コード例 #18
0
 public override bool AutoBill(int nTaskID, SBillTaskInfo info, ref SBillTaskResult result)
 {
     throw new NotImplementedException();
 }
コード例 #19
0
        /// <summary>
        /// 尝试进行登录
        /// </summary>
        /// <param name="info"></param>
        /// <param name="result"></param>
        /// <returns></returns>
        private bool TryLogin(SBillTaskInfo info, ref SBillTaskResult result)
        {
            // 已经处於登录状态
            if (s_bIsLogining)
            {
                return(true);
            }

            try
            {
                string loginUrl = FKConfig.CCBLoginUrl;
                // 此部分代码根据现有建行的页面设计
                // 如果建行个人银行网页改版,此处可能需要根据新页面做相应调整
                FKWebDriver.GetInstance.OpenUrl(loginUrl);

                // 等待出现登录界面
                var element = FKWebDriver.GetInstance.WaitUntilVisibleByXPath("//*[@id=\"fclogin\"]", 30000);
                if (element == null)
                {
                    result.msg    = "等待登录页超时";
                    result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_WaitElementTimeout;
                    return(false);
                }

                // CCB的登录页面是iframe内嵌html,需要首先switch
                FKWebDriver.GetInstance.SwitchToFrameByID("fclogin");

                // 填充登录账号
                FKWebDriver.GetInstance.SetTextByID("USERID", info.username);

                // 填充密码
                FKWebDriver.GetInstance.SetTextByID("LOGPASS", info.password);

                // 点击登录
                FKWebDriver.GetInstance.ClickByID("loginButton");

                // 超时
                element = FKWebDriver.GetInstance.WaitUntilVisibleByXPath("//*[@id=\"pnav_V6010000\"]", 30000);
                if (element == null)
                {
                    result.msg    = "等待主页超时";
                    result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_WaitElementTimeout;
                    return(false);
                }
                if (!FKWebDriver.GetInstance.ClickByID("pnav_V6020000"))
                {
                    result.msg    = "点击首页出错";
                    result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_LoginFailed;
                    return(false);
                }

                // 到了这里,将认为是成功了
                return(true);
            }
            catch (Exception e)
            {
                result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_LoginFailed;
                result.msg    = $"TryLogin抛出异常[{e.Message}]";
                return(false);
            }
        }