Beispiel #1
0
        private void ExportCD()
        {
            var cellphones = File.ReadAllLines(@"D:\给过的手机号-副本.txt");

            using (var db = new MangningXssDBEntities())
            {
                var beginDataTime = DateTime.Today.AddDays(-4);

                var endDataTime = DateTime.Today.AddDays(1);

                var dataList = db.DodiBusiness
                               .Join(db.DodiUserInfomation, a => a.Id, b => b.BusinessId, (B, A) => new { B.Id, A.UserName, A.GraduatedSchool, B.BranchOffice, A.Email, A.Cellphone, B.CreateTime, B.Sources, A.JobName, B.PromoteBrand, A.ProfessionalTitle })
                               .Where(w => /*!w.BranchOffice.StartsWith("北京") && !w.BranchOffice.StartsWith("上海") && !w.BranchOffice.StartsWith("广州") && */ w.BranchOffice.StartsWith("成都") && w.CreateTime > beginDataTime && w.CreateTime < endDataTime)
                               .Select(s => new { s.Id, s.UserName, s.Cellphone, s.Email, s.Sources, s.CreateTime, s.JobName, s.ProfessionalTitle })
                               .ToList();

                const string cookie = "PHPSESSID=j0lklef94l9akqabg41n3nqd93; Example_auth=f9d7XYivszgUGkEXygbytRrg8EzZWngyS25FZaKx1OSub%2FhBVliH; Hm_lvt_1360b6fe7fa346ff51189adc58afb874=1507336367,1507510768,1507596684,1507682510; Hm_lpvt_1360b6fe7fa346ff51189adc58afb874=1507705480";

                var cookieContainer = cookie.Serialize("crm.dodi.cn");

                HttpClientFactory.RequestForString("http://crm.dodi.cn/index.php/Notice/index", HttpMethod.Get, null, cookieContainer);

                var sb = new StringBuilder();

                sb.AppendLine("姓名\t手机\t邮箱\t年龄\t学历\t更新日期\t性别\t平台\t地点\t职位\t专业");

                var index = 0;

                foreach (var item in dataList)
                {
                    var response = HttpClientFactory.RequestForString($"http://crm.dodi.cn/index.php/Main/khxxy/business_id/{item.Id}/source/false_note", HttpMethod.Get, null, cookieContainer);

                    if (!response.IsSuccess)
                    {
                        RunInMainthread(() =>
                        {
                            Program.SetLog(this.tbx_Log, $"ID:{item.Id} 请求失败!{response.ErrorMsg}");
                        });

                        LogFactory.Warn($"ID:{item.Id} 请求失败!{response.ErrorMsg}");

                        continue;
                    }

                    if (!response.Data.Contains("商 机 ID:"))
                    {
                        RunInMainthread(() =>
                        {
                            Program.SetLog(this.tbx_Log, $"ID:{item.Id} 商机为空!{response.ErrorMsg}");
                        });

                        LogFactory.Warn($"ID:{item.Id} 商机为空!{response.ErrorMsg}");

                        continue;
                    }

                    var match = Regex.Match(response.Data, @"resume_email\('(.*?)','(\d+)','(\d+)','(\d+)',(\d+)\)");

                    if (!match.Success)
                    {
                        RunInMainthread(() =>
                        {
                            Program.SetLog(this.tbx_Log, $"ID:{item.Id} 匹配详情失败!");
                        });

                        LogFactory.Warn($"ID:{item.Id} 匹配详情失败!");

                        continue;
                    }

                    var email     = HttpUtility.UrlEncode(match.Result("$1"));
                    var phone     = HttpUtility.UrlEncode(match.Result("$2"));
                    var email_id  = HttpUtility.UrlEncode(match.Result("$3"));
                    var now_month = HttpUtility.UrlEncode(match.Result("$4"));
                    var school_id = HttpUtility.UrlEncode(match.Result("$5"));

                    if (cellphones.Contains(phone))
                    {
                        continue;
                    }

                    response = HttpClientFactory.RequestForString($"http://crm.dodi.cn/index.php/Main/email_body?email={email}&phone={phone}&email_id={email_id}&now_month={now_month}&school_id={school_id}", HttpMethod.Get, null, cookieContainer);

                    if (!response.IsSuccess)
                    {
                        RunInMainthread(() =>
                        {
                            Program.SetLog(this.tbx_Log, $"ID:{item.Id} 详情请求失败!{response.ErrorMsg}");
                        });

                        LogFactory.Warn($"ID:{item.Id} 详情请求失败!{response.ErrorMsg}");

                        continue;
                    }

                    //File.WriteAllText($@"D:\Business\{item.Id}.txt", response.Data);

                    var data = Regex.Unescape(response.Data);

                    var xbMatch = Regex.Match(data, "(男|女)");

                    if (xbMatch.Value.Trim() == "女")
                    {
                        continue;
                    }

                    var ageMatch = Regex.Match(data, "((?<=[^0-9])[0-9]{2}岁|年龄\\s*[0-9]{2}(?=[^0-9]))");

                    if (!ageMatch.Success)
                    {
                        ageMatch = Regex.Match(data, "(19|20)[0-9]{2}(年|-)[0-9]{1,2}(月|)(?=[^0-9])");
                    }

                    //var xlMatch = Regex.Match(data, "(高中|初中|小学|大专|中专)");

                    var xlMatch = Regex.Match(data, "(大专|本科|硕士|博士|MBA)");

                    //var date = item.CreateTime < DateTime.Today.AddDays(-3) ? item.CreateTime?.AddDays(2) : item.CreateTime;

                    sb.AppendLine($"{item.UserName}\t{item.Cellphone}\t{item.Email}\t{ageMatch.Value}\t{xlMatch.Value}\t{item.CreateTime?.ToString("yyyy-MM-dd")}\t{xbMatch.Value}\t{item.Sources.Substring(item.Sources.LastIndexOf("_", StringComparison.Ordinal) + 1)}\t成都\t{item.JobName}\t{item.ProfessionalTitle}");

                    //sb.AppendLine($"{item.Cellphone}");

                    //if (index % 1000 == 0)
                    //{
                    //    File.WriteAllText(@"D:\非北上广.txt", sb.ToString());
                    //}

                    RunInMainthread(() =>
                    {
                        Program.SetLog(this.tbx_Log, $"{Interlocked.Increment(ref index)}/{dataList.Count}");
                    });
                }
                ;

                File.WriteAllText(@"D:\成都大专以上.txt", sb.ToString());
            }
        }
        private void OldSystemLoginForm_Load(object sender, EventArgs e)
        {
            FiddlerApplication.BeforeRequest += oSessions =>
            {
                //if (oSessions.url.Contains("zhaopin")) oSessions["X-OverrideGateway"] = $"{webProxyIp}:{webProxyPort}";

                oSessions.bBufferResponse = true;

                if (oSessions.url.Contains("captcha.js"))
                {
                    if (oSessions.RequestHeaders.Exists("If-Modified-Since"))
                    {
                        oSessions.RequestHeaders.Remove("If-Modified-Since");
                    }

                    if (oSessions.RequestHeaders.Exists("If-None-Match"))
                    {
                        oSessions.RequestHeaders.Remove("If-None-Match");
                    }

                    if (oSessions.RequestHeaders.Exists("Accept-Encoding"))
                    {
                        oSessions.RequestHeaders.Remove("Accept-Encoding");
                    }
                }

                if (oSessions.RequestHeaders.Exists("User-Agent"))
                {
                    oSessions.RequestHeaders["User-Agent"] = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36";
                }
            };

            FiddlerApplication.BeforeResponse += oSessions =>
            {
                if (oSessions.url.Contains("captcha.js"))
                {
                    oSessions.ResponseHeaders["Cache-Control"] = "no-store";

                    var jsContent = oSessions.GetResponseBodyEncoding().GetString(oSessions.ResponseBody);

                    jsContent = "var hackStr = '';" + jsContent;

                    jsContent = jsContent.Replace("pData.join(\";\")", "hackStr");

                    jsContent = jsContent.Remove(jsContent.Length - 4);

                    jsContent += "this.hack = function (coordinate){ $(\"#captcha-submitCode\").removeClass(\"btn-disabled\");validate = true;hackStr = coordinate; $(\"#captcha-submitCode\").trigger(\"click\"); return true;}";

                    jsContent += "}\r\n";

                    jsContent += "function execHack(coordinate){this.captcha.hack(coordinate); return 1;}";

                    oSessions.ResponseBody = oSessions.GetResponseBodyEncoding().GetBytes(jsContent);
                }
            };

            if (!FiddlerApplication.IsStarted())
            {
                FiddlerApplication.Startup(8887, FiddlerCoreStartupFlags.Default);
            }

            List <ZhaopinCleaningProcedure> accounts;

            using (var db = new MangningXssDBEntities())
            {
                accounts = db.ZhaopinCleaningProcedure.Where(w => w.IsEnable && (string.IsNullOrEmpty(w.Cookie) || w.StartTime < DateTime.Today)).ToList();
            }

            this.AsyncSetLog(this.tbx_Log, $"共 {accounts.Count} 个号准备登录!");

            this.webBrowser.DocumentCompleted += webBrowser_DocumentCompleted;

            this.webBrowser.ScriptErrorsSuppressed = true;

            this.RunAsync(() =>
            {
                foreach (var item in accounts)
                {
                    account = item.Account;

                    password = item.Password;

                    webBrowser.Navigate("https://passport.zhaopin.com/org/login");

                    while (true)
                    {
                        if (!isWaitLogin)
                        {
                            Thread.Sleep(1000);

                            continue;
                        }

                        var index = 0;

                        object obj;

                        var isChecked = false;

                        while (!isChecked)
                        {
                            this.Invoke((MethodInvoker) delegate
                            {
                                index++;

                                if (this.webBrowser.Document?.GetElementById("CheckCodeCapt")?.GetAttribute("value") == "验证通过")
                                {
                                    Thread.Sleep(3000);

                                    this.webBrowser.Document?.GetElementById("loginbutton")?.InvokeMember("click");

                                    isChecked = true;

                                    return;
                                }

                                if (index % 2 != 0)
                                {
                                    obj = this.webBrowser.Document?.InvokeScript("execHack", new object[] { "66,76;173,44;239,80" });
                                }
                                else
                                {
                                    obj = this.webBrowser.Document?.InvokeScript("execHack", new object[] { "44,44;190,37;122,48" });
                                }

                                if (obj == null)
                                {
                                    this.AsyncSetLog(this.tbx_Log, "调用验证 JS 异常");
                                }
                            });

                            Thread.Sleep(500);
                        }

                        while (true)
                        {
                            if (!isLogined)
                            {
                                Thread.Sleep(1000);

                                continue;
                            }

                            break;
                        }

                        this.Invoke((MethodInvoker) delegate
                        {
                            item.Cookie = webBrowser.Document?.Cookie;

                            var document = webBrowser.Document;

                            document?.ExecCommand("ClearAuthenticationCache", false, null);
                        });

                        this.AsyncSetLog(this.tbx_Log, $"{account} 获取Cookie成功!");

                        using (var db = new MangningXssDBEntities())
                        {
                            var pro = db.ZhaopinCleaningProcedure.FirstOrDefault(f => f.Id == item.Id);

                            if (pro != null)
                            {
                                pro.Cookie = item.Cookie;
                            }

                            db.SaveChanges();
                        }

                        isWaitLogin = false;

                        isLogined = false;

                        break;
                    }
                }
            });
        }
        public void Watch()
        {
            //using (var db = new MangningXssDBEntities())
            //{
            //    var maxId = db.ZhaopinCleaningProcedure.Max(m => m.Id);

            //    for (var i = 1; i <= 11; i++)
            //    {
            //        db.ZhaopinCleaningProcedure.Add(new ZhaopinCleaningProcedure
            //        {
            //            Id = (short)(i + maxId),
            //            Account = $"qhzl_{i:000}",
            //            Cookie = null,
            //            IsEnable = true,
            //            IsOnline = false,
            //            Password = "******",
            //            StartTime = DateTime.Now.AddDays(-1)
            //        });
            //    }

            //    db.SaveChanges();
            //}


            if (!Directory.Exists(savePath))
            {
                Directory.CreateDirectory(savePath);
            }

            var cookieQueue = new ConcurrentQueue <KeyValuePair <KeyValuePair <int, string>, CookieContainer> >();

            var companyDic = new ConcurrentDictionary <string, int>();

            using (var db = new MangningXssDBEntities())
            {
                var companyArr = db.ZhaoPinCompany.Where(w => w.Source.Contains("MANUAL")).Select(s => s.Id).ToArray();

                var paramArr = db.ZhaopinStaff.Where(w => companyArr.Any(a => a == w.CompanyId) && !string.IsNullOrEmpty(w.Cookie)).Select(s => new { s.CompanyId, s.Username, s.Cookie }).ToArray();

                foreach (var item in paramArr)
                {
                    companyDic[item.Username] = 0;

                    cookieQueue.Enqueue(new KeyValuePair <KeyValuePair <int, string>, CookieContainer>(new KeyValuePair <int, string>(item.CompanyId, item.Username), item.Cookie.Serialize(".zhaopin.com")));
                }
            }

            using (var db = new MangningXssDBEntities())
            {
                var list = db.ZhaopinCleaningProcedure.Where(w => w.IsEnable && !w.IsOnline && !string.IsNullOrEmpty(w.Cookie));

                foreach (var item in list)
                {
                    if (item.StartTime < DateTime.Today)
                    {
                        item.TodayWatch = 0;
                    }

                    companyDic[item.Account] = item.TodayWatch;

                    cookieQueue.Enqueue(new KeyValuePair <KeyValuePair <int, string>, CookieContainer>(new KeyValuePair <int, string>(0, item.Account), item.Cookie.Serialize(".zhaopin.com")));

                    item.IsOnline = true;

                    item.StartTime = DateTime.Now;
                }

                db.SaveChanges();
            }

            Console.WriteLine($"已获取 Cookie 数 => {cookieQueue.Count}");

            for (var j = 0; j < 16; j++)
            {
                Task.Run(() =>
                {
                    try
                    {
                        while (true)
                        {
                            KeyValuePair <KeyValuePair <int, string>, CookieContainer> temp;

                            if (!cookieQueue.TryDequeue(out temp))
                            {
                                Thread.Sleep(1000);

                                continue;
                            }

                            while (true)
                            {
                                var condition = GetSingleCondition(temp.Key.Value);

                                if (condition == null)
                                {
                                    Console.WriteLine($"Company => {temp.Key.Value} 找不到可搜索的条件!");

                                    Thread.Sleep(1000);

                                    continue;
                                }

                                var pageIndex = 1;

                                var pageTotal = 1;

                                var total = 0;

                                var isbreak = false;

                                var workYearsEnd = condition.WorkYears == 30 ? 30 : condition.WorkYears + 1;

                                while (pageIndex < pageTotal + 1)
                                {
                                    var url = $"https://ihrsearch.zhaopin.com/Home/ResultForCustom?SF_1_1_8={condition.Age}%2C{condition.Age}&SF_1_1_9={condition.Gender}&SF_1_1_4={condition.WorkYears}%2C{workYearsEnd}&SF_1_1_5={condition.Degrees}%2C{condition.Degrees}&orderBy=BIRTH_YEAR%2C0&SF_1_1_27=0&SF_1_1_7={updateRange}%2C9&exclude=1&pageIndex={pageIndex}&pageSize=60";

                                    var requestResult = RequestFactory.QueryRequest(url, cookieContainer: temp.Value, referer: url);

                                    if (!requestResult.IsSuccess)
                                    {
                                        LogFactory.Warn($"Company => {temp.Key.Value} 条件搜索异常!异常原因=>{requestResult.ErrorMsg} Condition=>{JsonConvert.SerializeObject(condition)}");

                                        continue;
                                    }

                                    if (pageTotal == 1)
                                    {
                                        var match = Regex.Match(requestResult.Data, "(?s)<span>(\\d+)</span>份简历.+?rd-resumelist-pageNum\">1/(\\d+)</span>");

                                        if (!match.Success)
                                        {
                                            if (requestResult.Data.Contains("text/javascript\" r='m'"))
                                            {
                                                LogFactory.Warn($"Cookie 过期,过期用户 => {temp.Key.Value}");

                                                RemoveCookie(temp.Key.Value, companyDic[temp.Key.Value]);
                                            }
                                            else
                                            {
                                                LogFactory.Warn($"Company => {temp.Key.Value} 条件搜索异常!返回页面解析异常!{requestResult.Data}");
                                            }

                                            isbreak = true;

                                            break;
                                        }

                                        total = Convert.ToInt32(match.Result("$1"));

                                        pageTotal = Convert.ToInt32(match.Result("$2"));

                                        if (total == 0)
                                        {
                                            Console.WriteLine("该条件无搜索结果!");

                                            break;
                                        }
                                    }

                                    Console.WriteLine($"Company => {temp.Key.Value} 第 {pageIndex} 页  共 {pageTotal} 页 {total} 个结果");

                                    pageIndex++;

                                    //var matchs = Regex.Matches(requestResult.Data, "RedirectToRd/(.+?)','(.+?)','(.+?)',this\\);this");
                                    var matchs = Regex.Matches(requestResult.Data, "(?s)RedirectToRd/([^\r\n]+?)','([^\r\n]+?)','([^\r\n]+?)',this\\);this.+?(\\d{2}-\\d{2}-\\d{2})");

                                    var index = 0;

                                    foreach (Match item in matchs)
                                    {
                                        var number = item.Result("$1").Substring(0, 10);

                                        var numberParam = item.Result("$1").Substring(0, item.Result("$1").IndexOf("?", StringComparison.Ordinal));

                                        DateTime updateDateTime;

                                        if (DateTime.TryParse(item.Result("$4"), out updateDateTime))
                                        {
                                            if (QueryResumeIsExists(number, updateDateTime))
                                            {
                                                continue;
                                            }
                                        }
                                        else
                                        {
                                            if (QueryResumeIsExists(number))
                                            {
                                                continue;
                                            }
                                        }

                                        requestResult = RequestFactory.QueryRequest($"http://ihr.zhaopin.com/resumesearch/getresumedetial.do?resumeNo={numberParam}&searchresume=1&resumeSource=1&keyword=%E8%AF%B7%E8%BE%93%E5%85%A5%E7%AE%80%E5%8E%86%E5%85%B3%E9%94%AE%E8%AF%8D%EF%BC%8C%E5%A4%9A%E5%85%B3%E9%94%AE%E8%AF%8D%E5%8F%AF%E7%94%A8%E7%A9%BA%E6%A0%BC%E5%88%86%E9%9A%94&t={item.Result("$2")}&k={item.Result("$3")}&v=undefined&version=3&openFrom=1", cookieContainer: temp.Value);

                                        if (!requestResult.IsSuccess)
                                        {
                                            LogFactory.Warn($"Company => {temp.Key.Value} 简历详情查看异常!异常原因=>{requestResult.ErrorMsg} ResumeNumber=>{number}");

                                            continue;
                                        }

                                        try
                                        {
                                            var jsonObj = JsonConvert.DeserializeObject <dynamic>(requestResult.Data);

                                            if ((int)jsonObj["code"] != 1)
                                            {
                                                LogFactory.Warn($"Company => {temp.Key.Value} ResumeNumber => {number} 查看详情异常 信息:{(string)jsonObj["message"]} 查看简历份数:{companyDic[temp.Key.Value]}");

                                                if (((string)jsonObj["message"]).Contains("当日查看简历已达上限"))
                                                {
                                                    RemoveCookie(temp.Key.Value, companyDic[temp.Key.Value]);

                                                    isbreak = true;

                                                    break;
                                                }

                                                continue;
                                            }

                                            var resumeData = jsonObj.data;

                                            SaveCacheByOss(new KeyValuePair <KeyValuePair <int, string>, dynamic>(temp.Key, resumeData));

                                            Console.WriteLine($"Company => {temp.Key.Value} 查看简历成功!查看简历份数:{++companyDic[temp.Key.Value]} ResumeNumber => {number} {++index}/{matchs.Count}");
                                        }
                                        catch (Exception ex)
                                        {
                                            while (true)
                                            {
                                                if (ex.InnerException == null)
                                                {
                                                    break;
                                                }

                                                ex = ex.InnerException;
                                            }

                                            LogFactory.Error($"保存简历信息异常!异常信息:{ex.Message} 响应信息:{requestResult.Data}");
                                        }

                                        //if (companyDic[temp.Key.Value] > 1500)
                                        //{
                                        //    RemoveCookie(temp.Key.Value, companyDic[temp.Key.Value]);

                                        //    isbreak = true;

                                        //    break;
                                        //}
                                    }

                                    if (isbreak)
                                    {
                                        break;
                                    }
                                }

                                if (isbreak)
                                {
                                    break;
                                }

                                SetSearchStatus(condition.Id, 1, total);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        while (true)
                        {
                            if (ex.InnerException == null)
                            {
                                break;
                            }

                            ex = ex.InnerException;
                        }

                        LogFactory.Error($"Watch异常!异常信息:{ex.Message}  {ex.StackTrace}");
                    }
                });
            }
        }
        /// <summary>
        /// 上传简历
        /// </summary>
        private static void UploadResume()
        {
            var serializer = new Serialization.Template.Zhaopin.Json.v1.Serializer();

            var stopwatch = new Stopwatch();

            while (true)
            {
                string path;

                if (!uploadQueue.TryDequeue(out path))
                {
                    Thread.Sleep(100);

                    continue;
                }

                Interlocked.Increment(ref totalUpload);

                try
                {
                    stopwatch.Restart();

                    var resumeId = Convert.ToInt32(Path.GetFileNameWithoutExtension(path));

                    var content = File.ReadAllText(path);

                    var jsonObj = JsonConvert.DeserializeObject <dynamic>(content);

                    dynamic formatterResume;

                    try
                    {
                        if (jsonObj.Flag != null && jsonObj.Flag < 0)
                        {
                            formatterResume = Format.Convert_V0(Format.ConvertTo_Dtl_V5(content));
                        }
                        else
                        {
                            var serializationResume = serializer.Deserialize(content);

                            formatterResume = Formatter.Template.Zhaopin.Json.v1.Formatter.Format(serializationResume);
                        }
                    }
                    catch (Exception ex)
                    {
                        var filePath = $"{ConfigurationManager.AppSettings["File.FailPath"]}{Path.GetFileName(path)}";

                        if (File.Exists(filePath))
                        {
                            File.Delete(filePath);
                        }

                        File.Move(path, filePath);

                        Trace.TraceError(ex.ToString());

                        using (var db = new MangningXssDBEntities())
                        {
                            var resume = db.ZhaopinResume.FirstOrDefault(f => f.Id == resumeId);

                            if (resume != null)
                            {
                                resume.Flag = 0xA;
                            }

                            db.SaveChanges();
                        }

                        continue;
                    }

                    string tag;

                    while (true)
                    {
                        var data = JsonConvert.SerializeObject(new
                        {
                            formatterResume.Reference.Id,
                            formatterResume.Reference.Source
                        });

                        var response = PrepareUploadResume(data);

                        if (response.Code.ToString() != "0")
                        {
                            FinishUploadResume(data);

                            Trace.WriteLine($"{DateTime.Now} > PrepareUploadResume failed ! Data = {data}, Response = {JsonConvert.SerializeObject(response)}");

                            continue;
                        }

                        var badoucaiResumeJson = JsonConvert.SerializeObject(formatterResume);

                        response = UploadResume(badoucaiResumeJson);

                        var returnCode = (string)response.Code;

                        using (var db = new MangningXssDBEntities())
                        {
                            tag = response.Reference?.Tag.ToString();

                            db.ZhaopinResumeUploadLog.Add(new ZhaopinResumeUploadLog
                            {
                                ResumeId   = resumeId,
                                ReturnCode = returnCode,
                                Tag        = tag,
                                UploadTime = DateTime.Now
                            });

                            FinishUploadResume(data);

                            var resume = db.ZhaopinResume.FirstOrDefault(f => f.Id == resumeId);

                            if (resume != null)
                            {
                                resume.Flag = 0xF;
                            }

                            if (jsonObj.Flag != null && jsonObj.Flag < 0)
                            {
                                resume.Flag = 0xB;
                            }

                            if (returnCode != "0")
                            {
                                Trace.WriteLine($"{DateTime.Now} > UploadResume failed !ResumeId = {resumeId}, Response = {JsonConvert.SerializeObject(response)}.");

                                tag = "NULL";

                                db.SaveChanges();

                                var filePath = $"{ConfigurationManager.AppSettings["File.UploadFailPath"]}{Path.GetFileName(path)}";

                                if (File.Exists(filePath))
                                {
                                    File.Delete(filePath);
                                }

                                File.Move(path, filePath);

                                break;
                            }

                            if (tag == "C" || tag == "U" || tag == "N")
                            {
                                using (var stream = new MemoryStream(GZip.Compress(Encoding.UTF8.GetBytes(badoucaiResumeJson))))
                                {
                                    var id = response.Reference.ResumeId.ToString();

                                    badoucaiOssClient.PutObject(badoucaiBucketName, $"Badoucai/{id}", stream);
                                }

                                ProgramTasksThread.HandleResume(content, resumeId); // 更新 Resume 表的信息
                            }

                            File.Delete(path);

                            db.SaveChanges();

                            Interlocked.Increment(ref successUpload);
                        }

                        break;
                    }

                    stopwatch.Stop();

                    Console.WriteLine($"{DateTime.Now} > ResumeId = {resumeId}, Tag = {tag}, {successUpload}/{totalUpload} = {Math.Round(successUpload / (double)totalUpload, 3) * 100}%, Elapsed = {stopwatch.ElapsedMilliseconds} ms.");
                }
                catch (Exception ex)
                {
                    Trace.TraceError(ex.ToString());
                }
            }
        }
        /// <summary>
        /// 导入外部Josn
        /// </summary>
        private static void ImportResume()
        {
            var importCount = 0;

            while (true)
            {
                try
                {
                    var filePaths = Directory.GetFiles(importFilePath);

                    if (filePaths.Length == 0)
                    {
                        Thread.Sleep(10 * 1000);

                        continue;
                    }

                    Console.WriteLine($"{DateTime.Now} > {filePaths.Length} Need Import ! ");

                    foreach (var filePath in filePaths)
                    {
                        try
                        {
                            var jsonObj = JsonConvert.DeserializeObject <dynamic>(File.ReadAllText(filePath));

                            var resumeData = jsonObj.data == null ? jsonObj : jsonObj.data;

                            var resumeDetail = JsonConvert.DeserializeObject(resumeData.detialJSonStr.ToString());

                            var resumeId = resumeData.resumeId != null ? (int)resumeData.resumeId : resumeDetail.ResumeId != null ? (int)resumeDetail.ResumeId : 0;

                            var cellphone = resumeData.userDetials.mobilePhone.ToString();

                            if (string.IsNullOrEmpty(cellphone))
                            {
                                var path = importFailPath + Path.GetFileName(filePath);

                                if (File.Exists(path))
                                {
                                    File.Delete(path);
                                }

                                File.Move(filePath, path);

                                continue;
                            }

                            var resumeNumber = ((string)resumeData.resumeNo).Substring(0, 10);

                            var userId = (int)resumeData.userDetials.userMasterId;

                            var refreshTime = BaseFanctory.GetTime((string)resumeDetail.DateLastReleased).ToUniversalTime();

                            using (var db = new MangningXssDBEntities())
                            {
                                var resume = db.ZhaopinResume.FirstOrDefault(f => f.Id == resumeId);

                                var isNeedUpload = true;

                                var sourceFlag = -1;

                                var isUpload = false;

                                if (resume != null)
                                {
                                    sourceFlag = resume.Flag;
                                }

                                if (!(resume?.RefreshTime != null && resume.RefreshTime.Value.Date >= refreshTime.Date) || resume?.Flag < 8)
                                {
                                    if (resume != null)
                                    {
                                        resume.RandomNumber = resumeNumber;
                                        resume.RefreshTime  = refreshTime;
                                        resume.UpdateTime   = DateTime.UtcNow;
                                        if (string.IsNullOrEmpty(resume.UserExtId))
                                        {
                                            resume.UserExtId = resumeDetail.UserMasterExtId?.ToString();
                                        }
                                        if (resumeData.Flag != null && (int)resumeData.Flag < 0)
                                        {
                                            if (resume.Flag >= 8 || mangningOssClient.DoesObjectExist(mangningBucketName, $"Zhaopin/Resume/{resume.Id}") || mangningOssClient.DoesObjectExist(mangningBucketName, $"WatchResume/{resume.Id}"))
                                            {
                                                isNeedUpload = false;
                                            }
                                        }

                                        resume.Flag = 0xE;
                                    }
                                    else
                                    {
                                        resume = new ZhaopinResume
                                        {
                                            Id             = resumeId,
                                            RandomNumber   = resumeNumber,
                                            UserId         = userId,
                                            RefreshTime    = refreshTime,
                                            UpdateTime     = DateTime.UtcNow,
                                            UserExtId      = resumeDetail.UserMasterExtId.ToString(),
                                            DeliveryNumber = null,
                                            Source         = "Import",
                                            Flag           = 0xE
                                        };

                                        db.ZhaopinResume.Add(resume);
                                    }

                                    var user = db.ZhaopinUser.FirstOrDefault(f => f.Id == userId);

                                    if (user != null)
                                    {
                                        if (!user.Source.Contains("MANUAL"))
                                        {
                                            user.ModifyTime = BaseFanctory.GetTime((string)resumeDetail.DateModified).ToUniversalTime();
                                            user.CreateTime = resumeData.Flag != null && (int)resumeData.Flag < 0 ? user.CreateTime : BaseFanctory.GetTime((string)resumeDetail.DateCreated).ToUniversalTime();
                                            user.Cellphone  = resumeData.userDetials.mobilePhone.ToString();
                                            user.Email      = resumeData.userDetials.email.ToString();
                                            user.Name       = resumeData.userDetials.userName.ToString();
                                            user.UpdateTime = DateTime.UtcNow;
                                            user.Username   = resumeData.userDetials.email.ToString();
                                        }
                                    }
                                    else
                                    {
                                        user = new ZhaopinUser
                                        {
                                            Id         = userId,
                                            Source     = "Import",
                                            ModifyTime = BaseFanctory.GetTime((string)resumeDetail.DateModified).ToUniversalTime(),
                                            CreateTime = BaseFanctory.GetTime((string)resumeDetail.DateCreated).ToUniversalTime(),
                                            Cellphone  = resumeData.userDetials.mobilePhone.ToString(),
                                            Email      = resumeData.userDetials.email.ToString(),
                                            Name       = resumeData.userDetials.userName.ToString(),
                                            UpdateTime = DateTime.UtcNow,
                                            Username   = resumeData.userDetials.email.ToString()
                                        };

                                        db.ZhaopinUser.Add(user);
                                    }

                                    if (isNeedUpload)
                                    {
                                        isUpload = true;

                                        var resumeContent = JsonConvert.SerializeObject(resumeData);

                                        using (var jsonStream = new MemoryStream(GZip.Compress(Encoding.UTF8.GetBytes(resumeContent))))
                                        {
                                            mangningOssClient.PutObject(mangningBucketName, $"Zhaopin/Resume/{resume.Id}", jsonStream);
                                        }
                                    }

                                    db.SaveChanges();
                                }

                                File.Delete(filePath);

                                Console.WriteLine($"{DateTime.Now} > Improt success ! ResumeId = {resumeId}, SourceFlag = {sourceFlag}, IsUpload = {isUpload}, Count = {++importCount}.");
                            }
                        }
                        catch (Exception ex)
                        {
                            var path = importFailPath + Path.GetFileName(filePath);

                            if (File.Exists(path))
                            {
                                File.Delete(path);
                            }

                            File.Move(filePath, path);

                            Trace.WriteLine($"{DateTime.Now} > Import Error Message = {ex.Message}, Path = {path}.");
                        }
                    }
                }
                catch (Exception ex)
                {
                    Trace.TraceError(ex.ToString());
                }
            }
        }
        /// <summary>
        /// 处理多迪简历
        /// </summary>
        private static void HandleDodiResume()
        {
            while (true)
            {
                ZhaopinCleaningProcedure cleaningProcedure;

                if (!cookieQueue.TryDequeue(out cleaningProcedure))
                {
                    Thread.Sleep(100);

                    continue;
                }

                var localCookieContainer = cleaningProcedure.Cookie.Serialize(".zhaopin.com");

                while (true)
                {
                    int businessId;

                    if (!businessIdQueue.TryDequeue(out businessId))
                    {
                        Thread.Sleep(100);

                        continue;
                    }

                    using (var db = new MangningXssDBEntities())
                    {
                        var dodiBusiness = db.DodiBusiness.FirstOrDefault(f => f.Id == businessId);

                        if (dodiBusiness != null)
                        {
                            dodiBusiness.Status = 2;

                            db.SaveChanges();
                        }
                    }

                    try
                    {
                        var response = RequestFactory.QueryRequest($"http://crm.dodi.cn/index.php/Main/khxxy/business_id/{businessId}/source/false_note", cookieContainer: cookieContainer);

                        if (!response.IsSuccess)
                        {
                            continue;
                        }

                        if (!response.Data.Contains("商 机 ID:"))
                        {
                            Trace.WriteLine($"{DateTime.Now} > Business ID is Empty ! BusinessId = {businessId}");

                            continue;
                        }

                        var match = Regex.Match(response.Data, @"resume_email\('(.*?)','(\d+)','(\d+)','(\d+)',(\d+)\)");

                        if (!match.Success)
                        {
                            Trace.WriteLine($"{DateTime.Now} > Details match failed ! BusinessId = {businessId}");

                            continue;
                        }

                        var email = HttpUtility.UrlEncode(match.Result("$1"));

                        var phone = HttpUtility.UrlEncode(match.Result("$2"));

                        var email_id = HttpUtility.UrlEncode(match.Result("$3"));

                        var now_month = HttpUtility.UrlEncode(match.Result("$4"));

                        var school_id = HttpUtility.UrlEncode(match.Result("$5"));

                        response = HttpClientFactory.RequestForString($"http://crm.dodi.cn/index.php/Main/email_body?email={email}&phone={phone}&email_id={email_id}&now_month={now_month}&school_id={school_id}", HttpMethod.Get, null, cookieContainer);

                        if (!response.IsSuccess)
                        {
                            Trace.WriteLine($"{DateTime.Now} > Details request failed ! BusinessId = {businessId}");

                            continue;
                        }

                        var resumeDetail = Regex.Unescape(response.Data);

                        var company = Regex.Match(resumeDetail, "20[01]\\d[.][\\d\\s-.]+(.*?)\\s*(").ResultOrDefault("$1", "");

                        if (string.IsNullOrEmpty(company))
                        {
                            Console.WriteLine($"{DateTime.Now} > Company is Empty ! BusinessId = {businessId}");

                            continue;
                        }

                        var matchs = Regex.Matches(resumeDetail, "20[01]\\d\\.\\d{2}\\s-\\s20[01]\\d\\.\\d{2}\\s+([^&]+?)&");

                        var project = string.Empty;

                        foreach (Match item in matchs)
                        {
                            var matchString = item.Result("$1");

                            if (matchString.Contains("("))
                            {
                                continue;
                            }

                            if (matchString.Contains("</br>"))
                            {
                                continue;
                            }

                            if (matchString.Contains(" "))
                            {
                                continue;
                            }

                            project = matchString;

                            break;
                        }

                        if (string.IsNullOrEmpty(project))
                        {
                            Console.WriteLine($"{DateTime.Now} > Project is Empty ! BusinessId = {businessId}");

                            continue;
                        }

                        var url = $"https://ihrsearch.zhaopin.com/Home/ResultForCustom?SF_1_1_1={HttpUtility.UrlEncode(project)}&SF_1_1_25=COMPANY_NAME_ALL:{HttpUtility.UrlEncode(company)}&SF_1_1_27=0&orderBy=DATE_MODIFIED,1&pageSize=60&exclude=1";

                        var requestResult = RequestFactory.QueryRequest(url, cookieContainer: localCookieContainer, referer: url);

                        if (!requestResult.IsSuccess)
                        {
                            Trace.TraceError($"{DateTime.Now} > Search request failed ! BusinessId = {businessId}.");

                            continue;
                        }

                        match = Regex.Match(requestResult.Data, "(?s)<span>(\\d+)</span>份简历.+?rd-resumelist-pageNum\">1/(\\d+)</span>");

                        if (!match.Success)
                        {
                            if (requestResult.Data.Contains("text/javascript\" r='m'"))
                            {
                                Console.WriteLine($"{DateTime.Now} > Cookie Expired ! Account = {cleaningProcedure.Account}.");
                            }
                            else
                            {
                                Trace.TraceWarning($"{DateTime.Now} > Condition search error ! Page content = {requestResult.Data}, Account = {cleaningProcedure.Account}.");
                            }

                            using (var db = new MangningXssDBEntities())
                            {
                                var procedure = db.ZhaopinCleaningProcedure.FirstOrDefault(f => f.Id == cleaningProcedure.Id);

                                if (procedure != null)
                                {
                                    procedure.Cookie = null;

                                    db.SaveChanges();
                                }
                            }

                            businessIdQueue.Enqueue(businessId);

                            break;
                        }

                        var total = Convert.ToInt32(match.Result("$1"));

                        if (total != 1)
                        {
                            Console.WriteLine($"{DateTime.Now} > Search match wrong ! ResultCount = {total}, BusinessId = {businessId}, Company = {company}, Project = {project}.");

                            continue;
                        }

                        match = Regex.Match(requestResult.Data, "(?s)RedirectToRd/([^\r\n]+?)','([^\r\n]+?)','([^\r\n]+?)',this\\);this.+?(\\d{2}-\\d{2}-\\d{2})");

                        HandleResume(match, HttpUtility.HtmlDecode(phone), HttpUtility.HtmlDecode(email), cleaningProcedure, businessId);
                    }
                    catch (Exception ex)
                    {
                        Trace.TraceError(ex.ToString());
                    }
                }
            }
        }
        /// <summary>
        /// 查看简历详情
        /// </summary>
        /// <param name="match"></param>
        /// <param name="localCookieContainer"></param>
        /// <param name="cellphone"></param>
        /// <param name="email"></param>
        /// <param name="businessId"></param>
        /// <returns></returns>
        private static bool WatchResumeDetail(Match match, CookieContainer localCookieContainer, string cellphone, string email, int businessId)
        {
            var number = match.Result("$1").Substring(0, 10);

            var numberParam = match.Result("$1").Substring(0, match.Result("$1").IndexOf("?", StringComparison.Ordinal));

            var requestResult = RequestFactory.QueryRequest($"http://ihr.zhaopin.com/resumesearch/getresumedetial.do?resumeNo={numberParam}&searchresume=1&resumeSource=1&keyword=%E8%AF%B7%E8%BE%93%E5%85%A5%E7%AE%80%E5%8E%86%E5%85%B3%E9%94%AE%E8%AF%8D%EF%BC%8C%E5%A4%9A%E5%85%B3%E9%94%AE%E8%AF%8D%E5%8F%AF%E7%94%A8%E7%A9%BA%E6%A0%BC%E5%88%86%E9%9A%94&t={match.Result("$2")}&k={match.Result("$3")}&v=undefined&version=3&openFrom=1", cookieContainer: localCookieContainer);

            if (!requestResult.IsSuccess)
            {
                Trace.WriteLine($"{DateTime.Now} > Watching error ! Message = {requestResult.ErrorMsg}, ResumeNumber = {number}");

                return(false);
            }

            try
            {
                var jsonObj = JsonConvert.DeserializeObject <dynamic>(requestResult.Data);

                if ((int)jsonObj["code"] != 1)
                {
                    Trace.WriteLine($"{DateTime.Now} > Watching failure ! Message = {(string)jsonObj["message"]}, ResumeNumber = {number}");

                    return(false);
                }

                var resumeData = jsonObj.data;

                resumeData.userDetials.mobilePhone = cellphone;

                resumeData.userDetials.email = email;

                var resumeDetail = JsonConvert.DeserializeObject(resumeData.detialJSonStr.ToString());

                var resumeId = resumeData.resumeId != null ? (int)resumeData.resumeId : resumeDetail.ResumeId != null ? (int)resumeDetail.ResumeId : 0;

                using (var db = new MangningXssDBEntities())
                {
                    var business = db.DodiBusiness.FirstOrDefault(f => f.Id == businessId);

                    if (business != null)
                    {
                        business.Status = 3;

                        db.SaveChanges();
                    }
                }

                File.WriteAllText($"{path}{resumeId}.json", JsonConvert.SerializeObject(resumeData));

                Console.WriteLine($"{DateTime.Now} > Completion success ! ResumeNumber = {number}.");

                return(true);
            }
            catch (Exception ex)
            {
                while (true)
                {
                    if (ex.InnerException == null)
                    {
                        break;
                    }

                    ex = ex.InnerException;
                }

                Trace.WriteLine($"{DateTime.Now} > Watching exception ! Message = {ex.Message}, ResumeNumber = {number}");

                return(false);
            }
        }
        /// <summary>
        /// 刷新验证码
        /// </summary>
        /// <returns></returns>
        private DataResult ReferenceCheckCode()
        {
            // 准备颜色变换矩阵的元素
            float[][] colorMatrixElements =
            {
                new float[] { -1,  0,  0, 0, 0 },
                new float[] {  0, -1,  0, 0, 0 },
                new float[] {  0,  0, -1, 0, 0 },
                new float[] {  0,  0,  0, 1, 0 },
                new float[] {  1,  1,  1, 0, 1 }
            };

            // 为 ImageAttributes 设置颜色变换矩阵

            var colorMatrix = new ColorMatrix(colorMatrixElements);

            var imageAttributes = new ImageAttributes();

            imageAttributes.SetColorMatrix(colorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);

            locationStack.Clear();

            var streamResult = HttpClientFactory.RequestForStream("https://rd.zhaopin.com/resumePreview/captcha/getcap?t1515065150298", HttpMethod.Get, cookieContainer: cookieContainer);

            if (!streamResult.IsSuccess)
            {
                this.RunInMainthread(() =>
                {
                    this.lbl_Tip.Text = $"提示:{DateTime.Now:HH:mm:ss} 未获取到验证码!{streamResult.ErrorMsg}";
                });

                isGetCheckCode = false;

                return(new DataResult("未获取到验证码!"));
            }

            var codeStream = streamResult.Data;

            timestamp = (DateTime.Now.ToUniversalTime().Ticks - 621355968000000000) / 10000000 + new Random().Next(0, 1000).ToString("000");

            // 将 ImageAttributes 应用于绘制

            Bitmap picBody;

            try
            {
                picBody = Image.FromHbitmap(ImageHelper.GetValidCode_Zhaopin(Image.FromStream(codeStream)).GetHbitmap());
            }
            catch (Exception)
            {
                using (var db = new MangningXssDBEntities())
                {
                    var checkCode = db.ZhaopinCheckCode.FirstOrDefault(f => f.HandleUser == handleUser && f.Status != 2);

                    if (checkCode != null)
                    {
                        db.ZhaopinCheckCode.Remove(checkCode);

                        db.SaveChanges();
                    }

                    this.RunInMainthread(() =>
                    {
                        this.lbl_Tip.Text = $"提示:{DateTime.Now:HH:mm:ss} Cookie 过期!CompanyName = {compnayName}";
                    });

                    isGetCheckCode = false;

                    return(new DataResult("未获取到验证码!"));
                }
            }

            var imageBody = new Bitmap(picBody.Width, picBody.Height);

            var graphics = Graphics.FromImage(imageBody);

            graphics.DrawImage(picBody, new Rectangle(0, 0, picBody.Width, picBody.Height), 0, 0, picBody.Width, picBody.Height, GraphicsUnit.Pixel, imageAttributes);

            var picHeader = Image.FromHbitmap(ImageHelper.GetValidCodeSource_Zhaopin(Image.FromStream(codeStream)).GetHbitmap());

            var imageHeader = new Bitmap(picHeader.Width, picHeader.Height);

            graphics = Graphics.FromImage(imageHeader);

            graphics.DrawImage(picHeader, new Rectangle(0, 0, picHeader.Width, picHeader.Height), 0, 0, picHeader.Width, picHeader.Height, GraphicsUnit.Pixel, imageAttributes);

            graphics.Dispose();

            this.pic_Header.Image = imageHeader;

            this.pic_Body.Image = imageBody;

            endTime = DateTime.Now.AddMinutes(1);

            locationStack.Push(new Watermark
            {
                Index     = 0,
                Image     = this.pic_Body.Image,
                LocationX = -999,
                LocationY = -999
            });

            isGetCheckCode = false;

            return(new DataResult());
        }
        private void btn_Checking_Click(object sender, EventArgs e)
        {
            var coordinatParam = string.Empty;

            var list = new List <Watermark>();

            if (!locationStack.Any())
            {
                return;
            }

            while (true)
            {
                var watermark = locationStack.Pop();

                if (watermark.Index == 0)
                {
                    break;
                }

                list.Add(watermark);
            }

            list.Reverse();

            coordinatParam = list.Aggregate(coordinatParam, (current, item) => current + $";{item.LocationX + range / 2},{item.LocationY + range / 2}");

            if (coordinatParam.Length == 0)
            {
                coordinatParam = "99,99;99,99;99,99";
            }

            coordinatParam = coordinatParam.Substring(1);

            var checkedResult = RequestFactory.QueryRequest("https://rd.zhaopin.com/resumePreview/captcha/verifyjsonp?callback=jsonpCallback", $"p={HttpUtility.UrlEncode(coordinatParam)}&time={timestamp}", RequestEnum.POST, cookieContainer, host: proxyHost);

            if (!checkedResult.IsSuccess)
            {
                MessageBox.Show(checkedResult.ErrorMsg);

                return;
            }

            var match = Regex.Match(checkedResult.Data, "jsonpCallback\\('(.+?)'\\)");

            if (!match.Success)
            {
                this.lbl_Tip.Text = $"提示:{DateTime.Now:HH:mm:ss} 验证失败!";

                endTime = DateTime.Now.AddMinutes(1);

                var dataResult = ReferenceCheckCode();

                if (!dataResult.IsSuccess)
                {
                    endTime = null;
                }

                return;
            }

            checkedResult = RequestFactory.QueryRequest("https://rd.zhaopin.com/resumePreview/resume/_CheackValidatingCode?validatingCode=" + match.Result("$1"), "", RequestEnum.POST, cookieContainer, host: proxyHost);

            if (!checkedResult.IsSuccess || checkedResult.Data.ToLower().Trim() != "true")
            {
                this.lbl_Tip.Text = $"提示:{DateTime.Now:HH:mm:ss} 验证失败!{checkedResult.ErrorMsg}";

                endTime = DateTime.Now.AddMinutes(1);

                var dataResult = ReferenceCheckCode();

                if (!dataResult.IsSuccess)
                {
                    endTime = null;
                }

                return;
            }

            this.lbl_Tip.Text = $"提示:{DateTime.Now:HH:mm:ss} 验证成功!";

            endTime = null;

            this.btn_GetCheckCode.Enabled = true;

            this.btn_ReferenceCheckCode.Enabled = false;

            this.btn_Checking.Enabled = false;

            this.pic_Body.Image = null;

            this.pic_Header.Image = null;

            using (var db = new MangningXssDBEntities())
            {
                var checkCode = db.ZhaopinCheckCode.FirstOrDefault(f => f.HandleUser == handleUser && f.Status == 1);

                if (checkCode == null)
                {
                    return;
                }

                checkCode.Status = 2;

                checkCode.CompleteTime = DateTime.Now;

                db.SaveChanges();
            }

            ReferenceRank();
        }
        /// <summary>
        /// 處理簡歷列表
        /// </summary>
        /// <param name="resumes"></param>
        /// <param name="unhandled"></param>
        /// <param name="staff"></param>
        /// <param name="isWhile"></param>
        /// <param name="cookieContainer"></param>
        private static void HandleResumes(dynamic resumes, int unhandled, ZhaopinStaff staff, ref bool isWhile, CookieContainer cookieContainer)
        {
            var stopwatch = new Stopwatch();

            foreach (var item in resumes)
            {
                #region Handle resume

                try
                {
                    stopwatch.Restart();

                    #region Save resume and Upload

                    var requestResult = RequestFactory.QueryRequest($"http://ihr.zhaopin.com/resumesearch/getresumedetial.do?resumeNo={item.id}_{item.jobNumber}_{item.number}_1_1&resumeSource=3", cookieContainer: cookieContainer);

                    if (!requestResult.IsSuccess)
                    {
                        Trace.TraceWarning(requestResult.ErrorMsg);

                        continue;
                    }

                    var content = JsonConvert.DeserializeObject <dynamic>(requestResult.Data);

                    if ((int)content.code == 6001) // 登录过期
                    {
                        using (var db = new MangningXssDBEntities())
                        {
                            var zhaopinStaff = db.ZhaopinStaff.FirstOrDefault(f => f.Id == staff.Id);

                            if (zhaopinStaff != null)
                            {
                                zhaopinStaff.Cookie = null;

                                db.SaveChanges();

                                dictionary.TryRemove(staff.Id, out companyId);
                            }
                        }

                        Trace.WriteLine($"{DateTime.Now} > Loging Timeout ! Username = {staff.Username}, Message = {content.message}.");

                        isWhile = false;

                        break;
                    }

                    if ((int)content.code != 1)
                    {
                        Trace.WriteLine($"{DateTime.Now} > Get Resume Detail Error ! Username = {staff.Username}, Message = {content.message}.");

                        continue;
                    }

                    var resumeData = content.data;

                    var resumeDetail = JsonConvert.DeserializeObject(resumeData.detialJSonStr.ToString());

                    var refreshTime = BaseFanctory.GetTime((string)resumeDetail.DateLastReleased).ToUniversalTime();

                    resumeData.detialJSonStr = resumeDetail;

                    var resumeNumber = ((string)resumeData.resumeNo).Substring(0, 10);

                    var userId = (int)resumeData.userDetials.userMasterId;

                    var resumeId = resumeData.resumeId != null ? (int)resumeData.resumeId : resumeDetail.ResumeId != null ? (int)resumeDetail.ResumeId : 0;

                    var status = "Handle";

                    using (var db = new MangningXssDBEntities())
                    {
                        var resume = db.ZhaopinResume.FirstOrDefault(f => f.Id == resumeId);

                        if (!(resume?.RefreshTime != null && resume.RefreshTime.Value.Date >= refreshTime.Date))
                        {
                            if (resume != null)
                            {
                                resume.RandomNumber = resumeNumber;
                                resume.RefreshTime  = refreshTime;
                                resume.UpdateTime   = DateTime.UtcNow;
                                if (string.IsNullOrEmpty(resume.UserExtId))
                                {
                                    resume.UserExtId = resumeDetail.UserMasterExtId.ToString();
                                }
                                resume.Source = !resume.Source.Contains("Deliver") ? resume.Source += ",Deliver" : resume.Source;
                                resume.Flag   = 0xE;
                            }
                            else
                            {
                                resume = new ZhaopinResume
                                {
                                    Id             = resumeId,
                                    RandomNumber   = resumeNumber,
                                    UserId         = userId,
                                    RefreshTime    = refreshTime,
                                    UpdateTime     = DateTime.UtcNow,
                                    UserExtId      = resumeDetail.UserMasterExtId.ToString(),
                                    DeliveryNumber = null,
                                    Source         = "Deliver",
                                    Flag           = 0xE
                                };

                                db.ZhaopinResume.Add(resume);
                            }

                            var user = db.ZhaopinUser.FirstOrDefault(f => f.Id == userId);

                            if (user != null)
                            {
                                if (!user.Source.Contains("MANUAL"))
                                {
                                    user.ModifyTime = BaseFanctory.GetTime((string)resumeDetail.DateModified).ToUniversalTime();
                                    user.CreateTime = BaseFanctory.GetTime((string)resumeDetail.DateCreated).ToUniversalTime();
                                    user.Cellphone  = resumeData.userDetials.mobilePhone.ToString();
                                    user.Email      = resumeData.userDetials.email.ToString();
                                    user.Name       = resumeData.userDetials.userName.ToString();
                                    user.UpdateTime = DateTime.UtcNow;
                                    user.Username   = resumeData.userDetials.email.ToString();
                                }
                            }
                            else
                            {
                                user = new ZhaopinUser
                                {
                                    Id         = userId,
                                    Source     = "Deliver",
                                    ModifyTime = BaseFanctory.GetTime((string)resumeDetail.DateModified).ToUniversalTime(),
                                    CreateTime = BaseFanctory.GetTime((string)resumeDetail.DateCreated).ToUniversalTime(),
                                    Cellphone  = resumeData.userDetials.mobilePhone.ToString(),
                                    Email      = resumeData.userDetials.email.ToString(),
                                    Name       = resumeData.userDetials.userName.ToString(),
                                    UpdateTime = DateTime.UtcNow,
                                    Username   = resumeData.userDetials.email.ToString()
                                };

                                db.ZhaopinUser.Add(user);
                            }

                            var resumeContent = JsonConvert.SerializeObject(resumeData);

                            using (var jsonStream = new MemoryStream(GZip.Compress(Encoding.UTF8.GetBytes(resumeContent))))
                            {
                                mangningOssClient.PutObject(mangningBucketName, $"Zhaopin/Resume/{resumeId}", jsonStream);
                            }

                            var resumePath = $"{uploadFilePath}{resumeId}.json";

                            File.WriteAllText(resumePath, JsonConvert.SerializeObject(resumeData));

                            db.SaveChanges();
                        }
                        else
                        {
                            status = "NoHandle";
                        }
                    }

                    #endregion

                    Thread.Sleep(3000);

                    #region SignResume

                    var data = HttpUtility.UrlEncode(JsonConvert.SerializeObject(new
                    {
                        signTag    = "noSuit",
                        resumeList = new List <dynamic>
                        {
                            new
                            {
                                resumeNo     = $"{item.jobNumber}_{item.number}_{item.version}_1",
                                resumenumber = item.number,
                                item.version,
                                lanType      = 1,
                                jobname      = ((string)resumeData?.jobName)?.Replace("\"", "\\\"").Replace("\\", "\\\\"),
                                jobno        = item.jobNumber,
                                resumesource = item.resumeSource,
                                resumeJobId  = item.id,
                                resumerName  = ((string)item?.userName).Replace("\r", "").Replace("\n", "").Replace("\"", "\\\""),
                                resumejlName = ((string)item?.name).Replace("\r", "").Replace("\n", "").Replace("\"", "\\'").Replace("\\", "\\\\"),
                                resumerId    = item.userId
                            }
                        },
                        mark = ""
                    }));

                    requestResult = RequestFactory.QueryRequest("https://ihr.zhaopin.com/resumemanage/resumesignstate.do", $"data={data}", RequestEnum.POST, cookieContainer);

                    if (!requestResult.IsSuccess)
                    {
                        Trace.TraceWarning(requestResult.ErrorMsg);

                        continue;
                    }

                    content = JsonConvert.DeserializeObject <dynamic>(requestResult.Data);

                    if ((int)content.code == 6001) // 登录过期
                    {
                        using (var db = new MangningXssDBEntities())
                        {
                            var zhaopinStaff = db.ZhaopinStaff.FirstOrDefault(f => f.Id == staff.Id);

                            if (zhaopinStaff != null)
                            {
                                zhaopinStaff.Cookie = null;

                                db.SaveChanges();

                                dictionary.TryRemove(staff.Id, out companyId);
                            }
                        }

                        Trace.WriteLine($"{DateTime.Now} > Loging Timeout ! Username = {staff.Username}, Message = {content.message}.");

                        isWhile = false;

                        break;
                    }

                    if ((int)content.code != 1)
                    {
                        Trace.WriteLine($"{DateTime.Now} > Sign Resume Error ! Username = {staff.Username}, Message = {content.message}, ResumeId = {resumeId}.");

                        continue;
                    }

                    #endregion

                    stopwatch.Stop();

                    var elapsed = stopwatch.ElapsedMilliseconds;

                    Interlocked.Increment(ref count);

                    Console.WriteLine($"{DateTime.Now} > {count} {status} {staff.Username}:Unhandled = {--unhandled}, RId = {resumeId}, Elapsed = {elapsed} ms.");
                }
                catch (Exception ex)
                {
                    Trace.TraceError(ex.ToString());
                }

                #endregion
            }
        }
Beispiel #11
0
        private static void DownloadForTalentFolder()
        {
            var business = new SpiderResumeBusiness();

            Console.WriteLine("开始获取 Cookie ...");

            var cookies = business.GetCookies();

            foreach (var item in cookies)
            {
                cookieQueue.Enqueue(item);
            }

            for (var i = 0; i < taskCount; i++)
            {
                tasks.Add(Task.Run(() =>
                {
                    while (true)
                    {
                        KeyValuePair <int, string> cookie;

                        if (!cookieQueue.TryDequeue(out cookie))
                        {
                            break;
                        }

                        try
                        {
                            var token = cookie.Value.Substring(cookie.Value.IndexOf("at=", StringComparison.Ordinal) + 3, 32);

                            Console.WriteLine($"Cookie 队列剩余:{cookieQueue.Count}, 当前 Token:{token}");

                            var cookieContainer = cookie.Value.Serialize("zhaopin.com");

                            DataResult <string> requestResult;

                            dynamic content;

                            dynamic summary;

                            int count;

                            int pageNumber;

                            int begin;

                            int end;

                            var isBreak = false;

                            #region  载简历库简历

                            foreach (var key in new[] { "deal", "commu", "interview", "noSuit" })
                            {
                                var isContinue = false;

                                requestResult = business.GetResumes(cookieContainer, 0, 1, key, token);

                                if (!requestResult.IsSuccess)
                                {
                                    break;
                                }

                                content = JsonConvert.DeserializeObject <dynamic>(requestResult.Data);

                                if ((int)content.code != 1)
                                {
                                    LogFactory.Warn($"简历列表下载异常!message:{content.message} companyId:{cookie.Key}");

                                    if ((int)content.code == 6001) // 登录过期
                                    {
                                        isBreak = true;

                                        using (var db = new MangningXssDBEntities())
                                        {
                                            var staff = db.ZhaopinStaff.FirstOrDefault(f => f.CompanyId == cookie.Key);

                                            if (staff != null)
                                            {
                                                staff.Cookie = null;

                                                db.SaveChanges();
                                            }
                                        }

                                        break;
                                    }

                                    continue;
                                }

                                count = (int)content.data[key].numFound;

                                //Console.WriteLine($"CompanyId:{cookie.Key},分类:{key} 简历数:{count}");

                                if (count == 0)
                                {
                                    continue;
                                }

                                if (business.IsDownloadByDeliveryId((long)content.data[key].results[0].id, key))
                                {
                                    continue;
                                }

                                pageNumber = (int)Math.Ceiling(count / 90.0);

                                while (true)
                                {
                                    requestResult = business.GetResumes(cookieContainer, count - 1, 90, key, token);

                                    if (!requestResult.IsSuccess)
                                    {
                                        isContinue = true;

                                        break;
                                    }

                                    content = JsonConvert.DeserializeObject <dynamic>(requestResult.Data);

                                    if ((int)content.data[key].results.Count != 1)
                                    {
                                        var numFound = (int)content.data[key].numFound;

                                        if (numFound == count)
                                        {
                                            break;
                                        }

                                        count = numFound;

                                        continue;
                                    }

                                    break;
                                }

                                if (isContinue)
                                {
                                    continue;
                                }

                                summary = content.data[key].results[(int)content.data[key].results.Count - 1];

                                if (!business.IsDownloadByDeliveryId((long)summary.id, key))
                                {
                                    business.DownloadResumes(cookieContainer, pageNumber - 1, key, cookie.Key, business.GetResumes, token);

                                    continue;
                                }

                                #region 中分法查找新纪录的位置

                                begin = 0;

                                end = pageNumber - 1;

                                while (begin <= end)
                                {
                                    //Console.WriteLine($"Begin:{begin},End:{end}");

                                    Thread.Sleep(10);

                                    var current = (begin + end) >> 1;

                                    if (begin == end)
                                    {
                                        business.DownloadResumes(cookieContainer, current, key, cookie.Key, business.GetResumes, token);

                                        break;
                                    }

                                    requestResult = business.GetResumes(cookieContainer, current * 90, 90, key, token);

                                    if (!requestResult.IsSuccess)
                                    {
                                        break;
                                    }

                                    content = JsonConvert.DeserializeObject <dynamic>(requestResult.Data);

                                    if ((int)content.code != 1)
                                    {
                                        LogFactory.Warn($"简历列表下载异常!message:{content.message} companyId:{cookie.Key}");

                                        if ((int)content.code == 6001) // 登录过期
                                        {
                                            isBreak = true;

                                            using (var db = new MangningXssDBEntities())
                                            {
                                                var staff = db.ZhaopinStaff.FirstOrDefault(f => f.CompanyId == cookie.Key);

                                                if (staff != null)
                                                {
                                                    staff.Cookie = null;

                                                    db.SaveChanges();
                                                }
                                            }

                                            break;
                                        }

                                        continue;
                                    }

                                    count = (int)content.data[key].numFound;

                                    if (pageNumber != (int)Math.Ceiling(count / 90.0))
                                    {
                                        pageNumber = (int)Math.Ceiling(count / 90.0);

                                        end = pageNumber - 1;

                                        continue;
                                    }

                                    var summaries = content.data[key].results;

                                    var size = summaries.Count;

                                    // 如果当前页的第一条记录是否下载过,下载过则向前搜索,
                                    // 否则继续判断最后一条是否下载过,如下载过,则断点在
                                    // 当前页,否则向后搜索

                                    if (business.IsDownloadByDeliveryId((long)summaries[0].id, key))
                                    {
                                        end = current;
                                    }
                                    else
                                    {
                                        if (business.IsDownloadByDeliveryId((long)summaries[size - 1].id, key))
                                        {
                                            business.DownloadResumes(cookieContainer, current, key, cookie.Key, business.GetResumes, token);

                                            break;
                                        }

                                        begin = current + 1;
                                    }
                                }

                                #endregion
                            }

                            #endregion

                            if (isBreak)
                            {
                                continue;
                            }

                            #region  载回收站的简历

                            requestResult = business.GetRecycleResumes(cookieContainer, 0, 1, "recycle", token);

                            if (!requestResult.IsSuccess)
                            {
                                break;
                            }

                            content = JsonConvert.DeserializeObject <dynamic>(requestResult.Data);

                            count = (int)content.data.numFound;

                            //Console.WriteLine($"CompanyId:{cookie.Key},分类:Recycle 简历数:{count}");

                            if (count == 0)
                            {
                                continue;
                            }

                            if (business.IsDownloadByDeliveryId((long)content.data.results[0].id, "recycle"))
                            {
                                continue;
                            }

                            pageNumber = (int)Math.Ceiling(count / 90.0);

                            while (true)
                            {
                                requestResult = business.GetRecycleResumes(cookieContainer, count - 1, 90, "recycle", token);

                                if (!requestResult.IsSuccess)
                                {
                                    break;
                                }

                                content = JsonConvert.DeserializeObject <dynamic>(requestResult.Data);

                                if ((int)content.data.results.Count != 1)
                                {
                                    var numFound = (int)content.data.numFound;

                                    if (numFound == count)
                                    {
                                        break;
                                    }

                                    count = numFound;

                                    continue;
                                }

                                break;
                            }
                            summary = content.data.results[(int)content.data.results.Count - 1];

                            if (!business.IsDownloadByDeliveryId((long)summary.id, "recycle"))
                            {
                                business.DownloadResumes(cookieContainer, pageNumber - 1, "recycle", cookie.Key, business.GetRecycleResumes, token);

                                continue;
                            }

                            #region 中分法查找新纪录的位置

                            begin = 0;

                            end = pageNumber - 1;

                            while (begin <= end)
                            {
                                //Console.WriteLine($"Begin:{begin},End:{end}");

                                Thread.Sleep(10);

                                var current = (begin + end) >> 1;

                                if (begin == end)
                                {
                                    business.DownloadResumes(cookieContainer, current, "recycle", cookie.Key, business.GetRecycleResumes, token);

                                    break;
                                }

                                requestResult = business.GetRecycleResumes(cookieContainer, current * 90, 90, "recycle", token);

                                if (!requestResult.IsSuccess)
                                {
                                    break;
                                }

                                content = JsonConvert.DeserializeObject <dynamic>(requestResult.Data);

                                count = (int)content.data.numFound;

                                if (pageNumber != (int)Math.Ceiling(count / 90.0))
                                {
                                    pageNumber = (int)Math.Ceiling(count / 90.0);

                                    end = pageNumber - 1;

                                    continue;
                                }

                                var summaries = content.data.results;

                                var size = summaries.Count;

                                // 如果当前页的第一条记录是否下载过,下载过则向前搜索,
                                // 否则继续判断最后一条是否下载过,如下载过,则断点在
                                // 当前页,否则向后搜索

                                if (business.IsDownloadByDeliveryId((long)summaries[0].id, "recycle"))
                                {
                                    end = current;
                                }
                                else
                                {
                                    if (business.IsDownloadByDeliveryId((long)summaries[size - 1].id, "recycle"))
                                    {
                                        business.DownloadResumes(cookieContainer, current, "recycle", cookie.Key, business.GetRecycleResumes, token);

                                        break;
                                    }

                                    begin = current + 1;
                                }
                            }

                            #endregion

                            #endregion

                            while (true)
                            {
                                if (SpiderResumeBusiness.downQueue.Count != 0)
                                {
                                    Thread.Sleep(1000);

                                    continue;
                                }

                                break;
                            }
                        }
                        catch (Exception ex)
                        {
                            while (true)
                            {
                                if (ex.InnerException == null)
                                {
                                    break;
                                }

                                ex = ex.InnerException;
                            }

                            LogFactory.Warn($"下载简历异常! CompanyId:{cookie.Key} 跳过该 Cookie, 异常信息:{ex.Message} 堆栈:{ex.StackTrace}");
                        }
                    }
                }));
            }

            Task.WaitAll(tasks.ToArray());
        }
        /// <summary>
        /// 下载简历
        /// </summary>
        private static void DownloadResume()
        {
            while (true)
            {
                ZhaopinStaff staff;

                if (!staffQueue.TryDequeue(out staff))
                {
                    Thread.Sleep(10 * 1000);

                    continue;
                }

                try
                {
                    if (!dictionary.TryAdd(staff.Id, staff.CompanyId))
                    {
                        continue;
                    }

                    var cookieContainer = staff.Cookie.Serialize(".zhaopin.com");

                    var isWhile = true;

                    if (staff.Source.Contains("5.5"))
                    {
                        #region 网聘 5.5

                        while (isWhile)
                        {
                            var param = new { S_ResumeState = "1", S_CreateDate = $"{DateTime.Now.AddDays(-90):yyMMdd},{DateTime.Now:yyMMdd}", S_feedback = "", page = 1, pageSize = 100 };

                            var requestResult = RequestFactory.QueryRequest("https://rdapi.zhaopin.com/rd/resume/list", JsonConvert.SerializeObject(param), RequestEnum.POST, cookieContainer, contentType: ContentTypeEnum.Json.Description());

                            if (!requestResult.IsSuccess)
                            {
                                Trace.TraceWarning(requestResult.ErrorMsg);

                                continue;
                            }

                            var content = JsonConvert.DeserializeObject <dynamic>(requestResult.Data);

                            if ((int)content.code == 4) // 登录过期
                            {
                                using (var db = new MangningXssDBEntities())
                                {
                                    var zhaopinStaff = db.ZhaopinStaff.FirstOrDefault(f => f.Id == staff.Id);

                                    if (zhaopinStaff != null)
                                    {
                                        zhaopinStaff.Cookie = null;

                                        db.SaveChanges();

                                        dictionary.TryRemove(staff.Id, out companyId);
                                    }
                                }

                                Trace.WriteLine($"{DateTime.Now} > Loging Timeout ! Username = {staff.Username}, Message = {content.message}.");

                                break;
                            }

                            if ((int)content.code != 0)
                            {
                                Trace.WriteLine($"{DateTime.Now} > Get Resume List Error ! Username = {staff.Username}, Message = {content.message}.");

                                continue;
                            }

                            var resumes = content.data.dataList;

                            var unhandled = (int)content.data.total;

                            if (resumes.Count == 0)
                            {
                                break;
                            }

                            HandleResumes(resumes, unhandled, staff, ref isWhile, cookieContainer);
                        }

                        #endregion
                    }
                    else
                    {
                        #region 新系統

                        foreach (var orderFlag in new[] { "deal", "commu", "interview" })

                        {
                            while (isWhile)
                            {
                                var requestResult = GetResumes(cookieContainer, 0, 60, orderFlag);

                                if (!requestResult.IsSuccess)
                                {
                                    Trace.TraceWarning(requestResult.ErrorMsg);

                                    continue;
                                }

                                var content = JsonConvert.DeserializeObject <dynamic>(requestResult.Data);

                                if ((int)content.code == 6001) // 登录过期
                                {
                                    using (var db = new MangningXssDBEntities())
                                    {
                                        var zhaopinStaff = db.ZhaopinStaff.FirstOrDefault(f => f.Id == staff.Id);

                                        if (zhaopinStaff != null)
                                        {
                                            zhaopinStaff.Cookie = null;

                                            db.SaveChanges();

                                            dictionary.TryRemove(staff.Id, out companyId);
                                        }
                                    }

                                    Trace.WriteLine($"{DateTime.Now} > Loging Timeout ! Username = {staff.Username}, Message = {content.message}.");

                                    isWhile = false;

                                    break;
                                }

                                if ((int)content.code != 1)
                                {
                                    Trace.WriteLine($"{DateTime.Now} > Get Resume List Error ! Username = {staff.Username}, Message = {content.message}.");

                                    continue;
                                }

                                var resumes = content.data[orderFlag].results;

                                var unhandled = (int)content.data[orderFlag].numFound;

                                if (resumes.Count == 0)
                                {
                                    break;
                                }

                                HandleResumes(resumes, unhandled, staff, ref isWhile, cookieContainer);
                            }
                        }

                        #endregion
                    }
                }
                catch (Exception ex)
                {
                    Trace.TraceError(ex.ToString());
                }
                finally
                {
                    dictionary.TryRemove(staff.Id, out companyId);
                }
            }
        }
Beispiel #13
0
        /// <summary>
        /// 搜索旧库
        /// </summary>
        /// <param name="list"></param>
        /// <returns></returns>
        public static List <ResumeMatchResult> SearchOldLibrary(IEnumerable <dynamic> list)
        {
            var resumeList = new List <ResumeMatchResult>();

            using (var db = new ResumeMatchDBEntities())
            {
                foreach (var item in list)
                {
                    var resumeNumber = ((string)item.ResumeNumber).Substring(0, 10);

                    var resume = db.OldResumeSummary.FirstOrDefault(w => w.ResumeId == resumeNumber);

                    if (resume == null)
                    {
                        continue;
                    }

                    resume.MatchTime = DateTime.Now;

                    resume.IsMatched = true;

                    resumeList.Add(new ResumeMatchResult
                    {
                        Cellphone    = resume.Cellphone,
                        Email        = resume.Email,
                        ResumeNumber = item.ResumeNumber,
                        Status       = 2
                    });

                    using (var xdb = new MangningXssDBEntities())
                    {
                        var filePath = "X:" + ((string)item.SavePath).Replace("/", "\\");

                        if (!File.Exists(filePath))
                        {
                            LogFactory.Warn($"找不到文件路径:{filePath}, ResumeNumber:{resumeNumber}");

                            continue;
                        }

                        var resumeJson = JsonConvert.DeserializeObject <dynamic>(File.ReadAllText(filePath));

                        var detail = JsonConvert.DeserializeObject(resumeJson.detialJSonStr.ToString());

                        var resumeId = resumeJson.resumeId != null ? (int)resumeJson.resumeId : detail.ResumeId != null ? (int)detail.ResumeId : 0;

                        if (resumeId == 0)
                        {
                            LogFactory.Warn($"解析异常!ResumeId 为空, ResumeNumber:{resumeNumber}");

                            continue;
                        }

                        var userId = (int)resumeJson.userDetials.userMasterId;

                        var user = xdb.ZhaopinUser.FirstOrDefault(f => f.Id == userId);

                        if (user != null)
                        {
                            if (!user.Source.Contains("MANUAL"))
                            {
                                user.Id         = userId;
                                user.Source     = "XSS";
                                user.ModifyTime = BaseFanctory.GetTime((string)detail.DateModified).ToUniversalTime();
                                user.CreateTime = BaseFanctory.GetTime((string)detail.DateCreated).ToUniversalTime();
                                user.Cellphone  = resume.Cellphone;
                                user.Email      = resume.Email;
                                user.Name       = resumeJson.userDetials.userName.ToString();
                                user.UpdateTime = DateTime.UtcNow;
                                user.Username   = resumeJson.userDetials.email.ToString();
                            }
                        }
                        else
                        {
                            xdb.ZhaopinUser.AddOrUpdate(a => a.Id, new ZhaopinUser
                            {
                                Id         = userId,
                                Source     = "XSS",
                                ModifyTime = BaseFanctory.GetTime((string)detail.DateModified).ToUniversalTime(),
                                CreateTime = BaseFanctory.GetTime((string)detail.DateCreated).ToUniversalTime(),
                                Cellphone  = resume.Cellphone,
                                Email      = resume.Email,
                                Name       = resumeJson.userDetials.userName.ToString(),
                                UpdateTime = DateTime.UtcNow,
                                Username   = resumeJson.userDetials.email.ToString()
                            });
                        }

                        var resumeEntity = xdb.ZhaopinResume.FirstOrDefault(f => f.Id == resumeId);

                        if (resumeEntity == null)
                        {
                            xdb.ZhaopinResume.Add(new ZhaopinResume
                            {
                                Id             = resumeId,
                                RandomNumber   = resumeNumber,
                                UserId         = userId,
                                RefreshTime    = BaseFanctory.GetTime((string)detail.DateModified).ToUniversalTime(),
                                UpdateTime     = DateTime.UtcNow,
                                UserExtId      = detail.UserMasterExtId.ToString(),
                                DeliveryNumber = null,
                                Source         = "XSS"
                            });
                        }
                        else
                        {
                            resumeEntity.Id             = resumeId;
                            resumeEntity.RandomNumber   = resumeNumber;
                            resumeEntity.UserId         = userId;
                            resumeEntity.RefreshTime    = BaseFanctory.GetTime((string)detail.DateModified).ToUniversalTime();
                            resumeEntity.UpdateTime     = DateTime.UtcNow;
                            resumeEntity.UserExtId      = detail.UserMasterExtId.ToString();
                            resumeEntity.DeliveryNumber = resumeEntity.DeliveryNumber;
                            resumeEntity.Source         = resumeEntity.Source;
                        }

                        xdb.SaveChanges();

                        var path = $"{ConfigurationManager.AppSettings["Resume.SavePath"]}{DateTime.Now:yyyyMMdd}";

                        if (!Directory.Exists(path))
                        {
                            Directory.CreateDirectory(path);
                        }

                        var resumePath = $@"{path}\{resumeId}.json";

                        File.WriteAllText(resumePath, JsonConvert.SerializeObject(resumeJson));

                        uploadOssActionBlock.Post(resumePath);
                    }
                }

                db.TransactionSaveChanges();
            }

            return(resumeList);
        }
Beispiel #14
0
        /// <summary>
        /// 标记简历
        /// </summary>
        /// <param name="jsonContent"></param>
        /// <param name="resumeId"></param>
        /// <param name="client"></param>
        /// <param name="bucketName"></param>
        /// <returns></returns>
        private static short FlagResume(string jsonContent, int resumeId, IOss client, string bucketName)
        {
            using (var db = new MangningXssDBEntities())
            {
                var resume = db.ZhaopinResume.FirstOrDefault(f => f.Id == resumeId);

                if (resume == null)
                {
                    return(0x0);
                }

                if (jsonContent.Contains("detialJSonStr"))
                {
                    var jsonObj = JsonConvert.DeserializeObject <dynamic>(jsonContent);

                    if (!string.IsNullOrWhiteSpace((string)jsonObj.userDetials.mobilePhone))
                    {
                        resume.Flag = 0xF;
                    }
                    else
                    {
                        var user = db.ZhaopinUser.FirstOrDefault(f => f.Id == resume.UserId && !string.IsNullOrEmpty(f.Cellphone));

                        if (user == null)
                        {
                            resume.Flag = 0xD;
                        }
                        else
                        {
                            jsonObj.userDetials.mobilePhone = user.Cellphone;

                            jsonObj.userDetials.email = user.Email;

                            resume.Flag = 0xF;

                            var jsonResume = JsonConvert.SerializeObject(jsonObj);

                            try
                            {
                                using (var stream = new MemoryStream(GZip.Compress(Encoding.UTF8.GetBytes(jsonResume))))
                                {
                                    client.PutObject(bucketName, $"Zhaopin/Resume/{resumeId}", stream);
                                }

                                //if (resume.Flag != 0xD) File.WriteAllText($@"F:\ZhaopinOss\Resume\{resumeId}", jsonResume);
                            }
                            catch (Exception ex)
                            {
                                Trace.TraceError(ex.ToString());
                            }
                        }
                    }
                }
                else
                {
                    resume.Flag = 0x9;
                }

                db.SaveChanges();

                return(resume.Flag);
            }
        }
        public void Match()
        {
            if (!Directory.Exists(savePath))
            {
                Directory.CreateDirectory(savePath);
            }

            var cookieQueue = new ConcurrentQueue <KeyValuePair <KeyValuePair <int, string>, CookieContainer> >();

            var companyDic = new ConcurrentDictionary <string, int>();

            //using (var db = new MangningXssDBEntities())
            //{
            //    var companyArr = db.ZhaoPinCompany.Where(w => w.Source.Contains("MANUAL")).Select(s => s.Id).ToArray();

            //    var paramArr = db.ZhaopinStaff.Where(w => companyArr.Any(a => a == w.CompanyId) && !string.IsNullOrEmpty(w.Cookie)).Select(s => new { s.CompanyId, s.Username, s.Cookie }).ToArray();

            //    foreach (var item in paramArr)
            //    {
            //        companyDic[item.Username] = 0;

            //        cookieQueue.Enqueue(new KeyValuePair<KeyValuePair<int, string>, CookieContainer>(new KeyValuePair<int, string>(item.CompanyId, item.Username), item.Cookie.Serialize(".zhaopin.com")));
            //    }
            //}

            using (var db = new MangningXssDBEntities())
            {
                var list = db.ZhaopinCleaningProcedure.Where(w => w.IsEnable /* && !w.IsOnline*/ && !string.IsNullOrEmpty(w.Cookie));

                foreach (var item in list)
                {
                    if (item.StartTime < DateTime.Today)
                    {
                        item.TodayWatch = 0;
                    }

                    companyDic[item.Account] = item.TodayWatch;

                    cookieQueue.Enqueue(new KeyValuePair <KeyValuePair <int, string>, CookieContainer>(new KeyValuePair <int, string>(0, item.Account), item.Cookie.Serialize(".zhaopin.com")));

                    item.IsOnline = true;

                    item.StartTime = DateTime.Now;
                }

                db.SaveChanges();
            }

            Console.WriteLine($"已获取 Cookie 数 => {cookieQueue.Count}");

            Task.Run(() =>
            {
                while (true)
                {
                    if (searchQueue.Count > 500)
                    {
                        Thread.Sleep(100);

                        continue;
                    }

                    var list = this.GetOldResumes();

                    foreach (var item in list)
                    {
                        searchQueue.Enqueue(item);
                    }
                }
            });

            for (var j = 0; j < 16; j++)
            {
                Task.Run(() =>
                {
                    try
                    {
                        while (true)
                        {
                            KeyValuePair <KeyValuePair <int, string>, CookieContainer> temp;

                            if (!cookieQueue.TryDequeue(out temp))
                            {
                                Thread.Sleep(1000);

                                Console.WriteLine($"Company => {temp.Key.Value} 找不到可用Cookie!");

                                continue;
                            }

                            while (true)
                            {
                                SearchResumeModel search;

                                if (!searchQueue.TryDequeue(out search))
                                {
                                    Console.WriteLine($"Company => {temp.Key.Value} 找不到可搜索的条件!");

                                    Thread.Sleep(1000);

                                    continue;
                                }

                                var pageIndex = 1;

                                var pageTotal = 1;

                                var total = 0;

                                var isbreak = false;

                                var gender = search.Gender == "男" ? 1 : 2;

                                var isMatched = false;

                                foreach (var company in search.Companys)
                                {
                                    while (pageIndex < pageTotal + 1)
                                    {
                                        var url = $"https://ihrsearch.zhaopin.com/Home/ResultForCustom?SF_1_1_9={gender}&SF_1_1_25=COMPANY_NAME_ALL:{HttpUtility.UrlEncode(company)}&orderBy=BIRTH_YEAR%2C0&SF_1_1_27=0&exclude=1&pageIndex={pageIndex}&pageSize=60";

                                        var requestResult = RequestFactory.QueryRequest(url, cookieContainer: temp.Value, referer: url);

                                        if (!requestResult.IsSuccess)
                                        {
                                            LogFactory.Warn($"Company => {temp.Key.Value} 条件搜索异常!异常原因=>{requestResult.ErrorMsg} Condition=>{JsonConvert.SerializeObject(search)}");

                                            continue;
                                        }

                                        if (pageTotal == 1)
                                        {
                                            var match = Regex.Match(requestResult.Data, "(?s)<span>(\\d+)</span>份简历.+?rd-resumelist-pageNum\">1/(\\d+)</span>");

                                            if (!match.Success)
                                            {
                                                if (requestResult.Data.Contains("text/javascript\" r='m'"))
                                                {
                                                    LogFactory.Warn($"Cookie 过期,过期用户 => {temp.Key.Value}");

                                                    RemoveCookie(temp.Key.Value, companyDic[temp.Key.Value]);
                                                }
                                                else
                                                {
                                                    LogFactory.Warn($"Company => {temp.Key.Value} 条件搜索异常!返回页面解析异常!{requestResult.Data}");
                                                }

                                                isbreak = true;

                                                break;
                                            }

                                            total = Convert.ToInt32(match.Result("$1"));

                                            pageTotal = Convert.ToInt32(match.Result("$2"));

                                            if (total == 0)
                                            {
                                                Console.WriteLine("该条件无搜索结果!");

                                                break;
                                            }
                                        }

                                        Console.WriteLine($"Company => {temp.Key.Value} 第 {pageIndex} 页  共 {pageTotal} 页 {total} 个结果");

                                        if (pageTotal > 1)
                                        {
                                            break;
                                        }

                                        pageIndex++;

                                        var matchs = Regex.Matches(requestResult.Data, "(?s)RedirectToRd/([^\r\n]+?)','([^\r\n]+?)','([^\r\n]+?)',this\\);this.+?(\\d{2}-\\d{2}-\\d{2})");

                                        var index = 0;

                                        foreach (Match item in matchs)
                                        {
                                            var number = item.Result("$1").Substring(0, 10);

                                            var numberParam = item.Result("$1").Substring(0, item.Result("$1").IndexOf("?", StringComparison.Ordinal));

                                            var cache = GetResumeOfCache(number);

                                            if (cache == null)
                                            {
                                                DateTime updateDateTime;

                                                if (DateTime.TryParse(item.Result("$4"), out updateDateTime))
                                                {
                                                    QueryResumeIsExists(number, updateDateTime);
                                                }

                                                requestResult = RequestFactory.QueryRequest($"http://ihr.zhaopin.com/resumesearch/getresumedetial.do?resumeNo={numberParam}&searchresume=1&resumeSource=1&keyword=%E8%AF%B7%E8%BE%93%E5%85%A5%E7%AE%80%E5%8E%86%E5%85%B3%E9%94%AE%E8%AF%8D%EF%BC%8C%E5%A4%9A%E5%85%B3%E9%94%AE%E8%AF%8D%E5%8F%AF%E7%94%A8%E7%A9%BA%E6%A0%BC%E5%88%86%E9%9A%94&t={item.Result("$2")}&k={item.Result("$3")}&v=undefined&version=3&openFrom=1", cookieContainer: temp.Value);

                                                if (!requestResult.IsSuccess)
                                                {
                                                    LogFactory.Warn($"Company => {temp.Key.Value} 简历详情查看异常!异常原因=>{requestResult.ErrorMsg} ResumeNumber=>{number}");

                                                    continue;
                                                }

                                                try
                                                {
                                                    var jsonObj = JsonConvert.DeserializeObject <dynamic>(requestResult.Data);

                                                    if ((int)jsonObj["code"] != 1)
                                                    {
                                                        LogFactory.Warn($"Company => {temp.Key.Value} ResumeNumber => {number} 查看详情异常 信息:{(string)jsonObj["message"]} 查看简历份数:{companyDic[temp.Key.Value]}");

                                                        if (((string)jsonObj["message"]).Contains("当日查看简历已达上限"))
                                                        {
                                                            RemoveCookie(temp.Key.Value, companyDic[temp.Key.Value]);

                                                            isbreak = true;

                                                            break;
                                                        }

                                                        continue;
                                                    }

                                                    var resumeData = jsonObj.data;

                                                    var userId = (string)resumeData.userDetials.userMasterId;

                                                    if (search.SearchResumeId.Substring(2, 8) == (userId.Length == 8 ? userId : userId.Substring(1)))
                                                    {
                                                        Console.WriteLine($"匹配简历成功!ResumeNumber=>{number} 今日匹配成功数=> {++totalMatched}");

                                                        resumeData.userDetials.mobilePhone = search.Cellphone;

                                                        resumeData.userDetials.email = search.Email;

                                                        isMatched = true;
                                                    }

                                                    SaveCacheByOss(new KeyValuePair <KeyValuePair <int, string>, dynamic>(temp.Key, resumeData));

                                                    Console.WriteLine($"Company => {temp.Key.Value} 查看简历成功!查看简历份数:{++companyDic[temp.Key.Value]} ResumeNumber => {number} {++index}/{matchs.Count}");

                                                    if (isMatched)
                                                    {
                                                        break;
                                                    }
                                                }
                                                catch (Exception ex)
                                                {
                                                    while (true)
                                                    {
                                                        if (ex.InnerException == null)
                                                        {
                                                            break;
                                                        }

                                                        ex = ex.InnerException;
                                                    }

                                                    LogFactory.Error($"保存简历信息异常!异常信息:{ex.Message} 响应信息:{requestResult.Data}");
                                                }
                                            }
                                            else
                                            {
                                                var userId = cache.UserId.ToString();

                                                if (search.SearchResumeId.Substring(2, 8) == (userId.Length == 8 ? userId : userId.Substring(1)))
                                                {
                                                    Console.WriteLine($"匹配简历成功!ResumeNumber=>{number} 今日匹配成功数=> {++totalMatched}");

                                                    using (var xdb = new MangningXssDBEntities())
                                                    {
                                                        var model = xdb.ZhaopinMatchedCache.FirstOrDefault(f => f.ResumeId == cache.ResumeId);

                                                        if (model != null)
                                                        {
                                                            model.Cellphone = search.Cellphone;

                                                            model.Email = search.Email;

                                                            xdb.SaveChanges();
                                                        }
                                                    }

                                                    isMatched = true;

                                                    break;
                                                }
                                            }
                                        }

                                        if (isbreak || isMatched)
                                        {
                                            break;
                                        }
                                    }

                                    if (isbreak || isMatched)
                                    {
                                        break;
                                    }
                                }

                                ChangeResumeStatus(search.SearchResumeId, isMatched);

                                if (isbreak)
                                {
                                    break;
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        while (true)
                        {
                            if (ex.InnerException == null)
                            {
                                break;
                            }

                            ex = ex.InnerException;
                        }

                        LogFactory.Error($"Watch异常!异常信息:{ex.Message}  {ex.StackTrace}");
                    }
                });
            }
        }
        /// <summary>
        /// 下载
        /// </summary>
        /// <param name="cookieContainer"></param>
        /// <param name="jobNumber"></param>
        /// <param name="number"></param>
        /// <param name="refreshTime"></param>
        /// <param name="orderFlag"></param>
        /// <param name="deliveryId"></param>
        /// <param name="companyId"></param>
        /// <param name="token"></param>
        private static void Down(CookieContainer cookieContainer, string jobNumber, string number, DateTime refreshTime, string orderFlag, long deliveryId, int companyId, string token)
        {
            var resumeId = 0;

            var url = orderFlag == "recycle" ? $"http://ihr.zhaopin.com/resumesearch/getresumedetial.do?access_token={token}&resumeJobId={deliveryId}" : $"http://ihr.zhaopin.com/resumesearch/getresumedetial.do?resumeNo={deliveryId}_{jobNumber}_{number}_1_1&resumeSource=3";

            try
            {
                var requestResult = RequestFactory.QueryRequest(url, cookieContainer: cookieContainer);

                if (!requestResult.IsSuccess)
                {
                    LogFactory.Warn($"简历信息下载异常!异常信息:{requestResult.ErrorMsg},CompanyId:{companyId},jobNumber:{jobNumber}, ResumeNumber:{number} ");

                    return;
                }

                var resume = JsonConvert.DeserializeObject <dynamic>(requestResult.Data);

                if ((int)resume.code != 1)
                {
                    LogFactory.Warn($"简历信息下载异常!message:{resume.message},CompanyId:{companyId},jobNumber:{jobNumber}, ResumeNumber:{number} ");

                    if ((int)resume.code == 6001)
                    {
                        while (true)
                        {
                            Tuple <CookieContainer, string, string, DateTime, string, long, int, Tuple <string> > param;

                            if (!downQueue.TryDequeue(out param))
                            {
                                break;
                            }

                            if (param.Item7 != companyId)
                            {
                                downQueue.Enqueue(param);
                            }
                        }

                        return; // 登录过期
                    }

                    return;
                }

                Thread.Sleep(1000);

                if (resume.data == null)
                {
                    return;
                }

                var detail = JsonConvert.DeserializeObject(resume.data.detialJSonStr.ToString());

                resume.data.detialJSonStr = detail;

                var path = $"{ConfigurationManager.AppSettings["Resume.SavePath"]}";

                if (!Directory.Exists(path))
                {
                    Directory.CreateDirectory(path);
                }

                resumeId = (int)resume.data.resumeId;

                using (var db = new MangningXssDBEntities())
                {
                    if (db.ZhaopinDelivery.Any(a => a.Id == deliveryId))
                    {
                        Console.WriteLine($"DeliveryId:{deliveryId} 已下载过!");

                        return;
                    }

                    db.ZhaopinDelivery.Add(new ZhaopinDelivery
                    {
                        CompanyId    = companyId,
                        Id           = deliveryId,
                        ResumeId     = resumeId,
                        JobNumber    = jobNumber,
                        ResumeNumber = number
                    });

                    if (!db.ZhaopinDeliveryLog.Any(a => a.DeliveryId == deliveryId))
                    {
                        db.ZhaopinDeliveryLog.Add(new ZhaopinDeliveryLog
                        {
                            DeliveryId = deliveryId,
                            CompanyId  = companyId
                        });
                    }

                    db.TransactionSaveChanges();

                    if (db.ZhaopinResume.Any(a => a.Id == resumeId && a.RefreshTime >= refreshTime && a.Flag != 2))
                    {
                        var resumeNumber = number.Substring(0, 10);

                        Console.WriteLine($"简历已下载过!ResumeNumber:{resumeNumber}");

                        return;
                    }
                }

                if (!resumeDic.TryAdd(resumeId, resumeId))
                {
                    return;
                }

                var resumePath = $@"{path}\{resumeId}.json";

                File.WriteAllText(resumePath, JsonConvert.SerializeObject(resume.data));

                uploadOssActionBlock.Post(resumePath);

                var userId = (int)resume.data.userDetials.userMasterId;

                using (var db = new MangningXssDBEntities())
                {
                    var user = db.ZhaopinUser.FirstOrDefault(f => f.Id == userId);

                    if (user != null)
                    {
                        if (!user.Source.Contains("MANUAL"))
                        {
                            user.Id         = userId;
                            user.Source     = "XSS";
                            user.ModifyTime = BaseFanctory.GetTime((string)detail.DateModified).ToUniversalTime();
                            user.CreateTime = BaseFanctory.GetTime((string)detail.DateCreated).ToUniversalTime();
                            user.Cellphone  = resume.data.userDetials.mobilePhone.ToString();
                            user.Email      = resume.data.userDetials.email.ToString();
                            user.Name       = resume.data.userDetials.userName.ToString();
                            user.UpdateTime = DateTime.UtcNow;
                            user.Username   = resume.data.userDetials.email.ToString();
                        }
                    }
                    else
                    {
                        db.ZhaopinUser.AddOrUpdate(a => a.Id, new ZhaopinUser
                        {
                            Id         = userId,
                            Source     = "XSS",
                            ModifyTime = BaseFanctory.GetTime((string)detail.DateModified).ToUniversalTime(),
                            CreateTime = BaseFanctory.GetTime((string)detail.DateCreated).ToUniversalTime(),
                            Cellphone  = resume.data.userDetials.mobilePhone.ToString(),
                            Email      = resume.data.userDetials.email.ToString(),
                            Name       = resume.data.userDetials.userName.ToString(),
                            UpdateTime = DateTime.UtcNow,
                            Username   = resume.data.userDetials.email.ToString()
                        });
                    }

                    var resumeEntity = db.ZhaopinResume.FirstOrDefault(f => f.Id == resumeId);

                    var userExdId = Regex.IsMatch(detail.UserMasterExtId.ToString(), @"^J[MRSL]\d{9}$") ? detail.UserMasterExtId.ToString() : string.Empty;

                    if (resumeEntity == null)
                    {
                        db.ZhaopinResume.Add(new ZhaopinResume
                        {
                            Id             = resumeId,
                            RandomNumber   = number.Substring(0, 10),
                            UserId         = userId,
                            RefreshTime    = BaseFanctory.GetTime((string)detail.DateModified).ToUniversalTime(),
                            UpdateTime     = DateTime.UtcNow,
                            UserExtId      = userExdId,
                            DeliveryNumber = null,
                            Source         = "XSS,Deliver",
                            Flag           = 0xE
                        });
                    }
                    else
                    {
                        resumeEntity.RandomNumber = number.Substring(0, 10);
                        resumeEntity.UserId       = userId;
                        resumeEntity.RefreshTime  = BaseFanctory.GetTime((string)detail.DateModified).ToUniversalTime();
                        resumeEntity.UpdateTime   = DateTime.UtcNow;
                        if (string.IsNullOrEmpty(resumeEntity.UserExtId))
                        {
                            resumeEntity.UserExtId = userExdId;
                        }
                        resumeEntity.DeliveryNumber = resumeEntity.DeliveryNumber;
                        resumeEntity.Source         = !resumeEntity.Source.Contains("Deliver") ? resumeEntity.Source += ",Deliver" : resumeEntity.Source;
                        resumeEntity.Flag           = 0xE;
                        if (resumeEntity.IncludeTime == null)
                        {
                            resumeEntity.IncludeTime = DateTime.UtcNow;
                        }
                    }

                    db.SaveChanges();
                }

                Interlocked.Increment(ref downloadCount);

                resumeDic.TryRemove(resumeId, out resumeId);

                Console.WriteLine($"下载成功!{downloadCount}/{downQueue.Count} CId:{companyId} RId:{resumeId} DId:{deliveryId} orderFlag:{orderFlag} oss:{uploadOssActionBlock.InputCount}");
            }
            catch (Exception ex)
            {
                while (true)
                {
                    if (ex.InnerException == null)
                    {
                        break;
                    }

                    ex = ex.InnerException;
                }

                LogFactory.Warn($"下载简历异常!异常信息:{ex.Message} 堆栈:{ex.StackTrace} CompanyId:{companyId},ResumeId:{resumeId}, orderFlag:{orderFlag}");
            }
        }
        public void MatchResume()
        {
            const string path = @"D:\待清理数据\2017-11-24  智联招聘简历导出";

            var filesPath = Directory.EnumerateFileSystemEntries(path);

            var dictionary = new ConcurrentDictionary <string, string>();

            var index = 0;

            var queue = new ConcurrentQueue <string>();

            foreach (var filePath in filesPath)
            {
                queue.Enqueue(filePath);
            }

            for (var i = 0; i < 8; i++)
            {
                Task.Run(() =>
                {
                    while (true)
                    {
                        string filePath;

                        if (!queue.TryDequeue(out filePath))
                        {
                            continue;
                        }

                        Interlocked.Increment(ref index);

                        var htmlSource = File.ReadAllText(filePath);

                        var numberMatchResult = Regex.Match(htmlSource, "tips-id\">ID:(\\S{10})");

                        if (!numberMatchResult.Success)
                        {
                            LogFactory.Warn("简历编号匹配失败!Path:" + filePath);

                            continue;
                        }

                        var mobileMatchResult = Regex.Match(htmlSource, "main-title-fr\">(Mobile|手机) :.*?(\\d{11})");

                        if (!mobileMatchResult.Success)
                        {
                            LogFactory.Warn("手机号码匹配失败!Path:" + filePath);

                            continue;
                        }

                        var resumeNumber = numberMatchResult.Result("$1").Trim().Substring(0, 10);

                        var mobile = mobileMatchResult.Result("$2");

                        using (var db = new MangningXssDBEntities())
                        {
                            if (db.ZhaopinResume.Any(a => a.RandomNumber.StartsWith(resumeNumber)))
                            {
                                dictionary.TryAdd(resumeNumber, mobile);

                                continue;
                            }

                            if (db.ZhaopinUser.Any(a => a.Cellphone == mobile))
                            {
                                dictionary.TryAdd(resumeNumber, mobile);

                                continue;
                            }
                        }

                        using (var db = new BadoucaiAliyunDBEntities())
                        {
                            if (db.CoreResumeReferenceMapping.Any(a => a.Value.StartsWith(resumeNumber)))
                            {
                                dictionary.TryAdd(resumeNumber, mobile);

                                continue;
                            }

                            if (db.CoreResumeSummary.Any(a => a.Cellphone.ToString() == mobile))
                            {
                                dictionary.TryAdd(resumeNumber, mobile);
                            }
                        }
                    }
                });
            }

            SpinWait.SpinUntil(() => false);
        }
        /// <summary>
        /// 获取 Cookie 相关信息
        /// </summary>
        /// <returns></returns>
        public Dictionary <int, string> GetCookies()
        {
            dictionary.Clear();

            var cookieList = new Dictionary <int, string>();

            var cookieStaffList = new List <ZhaopinStaff>();

            using (var db = new MangningXssDBEntities())
            {
                while (true)
                {
                    try
                    {
                        var pageIndex = 0;

                        while (true)
                        {
                            //var list = db.ZhaopinStaff.Where(w => !string.IsNullOrEmpty(w.Cookie)).OrderByDescending(o => o.Id).Skip(pageIndex * 500).Take(500).ToList();

                            var companyArr = db.ZhaoPinCompany.Where(w => w.Source.Contains("MANUAL")).Select(s => s.Id).ToArray();

                            var list = db.ZhaopinStaff.Where(w => companyArr.Any(a => a == w.CompanyId) && !string.IsNullOrEmpty(w.Cookie)).OrderByDescending(o => o.Id).Skip(pageIndex * 500).Take(500).ToList();

                            if (!list.Any())
                            {
                                break;
                            }

                            cookieStaffList.AddRange(list);

                            pageIndex++;
                        }

                        cookieStaffList = cookieStaffList.Distinct().ToList();

                        break;
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine($"获取 Cookie 异常!{ex.Message} 准备重试...");
                    }
                }
            }

            foreach (var cookie in cookieStaffList)
            {
                if (dictionary.ContainsKey(cookie.Id))
                {
                    if (cookie.UpdateTime?.Subtract(dictionary[cookie.Id]).TotalMinutes < 30)
                    {
                        continue;
                    }

                    dictionary[cookie.Id] = cookie.UpdateTime ?? DateTime.Now;
                }
                else
                {
                    dictionary.Add(cookie.Id, cookie.UpdateTime ?? DateTime.Now);
                }

                cookieList.Add(cookie.CompanyId, cookie.Cookie);
            }

            Console.WriteLine($"获取 Cookie 完成,共 {cookieStaffList.Count} 个,{cookieList.Count} 个待爬取!");

            return(cookieList);
        }
        /// <summary>
        /// 处理简历
        /// </summary>
        /// <param name="item"></param>
        /// <param name="cellphone"></param>
        /// <param name="email"></param>
        /// <param name="cleaningProcedure"></param>
        /// <param name="businessId"></param>
        private static void HandleResume(Match item, string cellphone, string email, ZhaopinCleaningProcedure cleaningProcedure, int businessId)
        {
            var number = item.Result("$1").Substring(0, 10);

            DateTime updateDateTime;

            if (!DateTime.TryParse(item.Result("$4"), out updateDateTime))
            {
                return;
            }

            using (var db = new MangningXssDBEntities())
            {
                var resume = db.ZhaopinResume.FirstOrDefault(f => f.RandomNumber == number);

                if (resume != null)
                {
                    if (resume.Flag == 15)
                    {
                        #region 刷新简历更新时间

                        //if (resume.RefreshTime != null && updateDateTime.Date == resume.RefreshTime.Value.Date) continue;

                        resume.RefreshTime = updateDateTime;

                        resume.Flag = 14;

                        var filePath = $@"D:\Badoucai\Resume\LocationJson\{resume.Id}.json";

                        using (var stream = new MemoryStream())
                        {
                            if (!mangningOssClient.DoesObjectExist(mangningBucketName, $"Zhaopin/Resume/{resume.Id}"))
                            {
                                return;
                            }

                            var bytes = new byte[1024];

                            int len;

                            var streamContent = mangningOssClient.GetObject(mangningBucketName, $"Zhaopin/Resume/{resume.Id}").Content;

                            while ((len = streamContent.Read(bytes, 0, bytes.Length)) > 0)
                            {
                                stream.Write(bytes, 0, len);
                            }

                            var resumeContent = Encoding.UTF8.GetString(GZip.Decompress(stream.ToArray()));

                            var jsonObj = JsonConvert.DeserializeObject <dynamic>(resumeContent);

                            dynamic detialJSonStr;

                            try
                            {
                                detialJSonStr = jsonObj.detialJSonStr;

                                if (!string.IsNullOrEmpty((string)jsonObj.detialJSonStr.DateModified))
                                {
                                    jsonObj.detialJSonStr = JsonConvert.SerializeObject(jsonObj.detialJSonStr);
                                }
                            }
                            catch (Exception)
                            {
                                detialJSonStr = JsonConvert.DeserializeObject <dynamic>((string)jsonObj.detialJSonStr);
                            }

                            detialJSonStr.DateLastReleased = updateDateTime;

                            detialJSonStr.DateModified = updateDateTime;

                            jsonObj.detialJSonStr = detialJSonStr;

                            var newResumeContent = JsonConvert.SerializeObject(jsonObj);

                            using (var jsonStream = new MemoryStream(GZip.Compress(Encoding.UTF8.GetBytes(newResumeContent))))
                            {
                                mangningOssClient.PutObject(mangningBucketName, $"Zhaopin/Resume/{resume.Id}", jsonStream);
                            }

                            File.WriteAllText(filePath, newResumeContent);
                        }

                        #endregion
                    }

                    if (resume.Flag == 2)
                    {
                        var user = db.ZhaopinUser.FirstOrDefault(f => f.Id == resume.UserId);

                        if (user == null)
                        {
                            return;
                        }

                        if (!WatchResumeDetail(item, cookieContainer, user.Cellphone, user.Email, businessId))
                        {
                            var procedure = db.ZhaopinCleaningProcedure.FirstOrDefault(f => f.Id == cleaningProcedure.Id);

                            if (procedure != null)
                            {
                                procedure.Cookie = null;

                                db.SaveChanges();
                            }

                            businessIdQueue.Enqueue(businessId);
                        }
                    }
                }
                else
                {
                    var incompleteResume = db.ZhaopinIncompleteResume.FirstOrDefault(f => f.ResumeNumber == number);

                    if (incompleteResume != null)
                    {
                        incompleteResume.CompletionTime = DateTime.Now;
                    }

                    WatchResumeDetail(item, cookieContainer, cellphone, email, businessId);
                }

                db.SaveChanges();
            }
        }
Beispiel #20
0
        /// <summary>
        /// 投递简历
        /// </summary>
        private static void DeilverTask()
        {
            var userResumeQueue = new Queue <Tuple <dynamic, int> >();

            var positionQueue = new Queue <dynamic>();

            #region 填充用户简历及职位队列

            using (var db = new MangningXssDBEntities())
            {
                var date = DateTime.Now.Date.AddHours(-8);

                var userResumeRecordList = db.ZhaopinDeilveryRecord.AsNoTracking().Where(w => w.CreateTime > date).GroupBy(g => g.UserId).Select(s => s.Key).ToList();

                if (userResumeRecordList.Any())
                {
                    var userResumes = db.ZhaopinResume
                                      .Join(db.ZhaopinUser.Where(w => userResumeRecordList.Any(a => a == w.Id) && !string.IsNullOrEmpty(w.Cookie) && w.Source.Contains("MANUAL") && string.IsNullOrEmpty(w.Status)), a => a.UserId, b => b.Id, (a, b) => new { b.Username, a.UserId, ResumeNumber = a.DeliveryNumber, b.Cookie })
                                      .ToList();
                    foreach (var user in userResumes)
                    {
                        if (userResumeQueue.Count >= deilverUserCount)
                        {
                            break;
                        }

                        var todayDeilverCount = db.ZhaopinDeilveryRecord.Count(w => w.UserId == user.UserId && w.CreateTime > date);

                        //if (string.IsNullOrEmpty(user.Cookie))
                        //{
                        //    LogFactory.Warn($"投递用户:{user.Username} Cookie 已过期!请录入有效 Cookie !");

                        //    return;
                        //}

                        userResumeQueue.Enqueue(new Tuple <dynamic, int>(user, todayDeilverCount));
                    }
                }

                if (userResumeQueue.Count < deilverUserCount)
                {
                    var userResumeList = db.ZhaopinResume
                                         .Join(db.ZhaopinUser.Where(w => userResumeRecordList.All(a => a != w.Id) && !string.IsNullOrEmpty(w.Cookie) && w.Source.Contains("MANUAL") && string.IsNullOrEmpty(w.Status)), a => a.UserId, b => b.Id, (a, b) => new { b.Username, a.UserId, ResumeNumber = a.DeliveryNumber, b.Cookie })
                                         .ToList();

                    foreach (var f in userResumeList)
                    {
                        var todayDeilverCount = db.ZhaopinDeilveryRecord.Count(w => w.UserId == f.UserId && w.CreateTime > date);

                        if (todayDeilverCount < singleUserDeilverCount)
                        {
                            if (userResumeQueue.Count >= deilverUserCount)
                            {
                                break;
                            }

                            int code;

                            if (CheckUserIsUseable(f, out code))
                            {
                                userResumeQueue.Enqueue(new Tuple <dynamic, int>(f, todayDeilverCount));
                            }
                            else
                            {
                                var user = db.ZhaopinUser.FirstOrDefault(df => df.Id == f.UserId);

                                if (user != null)
                                {
                                    user.Status = "BLOCKED";

                                    if (code == -1)
                                    {
                                        user.Status = "ABNORMAL";
                                    }

                                    user.UpdateTime = DateTime.UtcNow;

                                    db.SaveChanges();
                                }
                            }
                        }
                    }
                }

                if (!userResumeQueue.Any())
                {
                    Console.WriteLine("等待可用用户中....");

                    return;
                }

                if (userResumeQueue.All(a => a.Item2 >= singleUserDeilverCount))
                {
                    var todayCount = db.ZhaopinDeilveryRecord.AsNoTracking().Count(c => c.CreateTime > date);

                    if (todayCount < singleUserDeilverCount * deilverUserCount)
                    {
                        Console.WriteLine("等待可用用户中....");

                        return;
                    }

                    Console.WriteLine("今日投递任务已完成....");

                    return;
                }

                var positionList = db.ZhaopinDeilverTask
                                   .Where(w => w.Status == 0)
                                   .Join(db.ZhaopinPosition, a => a.CompanyId, b => b.CompanyId, (a, b) => new { TaskId = a.Id, a.CompanyId, PositionId = b.Id, b.Number, b.CreateTime, b.IsEnable, b.Name })
                                   .OrderByDescending(o => o.CreateTime)
                                   .ToList();

                var deilverTaskList = db.ZhaopinDeilverTask.Where(w => w.Status == 0).OrderBy(o => o.Priority).ToList();

                date = DateTime.UtcNow.AddDays(-7);

                foreach (var f in deilverTaskList)
                {
                    var positions = positionList
                                    .Where(w => w.TaskId == f.Id && w.IsEnable && w.CreateTime > date)
                                    .OrderByDescending(o => o.CreateTime)
                                    .Skip(f.ActualDeilverCount)
                                    .Take(f.ExpectedDeilverCount - f.ActualDeilverCount)
                                    .ToList();

                    if (!positions.Any())
                    {
                        f.Status = 2;

                        f.CompleteTime = DateTime.UtcNow;

                        continue;
                    }

                    positions = positions.Take(f.ExpectedDeilverCount - f.ActualDeilverCount).ToList();

                    positions.ForEach(pf =>
                    {
                        positionQueue.Enqueue(pf);
                    });
                }

                db.TransactionSaveChanges();
            }

            if (!positionQueue.Any())
            {
                Console.WriteLine("等待分配任务中....");

                return;
            }

            #endregion

            while (true)
            {
                if (!positionQueue.Any())
                {
                    return;
                }

                var position = positionQueue.Dequeue();

                if (!userResumeQueue.Any())
                {
                    return;
                }

                var userResume = userResumeQueue.Dequeue();

                #region 投递简历

                var userDeilverNumber = 0;

                do
                {
                    var deilverResult = RequestFactory.QueryRequest($"https://my.zhaopin.com/v5/FastApply/resumeinfo.aspx?t=3&j={position.Number}&j2=&so=&su=&ff=ssb&rv={userResume.Item1.ResumeNumber}_1&rl=1&cl=&sd=0&fd=&c=jsonp7u3t5v&_=1493174565322", cookieContainer: ((string)userResume.Item1.Cookie).Serialize("zhaopin.com"));

                    if (!deilverResult.IsSuccess)
                    {
                        LogFactory.Warn($"投递简历请求异常!简历编号:{userResume.Item1.ResumeNumber},职位编号:{position.Number},异常信息:{deilverResult.ErrorMsg}");

                        continue;
                    }

                    var message = JsonConvert.DeserializeObject <dynamic>(Regex.Match(deilverResult.Data, @"(\{.+?\})").Result("$1"));

                    if (message.loginstatus.ToString().Contains("7_Position"))
                    {
                        LogFactory.Warn($"该职位已下架!职位编号:{position.Number} Json:{JsonConvert.SerializeObject(message)}");

                        using (var db = new MangningXssDBEntities())
                        {
                            var positionId = (int)position.PositionId;

                            var positionDefault = db.ZhaopinPosition.FirstOrDefault(f => f.Id == positionId);

                            if (positionDefault != null)
                            {
                                positionDefault.IsEnable = false;
                            }
                            else
                            {
                                LogFactory.Warn("数据库未找到对应的职位!职位ID:" + positionId);
                            }

                            db.TransactionSaveChanges();
                        }

                        if (!positionQueue.Any())
                        {
                            return;
                        }

                        position = positionQueue.Dequeue();

                        continue;
                    }

                    if (message.loginstatus.ToString() != "6")
                    {
                        LogFactory.Warn($"用户登录 Cookie 失效!用户ID:{userResume.Item1.UserId} Json:{JsonConvert.SerializeObject(message)}");

                        using (var db = new MangningXssDBEntities())
                        {
                            var userId = (int)userResume.Item1.UserId;

                            var user = db.ZhaopinUser.FirstOrDefault(f => f.Id == userId);

                            if (user != null)
                            {
                                user.Cookie = "";

                                user.UpdateTime = DateTime.UtcNow;
                            }
                            else
                            {
                                LogFactory.Warn("数据库未找到对应的用户!用户ID:" + userId);
                            }

                            //db.TransactionSaveChanges();
                        }

                        if (!userResumeQueue.Any())
                        {
                            return;
                        }

                        userResume = userResumeQueue.Dequeue();

                        continue;
                    }

                    var status = message.postBackInfo.ToString().Split('_');

                    if (status[3].ToString() == "0")
                    {
                        if (status[0] == "0" && status[1] == "0" && status[2] == "0")
                        {
                            using (var db = new MangningXssDBEntities())
                            {
                                var userId = (int)userResume.Item1.UserId;

                                var user = db.ZhaopinUser.FirstOrDefault(f => f.Id == userId);

                                if (user != null)
                                {
                                    user.Status = "PENDING";

                                    user.UpdateTime = DateTime.UtcNow;

                                    db.TransactionSaveChanges();
                                }
                            }

                            LogFactory.Warn($"该帐号已不能继续投递!用户ID:{userResume.Item1.UserId}");

                            if (!userResumeQueue.Any())
                            {
                                return;
                            }

                            userResume = userResumeQueue.Dequeue();

                            continue;
                        }

                        LogFactory.Warn($"七天内已投递过该职位!用户ID:{userResume.Item1.UserId},职位编号:{position.Number},职位名称:{position.Name}");

                        if (userDeilverNumber < userResumeQueue.Count)
                        {
                            userResumeQueue.Enqueue(userResume);

                            userDeilverNumber++;

                            userResume = userResumeQueue.Dequeue();

                            continue;
                        }

                        if (!positionQueue.Any())
                        {
                            return;
                        }

                        position = positionQueue.Dequeue();

                        userDeilverNumber = 0;

                        continue;
                    }

                    var deilverCount = userResume.Item2;

                    if (++deilverCount < singleUserDeilverCount)
                    {
                        userResumeQueue.Enqueue(new Tuple <dynamic, int>(userResume.Item1, deilverCount));
                    }

                    break;
                }while (true);

                #endregion

                #region 变更任务状态及添加投递记录

                using (var db = new MangningXssDBEntities())
                {
                    var taskId = (int)position.TaskId;

                    var deilverTask = db.ZhaopinDeilverTask.FirstOrDefault(f => f.Id == taskId);

                    if (deilverTask != null)
                    {
                        deilverTask.ActualDeilverCount += 1;

                        if (deilverTask.ActualDeilverCount == deilverTask.ExpectedDeilverCount)
                        {
                            deilverTask.Status = 1;

                            deilverTask.CompleteTime = DateTime.UtcNow;
                        }
                    }
                    else
                    {
                        LogFactory.Warn("数据库未找到对应的任务!任务ID:" + taskId);
                    }

                    db.ZhaopinDeilveryRecord.Add(new ZhaopinDeilveryRecord
                    {
                        CompanyId  = position.CompanyId,
                        PositionId = position.PositionId,
                        UserId     = userResume.Item1.UserId,
                        CreateTime = DateTime.UtcNow
                    });

                    db.TransactionSaveChanges();
                }

                #endregion

                LogFactory.Info($"投递成功!用户:{userResume.Item1.Username} 今日投递数:{userResume.Item2 + 1} 职位:{position.Name} 还剩 {positionQueue.Count} 个职位待投递");

                if (userResumeQueue.Count != 0)
                {
                    Thread.Sleep(1000 * 5 / userResumeQueue.Count);
                }
            }
        }
Beispiel #21
0
        /// <summary>
        /// 下载投递简历列表
        /// </summary>
        /// <param name="path"></param>
        /// <param name="cookieStr"></param>
        public void DownOldSystemResumeDetail(string path, string cookieStr)
        {
            var count = 0;

            while (true)
            {
                var requestResult = RequestFactory.QueryRequest("https://rd2.zhaopin.com/rdapply/resumes/apply/search?SF_1_1_38=7,9&orderBy=CreateTime", "PageList2=&DColumn_hidden=&searchKeyword=&curSubmitRecord=1586&curMaxPageNum=80&PageList2=1&buttonAsse=%E5%AF%BC%E5%85%A5%E6%B5%8B%E8%AF%84%E7%B3%BB%E7%BB%9F&buttonInfo=%E5%8F%91%E9%80%9A%E7%9F%A5%E4%BF%A1&SF_1_1_50=1&SF_1_1_51=-1&SF_1_1_45=&SF_1_1_44=&SF_1_1_52=0&SF_1_1_49=0&IsInvited=0&position_city=%5B%25%25POSITION_CITY%25%25%5D&deptName=&select_unique_id=&selectedResumeList=&PageNo=&PosState=&MinRowID=&MaxRowID=2722819791&RowsCount=123&PagesCount=5&PageType=0&CurrentPageNum=1&Position_IDs=%5B%25%25POSITION_IDS%25%25%5D&Position_ID=%5B%25%25POSITION_ID%25%25%5D&SortType=0&isCmpSum=0&SelectIndex_Opt=0&Resume_count=0&CID=56211453&forwardingEmailList=&click_search_op_type=-1&X-Requested-With=XMLHttpRequest", RequestEnum.POST, _cookieContainer);

                if (!requestResult.IsSuccess)
                {
                    this.AsyncSetLog(this.tbx_Log, "请求异常!异常原因:" + requestResult.ErrorMsg);

                    return;
                }

                var matches = Regex.Matches(requestResult.Data, "(?s)javascript:ViewOneResume.+?'(\\d+)'\\);\" href=\"(.+?)\".+?>(.+?)</a.+?<td title=\"(.+?)\"");

                if (requestResult.Data.Contains("因请求量过大导致系统无法处理您的请求,您需要通过验证才能继续后续的操作!"))
                {
                    this.AsyncSetLog(this.tbx_Log, "搜索简历列表失败!出现验证码!");

                    using (var db = new MangningXssDBEntities())
                    {
                        if (!db.ZhaopinCheckCode.Any(a => a.Account == companyName && (a.Status == 0 || a.Status == 1)))
                        {
                            db.ZhaopinCheckCode.Add(new ZhaopinCheckCode
                            {
                                Account    = companyName,
                                Cookie     = cookieStr,
                                CreateTime = DateTime.Now,
                                Status     = 0,
                                Type       = 1
                            });

                            db.SaveChanges();
                        }
                    }

                    Thread.Sleep(retryInterval);

                    continue;
                }

                if (matches.Count == 0)
                {
                    Thread.Sleep(10 * 1000);

                    continue;
                }

                var ids = string.Empty;

                foreach (Match match in matches)
                {
                    try
                    {
                        var filePath = $"{path}\\{match.Result("$3").Replace("\\", "").Replace("/", "")}_{DateTime.Parse(match.Result("$4")):yyyy-MM-dd HH:mm:ss}.txt";

                        while (true)
                        {
                            requestResult = RequestFactory.QueryRequest($"https:{match.Result("$2")}", cookieContainer: _cookieContainer);

                            if (!requestResult.IsSuccess)
                            {
                                this.AsyncSetLog(this.tbx_Log, "请求异常!异常原因:" + requestResult.ErrorMsg);

                                return;
                            }

                            if (requestResult.Data.Contains("因请求量过大导致系统无法处理您的请求,您需要通过验证才能继续后续的操作!"))
                            {
                                this.AsyncSetLog(this.tbx_Log, "查看简历详情失败!出现验证码!");

                                using (var db = new MangningXssDBEntities())
                                {
                                    if (!db.ZhaopinCheckCode.Any(a => a.Account == companyName && (a.Status == 0 || a.Status == 1)))
                                    {
                                        db.ZhaopinCheckCode.Add(new ZhaopinCheckCode
                                        {
                                            Account    = companyName,
                                            Cookie     = cookieStr,
                                            CreateTime = DateTime.Now,
                                            Status     = 0,
                                            Type       = 1
                                        });

                                        db.SaveChanges();
                                    }
                                }

                                Thread.Sleep(retryInterval);

                                continue;
                            }

                            Thread.Sleep(interval);

                            ids += match.Result("$1") + "%3B";

                            break;
                        }

                        File.WriteAllText(filePath, requestResult.Data);

                        this.AsyncSetLog(this.tbx_Log, $"下载成功!第 {++count} 份 Path => {filePath}");

                        var htmlDocument = new HtmlDocument();

                        htmlDocument.LoadHtml(requestResult.Data);

                        resumeQueue.Enqueue(new KeyValuePair <HtmlDocument, DateTime>(htmlDocument, DateTime.Parse(match.Result("$4"))));
                    }
                    catch (Exception ex)
                    {
                        this.AsyncSetLog(this.tbx_Log, "程序异常!异常消息:" + ex.Message);
                    }
                }

                requestResult = RequestFactory.QueryRequest("https://rd2.zhaopin.com/RdApply/Resumes/Apply/SetResumeState", $"ids={ids}&oldResumeState=1&resumeState=4", RequestEnum.POST, _cookieContainer);

                var jsonObj = JsonConvert.DeserializeObject <dynamic>(requestResult.Data);

                if ((int)jsonObj.Code != 200)
                {
                    this.AsyncSetLog(this.tbx_Log, $"标记简历为不合适失败!Message = {(string)jsonObj.Message}");

                    continue;
                }

                this.AsyncSetLog(this.tbx_Log, "标记简历为不合适成功!");
            }

            this.AsyncSetLog(this.tbx_Log, "简历处理完成!");

            this.RunInMainthread(() =>
            {
                this.btn_StartDownload.Enabled = true;
            });
        }
Beispiel #22
0
        /// <summary>
        /// 检查用户账户是否被封禁
        /// </summary>
        /// <param name="userResume"></param>
        /// <param name="code"></param>
        /// <returns></returns>
        private static bool CheckUserIsUseable(dynamic userResume, out int code)
        {
            code = 0;

            var date = DateTime.Now.Date.AddHours(-8);

            if (checkRecordDictionary.ContainsKey(userResume.UserId) && checkRecordDictionary[userResume.UserId] > date)
            {
                return(true);
            }

            while (true)
            {
                if (!localCompanyInfoQueue.Any())
                {
                    using (var db = new MangningXssDBEntities())
                    {
                        var companyPositionList = (from a in db.ZhaoPinCompany
                                                   join b in db.ZhaopinPosition on a.Id equals b.CompanyId
                                                   join c in db.ZhaopinStaff on a.Id equals c.CompanyId
                                                   where a.Source.Contains("MANUAL") && !string.IsNullOrEmpty(c.Cookie) && b.IsEnable
                                                   select new
                        {
                            a.Name,
                            CompanyId = a.Id,
                            PositionNumber = b.Number,
                            c.Cookie
                        }).ToList();

                        if (companyPositionList.Any())
                        {
                            companyPositionList.ForEach(f =>
                            {
                                localCompanyInfoQueue.Enqueue(f);
                            });
                        }
                        else
                        {
                            //todo:调用通知API

                            LogFactory.Warn("无有效本地公司 Cookie 校验帐号是否可用!");

                            Thread.Sleep(TimeSpan.FromSeconds(30));

                            continue;
                        }
                    }
                }

                while (true)
                {
                    if (!localCompanyInfoQueue.Any())
                    {
                        break;
                    }

                    var localCompanyInfo = localCompanyInfoQueue.Dequeue();

                    var cookieStr = (string)localCompanyInfo.Cookie;

                    var isLoginResult = RequestFactory.QueryRequest("https://ihr.zhaopin.com/home/assetcount.do", cookieContainer: cookieStr.Serialize("zhaopin.com"));

                    if (!isLoginResult.IsSuccess)
                    {
                        LogFactory.Warn($"校验公司 Cookie 是否有效请求异常!公司:{localCompanyInfo.Name},异常信息:{isLoginResult.ErrorMsg}");

                        continue;
                    }

                    var obj = JsonConvert.DeserializeObject(isLoginResult.Data) as JObject;

                    if ((string)obj?["code"] != "200")
                    {
                        var id = (int)localCompanyInfo.CompanyId;

                        using (var db = new MangningXssDBEntities())
                        {
                            var companyStaff = db.ZhaopinStaff.FirstOrDefault(f => f.CompanyId == id);

                            if (companyStaff != null)
                            {
                                companyStaff.Cookie = "";
                            }

                            db.TransactionSaveChanges();
                        }

                        var count = localCompanyInfoQueue.Count;

                        for (var i = 0; i < count; i++)
                        {
                            var temp = localCompanyInfoQueue.Dequeue();

                            if (temp.CompanyId != localCompanyInfo.CompanyId)
                            {
                                localCompanyInfoQueue.Enqueue(temp);
                            }
                        }

                        LogFactory.Warn($"公司 Cookie 失效!公司:{localCompanyInfo.Name},异常信息:{obj?["message"]}");

                        continue;
                    }

                    var userCookieStr = (string)userResume.Cookie;

                    var deilverResult = RequestFactory.QueryRequest($"https://my.zhaopin.com/v5/FastApply/resumeinfo.aspx?t=3&j={localCompanyInfo.PositionNumber}&j2=&so=&su=&ff=ssb&rv={userResume.ResumeNumber}_1&rl=1&cl=&sd=0&fd=&c=jsonp7u3t5v&_=1493174565322", cookieContainer: userCookieStr.Serialize("zhaopin.com"));

                    if (!deilverResult.IsSuccess)
                    {
                        LogFactory.Warn($"投递简历请求异常!简历编号:{userResume.ResumeNumber},职位编号:{localCompanyInfo.PositionNumber},异常信息:{deilverResult.ErrorMsg}");

                        continue;
                    }

                    var message = JsonConvert.DeserializeObject <dynamic>(Regex.Match(deilverResult.Data, @"(\{.+?\})").Result("$1"));

                    var status = message.postBackInfo.ToString().Split('_');

                    if (message.loginstatus.ToString() != "6")
                    {
                        return(true);
                    }

                    if (message.loginstatus.ToString() == "7_Position has Down")
                    {
                        LogFactory.Warn($"该职位已下架!职位编号:{localCompanyInfo.PositionNumber}");

                        using (var db = new MangningXssDBEntities())
                        {
                            var positionNumber = (string)localCompanyInfo.PositionNumber;

                            var positionDefault = db.ZhaopinPosition.FirstOrDefault(f => f.Number == positionNumber);

                            if (positionDefault != null)
                            {
                                positionDefault.IsEnable = false;
                            }
                            else
                            {
                                LogFactory.Warn("数据库未找到对应的职位!职位 Number:" + positionNumber);
                            }

                            db.TransactionSaveChanges();
                        }

                        continue;
                    }

                    if (status[3].ToString() == "0")
                    {
                        Console.WriteLine($"投递本地公司失败!,职位 7 天内投递过!公司:{localCompanyInfo.Name} 职位编号:{localCompanyInfo.PositionNumber} 用户:{userResume.Username}");

                        if (!localCompanyInfoQueue.Any())
                        {
                            LogFactory.Warn($"本地可用公司的所有职位均在7天内投递过!用户:{userResume.Username}");
                        }

                        continue;
                    }

                    Console.WriteLine($"投递本地公司成功!公司:{localCompanyInfo.Name},用户:{userResume.Username}");

                    Thread.Sleep(TimeSpan.FromSeconds(5));

                    var token = cookieStr.Substring(cookieStr.IndexOf("Token=", StringComparison.Ordinal) + 6, 32);

                    var dataResult = RequestFactory.QueryRequest($"https://ihr.zhaopin.com/resumemanage/resumelistbykey.do?access_token={token}&v=0.47046618467879875", "startNum=0&rowsCount=30&ageStart=&ageEnd=&workYears=&sex=&edu=&liveCity=&hopeWorkCity=&upDate=&companyName=&exclude=&keywords=&onlyLastWork=false&orderFlag=deal&countFlag=1&jobNo=&pageType=all&source=1%3B2%3B5&sort=time", RequestEnum.POST, cookieStr.Serialize("zhaopin.com"));

                    if (!dataResult.IsSuccess)
                    {
                        LogFactory.Warn($"搜索简历列表请求异常!公司ID:{localCompanyInfo.CompanyId},异常信息:{deilverResult.ErrorMsg}");

                        continue;
                    }

                    var jsonObj = JsonConvert.DeserializeObject(dataResult.Data) as JObject;

                    if ((string)jsonObj?["code"] != "1")
                    {
                        var id = (int)localCompanyInfo.CompanyId;

                        using (var db = new MangningXssDBEntities())
                        {
                            var companyStaff = db.ZhaopinStaff.FirstOrDefault(f => f.CompanyId == id);

                            if (companyStaff != null)
                            {
                                companyStaff.Cookie = "";
                            }

                            db.TransactionSaveChanges();
                        }

                        var count = localCompanyInfoQueue.Count;

                        for (var i = 0; i < count; i++)
                        {
                            var temp = localCompanyInfoQueue.Dequeue();

                            if (temp.CompanyId != localCompanyInfo.CompanyId)
                            {
                                localCompanyInfoQueue.Enqueue(temp);
                            }
                        }

                        LogFactory.Warn($"企业帐号简历列表获取异常!公司ID:{localCompanyInfo.CompanyId},异常信息:{jsonObj?["message"]}");

                        continue;
                    }

                    var resumes = jsonObj?["data"]["deal"]["results"] as JArray;

                    if (resumes == null)
                    {
                        LogFactory.Warn($"搜索简历列表 Josn 解析异常!公司ID:{localCompanyInfo.CompanyId},异常 Josn:{dataResult.Data}");

                        continue;
                    }

                    localCompanyInfoQueue.Enqueue(localCompanyInfo);

                    var resume = resumes.FirstOrDefault(a => a["userId"] == userResume.UserId && Convert.ToDateTime(a["createTime"]) > DateTime.UtcNow.AddMinutes(-5));

                    if (resume != null)
                    {
                        if (!resume.ToString().Contains("<script"))
                        {
                            LogFactory.Warn($"简历未处理,用户:{userResume.Username}");

                            code = -1;

                            return(false);
                        }

                        checkRecordDictionary[userResume.UserId] = DateTime.UtcNow;

                        Console.WriteLine($"用户可用!公司:{localCompanyInfo.Name},用户:{userResume.Username}");

                        return(true);
                    }

                    Console.WriteLine($"用户不可用!公司:{localCompanyInfo.Name},用户:{userResume.Username}");

                    return(false);
                }
            }
        }
        /// <summary>
        /// 组合简历
        /// </summary>
        private static void PortfolioResume()
        {
            while (true)
            {
                try
                {
                    ZhaopinResume resume;

                    var stopwatch = new Stopwatch();

                    stopwatch.Restart();

                    if (!resumeQueue.TryDequeue(out resume))
                    {
                        Thread.Sleep(100);

                        continue;
                    }

                    var filePath = $"{uploadFilePath}{resume.Id}.json";

                    if (File.Exists(filePath))
                    {
                        uploadQueue.Enqueue(filePath);

                        continue;
                    }

                    string userId;

                    string cellphone;

                    string email;

                    using (var db = new MangningXssDBEntities())
                    {
                        var user = db.ZhaopinUser.AsNoTracking().FirstOrDefault(f => f.Id == resume.UserId);

                        if (user == null)
                        {
                            continue;
                        }

                        userId = user.Id.ToString();

                        cellphone = user.Cellphone;

                        email = user.Email;

                        using (var stream = new MemoryStream())
                        {
                            if (mangningOssClient.DoesObjectExist(mangningBucketName, $"Zhaopin/Resume/{resume.Id}"))
                            {
                                var bytes = new byte[1024];

                                int len;

                                var streamContent = mangningOssClient.GetObject(mangningBucketName, $"Zhaopin/Resume/{resume.Id}").Content;

                                while ((len = streamContent.Read(bytes, 0, bytes.Length)) > 0)
                                {
                                    stream.Write(bytes, 0, len);
                                }

                                var resumeContent = Encoding.UTF8.GetString(GZip.Decompress(stream.ToArray()));

                                var resumeObj = JsonConvert.DeserializeObject <dynamic>(resumeContent);

                                var resumeDetail = JsonConvert.DeserializeObject(resumeObj.detialJSonStr.ToString());

                                resumeDetail.DateModified = user.ModifyTime.ToLocalTime();

                                resumeDetail.DateCreated = user.CreateTime?.ToLocalTime() ?? resumeDetail.DateCreated;

                                resumeDetail.DateLastReleased = resume.RefreshTime.Value.ToLocalTime();

                                resumeDetail.DateLastViewed = resume.RefreshTime.Value.ToLocalTime();

                                resumeObj.detialJSonStr = resumeDetail;

                                resumeContent = JsonConvert.SerializeObject(resumeObj);

                                File.WriteAllText(filePath, resumeContent);

                                uploadQueue.Enqueue(filePath);

                                continue;
                            }

                            if (mangningOssClient.DoesObjectExist(mangningBucketName, $"WatchResume/{resume.Id}"))
                            {
                                var bytes = new byte[1024];

                                int len;

                                var streamContent = mangningOssClient.GetObject(mangningBucketName, $"WatchResume/{resume.Id}").Content;

                                while ((len = streamContent.Read(bytes, 0, bytes.Length)) > 0)
                                {
                                    stream.Write(bytes, 0, len);
                                }

                                var resumeContent = Encoding.UTF8.GetString(GZip.Decompress(stream.ToArray()));

                                var resumeObj = JsonConvert.DeserializeObject <dynamic>(resumeContent);

                                resumeObj.userDetials.mobilePhone = user.Cellphone;

                                resumeObj.userDetials.email = user.Email;

                                var resumeDetail = JsonConvert.DeserializeObject(resumeObj.detialJSonStr.ToString());

                                resumeDetail.DateModified = user.ModifyTime.ToLocalTime();

                                resumeDetail.DateCreated = user.CreateTime.Value.ToLocalTime();

                                resumeDetail.DateLastReleased = resume.RefreshTime.Value.ToLocalTime();

                                resumeDetail.DateLastViewed = resume.RefreshTime.Value.ToLocalTime();

                                resumeObj.detialJSonStr = resumeDetail;

                                resumeContent = JsonConvert.SerializeObject(resumeObj);

                                using (var jsonStream = new MemoryStream(GZip.Compress(Encoding.UTF8.GetBytes(resumeContent))))
                                {
                                    mangningOssClient.PutObject(mangningBucketName, $"Zhaopin/Resume/{resume.Id}", jsonStream);
                                }

                                File.WriteAllText(filePath, resumeContent);

                                uploadQueue.Enqueue(filePath);

                                continue;
                            }

                            var zhaopinResume = db.ZhaopinResume.FirstOrDefault(f => f.Id == resume.Id);

                            if (zhaopinResume != null)
                            {
                                zhaopinResume.Flag = 0x2;
                            }
                        }

                        db.SaveChanges();

                        stopwatch.Stop();
                    }

                    using (var bdcDb = new BadoucaiAliyunDBEntities())
                    {
                        bdcDb.CoreResumeZhaopin.Add(new CoreResumeZhaopin
                        {
                            Cellphone = cellphone,
                            Email     = email,
                            ResumeKey = userId,
                            Type      = "ResumeUserId",
                            IsMatched = false
                        });

                        bdcDb.SaveChanges();
                    }

                    Console.WriteLine($"{DateTime.Now} > 简历未找到 Josn 源!ResumeId = {resume.Id}, UserId = {userId}, Elapsed = {stopwatch.ElapsedMilliseconds} ms.");
                }
                catch (Exception ex)
                {
                    Trace.TraceError(ex.ToString());
                }
            }
        }
Beispiel #24
0
        /// <summary>
        /// 按条件搜索简历
        /// </summary>
        /// <param name="cookieContainer"></param>
        private static void SearchResumes(CookieContainer cookieContainer)
        {
            while (true)
            {
                ZhaopinSearchCondition condition;

                if (count >= refreshCount)
                {
                    break;
                }

                if (!conditionQueue.TryDequeue(out condition))
                {
                    Thread.Sleep(100);

                    break;
                }

                var pageIndex = 1;

                var pageTotal = 1;

                var total = 0;

                while (pageIndex < pageTotal + 1)
                {
                    if (count >= refreshCount)
                    {
                        break;
                    }

                    // 2041:宝安  635:南京  653:杭州  639:苏州 765:深圳

                    var param = string.IsNullOrEmpty(keyword) ? string.Empty : $"SF_1_1_1={keyword}&";

                    param += string.IsNullOrEmpty(position) ? string.Empty : $"SF_1_1_2={position}&";

                    param += string.IsNullOrEmpty(industry) ? string.Empty : $"SF_1_1_3={industry}&";

                    var url = $"https://ihrsearch.zhaopin.com/Home/ResultForCustom?{param}SF_1_1_6={city}&SF_1_1_8={condition.Age}%2C{condition.Age}&SF_1_1_9={condition.Gender}&SF_1_1_5={condition.Degrees}%2C{condition.Degrees}&orderBy=BIRTH_YEAR%2C0&SF_1_1_27=0&SF_1_1_7={date}%2C9&exclude=1&pageIndex={pageIndex}&pageSize=60";

                    var requestResult = RequestFactory.QueryRequest(url, cookieContainer: cookieContainer, referer: url);

                    if (!requestResult.IsSuccess)
                    {
                        Trace.TraceError($"{DateTime.Now} > Search Error ! Message = {requestResult.ErrorMsg} Condition = {JsonConvert.SerializeObject(condition)}.");

                        continue;
                    }

                    if (pageTotal == 1)
                    {
                        var match = Regex.Match(requestResult.Data, "(?s)<span>(\\d+)</span>份简历.+?rd-resumelist-pageNum\">1/(\\d+)</span>");

                        if (!match.Success)
                        {
                            if (requestResult.Data.Contains("text/javascript\" r='m'"))
                            {
                                Trace.TraceWarning($"{DateTime.Now} > Cookie Expired !");
                            }
                            else
                            {
                                Trace.TraceWarning($"{DateTime.Now} > Condition search error ! Page content = {requestResult.Data}");
                            }

                            return;
                        }

                        total = Convert.ToInt32(match.Result("$1"));

                        pageTotal = Convert.ToInt32(match.Result("$2"));

                        totalCount += total;

                        if (total == 0)
                        {
                            Console.WriteLine($"{DateTime.Now} > Search results are empty !");

                            break;
                        }
                    }

                    Console.WriteLine($"{DateTime.Now} > 第 {pageIndex} 页  共 {pageTotal} 页 {total} 个结果");

                    pageIndex++;

                    var matchs = Regex.Matches(requestResult.Data, "(?s)RedirectToRd/([^\r\n]+?)','([^\r\n]+?)','([^\r\n]+?)',this\\);this.+?(\\d{2}-\\d{2}-\\d{2})");

                    foreach (Match item in matchs)
                    {
                        try
                        {
                            if (count >= refreshCount)
                            {
                                break;
                            }

                            var number = item.Result("$1").Substring(0, 10);

                            DateTime updateDateTime;

                            if (!DateTime.TryParse(item.Result("$4"), out updateDateTime))
                            {
                                continue;
                            }

                            using (var db = new MangningXssDBEntities())
                            {
                                var resume = db.ZhaopinResume.FirstOrDefault(f => f.RandomNumber == number);

                                if (resume != null)
                                {
                                    if (resume.Flag == 15)
                                    {
                                        #region 刷新简历更新时间

                                        //if (resume.RefreshTime != null && updateDateTime.Date == resume.RefreshTime.Value.Date) continue;

                                        resume.RefreshTime = updateDateTime;

                                        resume.Flag = 14;

                                        var filePath = $@"D:\Badoucai\Resume\LocationJson\{resume.Id}.json";

                                        using (var stream = new MemoryStream())
                                        {
                                            if (!mangningOssClient.DoesObjectExist(mangningBucketName, $"Zhaopin/Resume/{resume.Id}"))
                                            {
                                                continue;
                                            }

                                            var bytes = new byte[1024];

                                            int len;

                                            var streamContent = mangningOssClient.GetObject(mangningBucketName, $"Zhaopin/Resume/{resume.Id}").Content;

                                            while ((len = streamContent.Read(bytes, 0, bytes.Length)) > 0)
                                            {
                                                stream.Write(bytes, 0, len);
                                            }

                                            var resumeContent = Encoding.UTF8.GetString(GZip.Decompress(stream.ToArray()));

                                            var jsonObj = JsonConvert.DeserializeObject <dynamic>(resumeContent);

                                            dynamic detialJSonStr;

                                            try
                                            {
                                                detialJSonStr = jsonObj.detialJSonStr;

                                                if (!string.IsNullOrEmpty((string)jsonObj.detialJSonStr.DateModified))
                                                {
                                                    jsonObj.detialJSonStr = JsonConvert.SerializeObject(jsonObj.detialJSonStr);
                                                }
                                            }
                                            catch (Exception)
                                            {
                                                detialJSonStr = JsonConvert.DeserializeObject <dynamic>((string)jsonObj.detialJSonStr);
                                            }

                                            detialJSonStr.DateLastReleased = updateDateTime;

                                            detialJSonStr.DateModified = updateDateTime;

                                            jsonObj.detialJSonStr = detialJSonStr;

                                            var newResumeContent = JsonConvert.SerializeObject(jsonObj);

                                            using (var jsonStream = new MemoryStream(GZip.Compress(Encoding.UTF8.GetBytes(newResumeContent))))
                                            {
                                                mangningOssClient.PutObject(mangningBucketName, $"Zhaopin/Resume/{resume.Id}", jsonStream);
                                            }

                                            File.WriteAllText(filePath, newResumeContent);
                                        }

                                        #endregion
                                    }

                                    if (resume.Flag == 2)
                                    {
                                        var user = db.ZhaopinUser.FirstOrDefault(f => f.Id == resume.UserId);

                                        if (user == null)
                                        {
                                            continue;
                                        }

                                        WatchResumeDetail(item, cookieContainer, user.Cellphone, user.Email);
                                    }
                                }
                                else
                                {
                                    var incompleteResume = db.ZhaopinIncompleteResume.FirstOrDefault(f => f.ResumeNumber == number);

                                    if (incompleteResume == null)
                                    {
                                        continue;
                                    }

                                    if (WatchResumeDetail(item, cookieContainer, incompleteResume.Cellphone, incompleteResume.Email))
                                    {
                                        incompleteResume.CompletionTime = DateTime.Now;
                                    }
                                }

                                db.SaveChanges();

                                Interlocked.Increment(ref count);

                                if (resume != null)
                                {
                                    sb.AppendLine(resume.Id.ToString());
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            Trace.TraceError(ex.ToString());
                        }
                    }

                    Console.WriteLine($"{DateTime.Now} > Total = {totalCount}, Update Count = {count}, Cookie Count = {cookieQueue.Count}, Condition Count = {conditionQueue.Count}. ");
                }
            }
        }
        public void Watch()
        {
            var cookieQueue = new ConcurrentQueue <KeyValuePair <KeyValuePair <int, string>, CookieContainer> >();

            using (var db = new MangningXssDBEntities())
            {
                var companyArr = db.ZhaoPinCompany.Where(w => w.Source.Contains("MANUAL")).Select(s => s.Id).ToArray();

                var paramArr = db.ZhaopinStaff.Where(w => companyArr.Any(a => a == w.CompanyId) && !string.IsNullOrEmpty(w.Cookie)).Select(s => new { s.CompanyId, s.Username, s.Cookie }).ToArray();

                foreach (var item in paramArr)
                {
                    cookieQueue.Enqueue(new KeyValuePair <KeyValuePair <int, string>, CookieContainer>(new KeyValuePair <int, string>(item.CompanyId, item.Username), item.Cookie.Serialize(".zhaopin.com")));
                }
            }

            using (var db = new MangningXssDBEntities())
            {
                var list = db.ZhaopinCleaningProcedure.Where(w => w.IsEnable && !string.IsNullOrEmpty(w.Cookie));

                foreach (var item in list)
                {
                    cookieQueue.Enqueue(new KeyValuePair <KeyValuePair <int, string>, CookieContainer>(new KeyValuePair <int, string>(0, item.Account), item.Cookie.Serialize(".zhaopin.com")));
                }
            }

            #region 插入查询条件

            for (var degrees = 5; degrees < 16; degrees += 2)
            {
                for (var age = 20; age <= 28; age++)
                {
                    queue.Enqueue(new
                    {
                        Degrees = degrees,
                        Age     = age
                    });
                }
            }

            #endregion

            Console.WriteLine($"已获取 Cookie 数 => {cookieQueue.Count}");

            for (var j = 0; j < 4; j++)
            {
                Task.Run(() =>
                {
                    try
                    {
                        while (true)
                        {
                            KeyValuePair <KeyValuePair <int, string>, CookieContainer> temp;

                            if (!cookieQueue.TryDequeue(out temp))
                            {
                                Thread.Sleep(1000);

                                continue;
                            }

                            while (true)
                            {
                                dynamic condition;

                                if (!queue.TryDequeue(out condition))
                                {
                                    Console.WriteLine($"Company => {temp.Key.Value} 找不到可搜索的条件!");

                                    Thread.Sleep(1000);
                                    continue;
                                }

                                var pageIndex = 1;

                                var pageTotal = 1;

                                var total = 0;

                                var isbreak = false;

                                while (pageIndex < pageTotal + 1)
                                {
                                    var url = $"https://ihrsearch.zhaopin.com/Home/ResultForCustom?SF_1_1_7=1%2C9&SF_1_1_5={condition.Degrees}%2C{condition.Degrees}&SF_1_1_18=530%3B854%3B531&SF_1_1_8={condition.Age}%2C{condition.Age}&SF_1_1_27=0&orderBy=DATE_MODIFIED,1&pageSize=60&exclude=1";

                                    var requestResult = RequestFactory.QueryRequest(url, cookieContainer: temp.Value, referer: url);

                                    if (!requestResult.IsSuccess)
                                    {
                                        LogFactory.Warn($"Company => {temp.Key.Value} 条件搜索异常!异常原因=>{requestResult.ErrorMsg} Condition=>{JsonConvert.SerializeObject(condition)}");

                                        continue;
                                    }

                                    if (pageTotal == 1)
                                    {
                                        var match = Regex.Match(requestResult.Data, "(?s)<span>(\\d+)</span>份简历.+?rd-resumelist-pageNum\">1/(\\d+)</span>");

                                        if (!match.Success)
                                        {
                                            if (requestResult.Data.Contains("text/javascript\" r='m'"))
                                            {
                                                LogFactory.Warn($"Cookie 过期,过期用户 => {temp.Key.Value}");
                                            }
                                            else
                                            {
                                                LogFactory.Warn($"Company => {temp.Key.Value} 条件搜索异常!返回页面解析异常!{requestResult.Data}");
                                            }

                                            isbreak = true;

                                            break;
                                        }

                                        total = Convert.ToInt32(match.Result("$1"));

                                        pageTotal = Convert.ToInt32(match.Result("$2"));

                                        if (total == 0)
                                        {
                                            Console.WriteLine("该条件无搜索结果!");

                                            break;
                                        }
                                    }

                                    Console.WriteLine($"Company => {temp.Key.Value} 第 {pageIndex} 页  共 {pageTotal} 页 {total} 个结果");

                                    pageIndex++;

                                    var matchs = Regex.Matches(requestResult.Data, "(?s)RedirectToRd/([^\r\n]+?)','([^\r\n]+?)','([^\r\n]+?)',this\\);this.+?(\\d{2}-\\d{2}-\\d{2})");

                                    using (var db = new MangningXssDBEntities())
                                    {
                                        foreach (Match item in matchs)
                                        {
                                            var number = item.Result("$1").Substring(0, 10);

                                            var numberParam = item.Result("$1").Substring(0, item.Result("$1").IndexOf("?", StringComparison.Ordinal));

                                            if (!hashSet.Add(number))
                                            {
                                                continue;
                                            }

                                            db.ZhaopinResumeNumber.Add(new ZhaopinResumeNumber {
                                                ResumeNumber = number
                                            });

                                            var resume = db.ZhaopinResume.FirstOrDefault(f => f.RandomNumber == number);

                                            if (resume == null)
                                            {
                                                continue;
                                            }

                                            var user = db.ZhaopinUser.FirstOrDefault(f => f.Id == resume.UserId && !string.IsNullOrEmpty(f.Cellphone));

                                            if (user == null)
                                            {
                                                continue;
                                            }

                                            requestResult = RequestFactory.QueryRequest($"http://ihr.zhaopin.com/resumesearch/getresumedetial.do?resumeNo={numberParam}&searchresume=1&resumeSource=1&keyword=%E8%AF%B7%E8%BE%93%E5%85%A5%E7%AE%80%E5%8E%86%E5%85%B3%E9%94%AE%E8%AF%8D%EF%BC%8C%E5%A4%9A%E5%85%B3%E9%94%AE%E8%AF%8D%E5%8F%AF%E7%94%A8%E7%A9%BA%E6%A0%BC%E5%88%86%E9%9A%94&t={item.Result("$2")}&k={item.Result("$3")}&v=undefined&version=3&openFrom=1", cookieContainer: temp.Value);

                                            if (!requestResult.IsSuccess)
                                            {
                                                LogFactory.Warn($"Company => {temp.Key.Value} 简历详情查看异常!异常原因=>{requestResult.ErrorMsg} ResumeNumber=>{number}");

                                                continue;
                                            }

                                            try
                                            {
                                                var jsonObj = JsonConvert.DeserializeObject <dynamic>(requestResult.Data);

                                                if ((int)jsonObj["code"] != 1)
                                                {
                                                    LogFactory.Warn($"Company => {temp.Key.Value} ResumeNumber => {number} 查看详情异常 信息:{(string)jsonObj["message"]}");

                                                    if (((string)jsonObj["message"]).Contains("当日查看简历已达上限"))
                                                    {
                                                        isbreak = true;

                                                        break;
                                                    }

                                                    continue;
                                                }

                                                var resumeData = jsonObj.data;

                                                resumeData.userDetials.mobilePhone = user.Cellphone;

                                                resumeData.userDetials.email = user.Email;

                                                File.WriteAllText($@"D:\ResumeBusiness\{number}.json", JsonConvert.SerializeObject(resumeData));

                                                Console.WriteLine($"Company => {temp.Key.Value} 查看简历成功!ResumeNumber => {number}");
                                            }
                                            catch (Exception ex)
                                            {
                                                while (true)
                                                {
                                                    if (ex.InnerException == null)
                                                    {
                                                        break;
                                                    }

                                                    ex = ex.InnerException;
                                                }

                                                LogFactory.Error($"保存简历信息异常!异常信息:{ex.Message} 响应信息:{requestResult.Data}");
                                            }
                                        }

                                        db.SaveChanges();
                                    }

                                    if (isbreak)
                                    {
                                        break;
                                    }
                                }

                                if (isbreak)
                                {
                                    break;
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        while (true)
                        {
                            if (ex.InnerException == null)
                            {
                                break;
                            }

                            ex = ex.InnerException;
                        }

                        LogFactory.Error($"Watch异常!异常信息:{ex.Message}  {ex.StackTrace}");
                    }
                });
            }
        }
        /// <summary>
        /// 标记简历
        /// </summary>
        /// <param name="jsonContent"></param>
        /// <param name="resumeId"></param>
        private static void FlagResume(string jsonContent, int resumeId)
        {
            using (var db = new MangningXssDBEntities())
            {
                var resume = db.ZhaopinResume.FirstOrDefault(f => f.Id == resumeId);

                if (resume?.Flag == 0xF)
                {
                    badoucaiOssClient.DeleteObject(badoucaiBucketName, $"Zhaopin/{resumeId}");

                    resume.IncludeTime = DateTime.UtcNow;

                    db.SaveChanges();

                    return;
                }

                var resumeIdStr = resumeId.ToString();

                if (jsonContent.Contains("detialJSonStr"))
                {
                    var jsonObj = JsonConvert.DeserializeObject <dynamic>(jsonContent);

                    //var userId = (int)jsonObj.userDetials.userMasterId;

                    if (string.IsNullOrWhiteSpace((string)jsonObj.userDetials.mobilePhone))
                    {
                        var user = resume != null?db.ZhaopinUser.FirstOrDefault(f => f.Id == resume.UserId && !string.IsNullOrEmpty(f.Cellphone)) : null;

                        if (user == null)
                        {
                            using (var adb = new BadoucaiAliyunDBEntities())
                            {
                                var reference = adb.CoreResumeReference.AsNoTracking().FirstOrDefault(f => f.Id == resumeIdStr);

                                CoreResumeSummary summary = null;

                                if (reference != null)
                                {
                                    summary = adb.CoreResumeSummary.AsNoTracking().FirstOrDefault(f => f.Id == reference.ResumeId);
                                }

                                if (summary != null)
                                {
                                    jsonObj.userDetials.mobilePhone = summary.Cellphone;

                                    jsonObj.userDetials.email = summary.Email;
                                }
                            }
                        }
                        else
                        {
                            jsonObj.userDetials.mobilePhone = user.Cellphone;

                            jsonObj.userDetials.email = user.Email;
                        }
                    }

                    File.WriteAllText($"{jsonFilePath}{resumeId}", jsonContent);

                    #region 被注释的代码

                    //var flag = string.IsNullOrEmpty((string)jsonObj.userDetials.mobilePhone) ? (short)0x0 : (short)0xF;

                    //dynamic detialJSonStr;

                    //try
                    //{
                    //    detialJSonStr = jsonObj.detialJSonStr;

                    //    if (!string.IsNullOrEmpty((string)jsonObj.detialJSonStr.DateModified))
                    //    {
                    //        jsonObj.detialJSonStr = JsonConvert.SerializeObject(jsonObj.detialJSonStr);
                    //    }
                    //}
                    //catch (Exception)
                    //{
                    //    detialJSonStr = JsonConvert.DeserializeObject<dynamic>((string)jsonObj.detialJSonStr);
                    //}

                    //if (resume == null)
                    //{
                    //    db.ZhaopinResume.Add(new ZhaopinResume
                    //    {
                    //        Id = resumeId,
                    //        RandomNumber = ((string)jsonObj.resumeNo).Substring(0, 10),
                    //        UserId = userId,
                    //        RefreshTime = BaseFanctory.GetTime((string)detialJSonStr.DateModified).ToUniversalTime(),
                    //        UpdateTime = DateTime.UtcNow,
                    //        UserExtId = (string)detialJSonStr.UserMasterExtId,
                    //        Source = "XSS",
                    //        Flag = flag
                    //    });

                    //    handlerFlag = "Insert";
                    //}
                    //else
                    //{
                    //    resume.RandomNumber = ((string)jsonObj.resumeNo).Substring(0, 10);
                    //    resume.UserId = userId;
                    //    resume.RefreshTime = BaseFanctory.GetTime((string)detialJSonStr.DateModified).ToUniversalTime();
                    //    resume.UpdateTime = DateTime.UtcNow;
                    //    resume.Flag = flag;

                    //    handlerFlag = "Update";
                    //}

                    //db.ZhaopinUser.AddOrUpdate(new ZhaopinUser
                    //{
                    //    Id = userId,
                    //    Cellphone = (string)jsonObj.userDetials.mobilePhone,
                    //    CreateTime = BaseFanctory.GetTime((string)detialJSonStr.DateCreated).ToUniversalTime(),
                    //    Email = (string)jsonObj.userDetials.email,
                    //    ModifyTime = BaseFanctory.GetTime((string)detialJSonStr.DateModified).ToUniversalTime(),
                    //    Name = (string)jsonObj.userDetials.userName,
                    //    Source = "XSS",
                    //    UpdateTime = DateTime.UtcNow
                    //});

                    //var jsonResume = JsonConvert.SerializeObject(jsonObj);

                    //if (flag == 0x0)
                    //{
                    //    var path = $@"F:\ZhaopinOss\Resume\NoInformation\{resumeIdStr.Substring(0, 2)}\{resumeIdStr.Substring(2, 2)}";

                    //    if (!Directory.Exists(path)) Directory.CreateDirectory(path);

                    //    File.WriteAllText($@"{path}\{resumeIdStr}",jsonResume);
                    //}
                    //else
                    //{
                    //    var path = $@"F:\ZhaopinOss\Resume\HaveInformation\{resumeIdStr.Substring(0, 2)}\{resumeIdStr.Substring(2, 2)}";

                    //    if (!Directory.Exists(path)) Directory.CreateDirectory(path);

                    //    File.WriteAllText($@"{path}\{resumeIdStr}", jsonResume);

                    //    using (var stream = new MemoryStream(GZip.Compress(Encoding.UTF8.GetBytes(jsonResume))))
                    //    {
                    //        mangningClient.PutObject(mangningBucketName, $"Zhaopin/Resume/{resumeIdStr}", stream);
                    //    }
                    //}

                    #endregion

                    badoucaiOssClient.DeleteObject(badoucaiBucketName, $"Zhaopin/{resumeId}");
                }
                else
                {
                    if (jsonContent.StartsWith("\"<!DOCTYPE HTML>", StringComparison.OrdinalIgnoreCase) || jsonContent.StartsWith("<html", StringComparison.OrdinalIgnoreCase))
                    {
                        if (jsonContent.StartsWith("\"<!DOCTYPE HTML>", StringComparison.OrdinalIgnoreCase))
                        {
                            jsonContent = jsonContent.Substring(1);

                            jsonContent = jsonContent.Substring(0, jsonContent.Length - 1);

                            jsonContent = Regex.Unescape(jsonContent);
                        }

                        var updateTime = Regex.Match(jsonContent, "(?s)resumeUpdateTime\">(.+?)<.+?userName.+?alt=\"(.+?)\"").ResultOrDefault("$1", "");

                        var name = Regex.Match(jsonContent, "(?s)resumeUpdateTime\">(.+?)<.+?userName.+?alt=\"(.+?)\"").ResultOrDefault("$2", "").Replace("\\", "").Replace("/", "");

                        string fileName;

                        if (string.IsNullOrEmpty(updateTime) || string.IsNullOrEmpty(name))
                        {
                            fileName = $"{resumeId}";
                        }
                        else
                        {
                            fileName = $"{name}_{updateTime.Replace("年", "-").Replace("月", "-").Replace("日", "")}.txt";
                        }

                        File.WriteAllText($"{domFilePath}{fileName}", jsonContent);
                    }
                    else
                    {
                        Trace.WriteLine($"{DateTime.Now} > 简历格式异常!异常简历ID = {resumeId}, Content = {jsonContent}");
                    }

                    badoucaiOssClient.DeleteObject(badoucaiBucketName, $"Zhaopin/{resumeId}");
                }
            }
        }
        public void SaveResumeInfo(ResumeMatchResult model)
        {
            using (var xdb = new MangningXssDBEntities())
            {
                var user = xdb.ZhaopinUser.FirstOrDefault(f => f.Id == model.UserId);

                if (user == null)
                {
                    xdb.ZhaopinUser.Add(new ZhaopinUser
                    {
                        Id         = model.UserId,
                        Source     = "Watch",
                        ModifyTime = model.ModifyTime,
                        Cellphone  = model.Cellphone,
                        Email      = model.Email,
                        Name       = model.Name,
                        UpdateTime = DateTime.UtcNow,
                        CreateTime = model.CreateTime
                    });
                }
                else
                {
                    user.ModifyTime = model.ModifyTime;
                    user.UpdateTime = DateTime.UtcNow;
                    user.Name       = model.Name;
                }

                var resumeEntity = xdb.ZhaopinResume.FirstOrDefault(f => f.Id == model.ResumeId);

                var userExtId = Regex.IsMatch(model.UserExtId, @"^J[MRSL]\d{9}$") ? model.UserExtId : string.Empty;

                if (resumeEntity == null)
                {
                    xdb.ZhaopinResume.Add(new ZhaopinResume
                    {
                        Id           = model.ResumeId,
                        RandomNumber = model.ResumeNumber,
                        UserId       = model.UserId,
                        RefreshTime  = model.ModifyTime,
                        UpdateTime   = DateTime.UtcNow,
                        UserExtId    = userExtId,
                        Source       = "Watch"
                    });
                }
                else
                {
                    resumeEntity.RandomNumber = model.ResumeNumber;
                    resumeEntity.UserId       = model.UserId;
                    resumeEntity.RefreshTime  = model.ModifyTime;
                    if (string.IsNullOrEmpty(resumeEntity.UserExtId))
                    {
                        resumeEntity.UserExtId = userExtId;
                    }
                }

                var cache = xdb.ZhaopinMatchedCache.FirstOrDefault(f => f.ResumeId == model.ResumeId);

                if (cache == null)
                {
                    xdb.ZhaopinMatchedCache.Add(new ZhaopinMatchedCache
                    {
                        ResumeId     = model.ResumeId,
                        ModifyTime   = model.ModifyTime,
                        Cellphone    = model.Cellphone,
                        Email        = model.Email,
                        Name         = model.Name,
                        Path         = model.Path,
                        ResumeNumber = model.ResumeNumber,
                        UserExtId    = model.UserExtId,
                        UserId       = model.UserId
                    });
                }
                else
                {
                    cache.Cellphone = model.Cellphone;
                    cache.Email     = model.Email;
                    cache.UserExtId = model.UserExtId;
                }

                var watched = xdb.ZhaopinWatchedResume.FirstOrDefault(f => f.Id == model.ResumeId);

                if (watched == null)
                {
                    xdb.ZhaopinWatchedResume.Add(new ZhaopinWatchedResume
                    {
                        Id           = model.ResumeId,
                        ResumeNumber = model.ResumeNumber,
                        CompanyId    = model.CompanyId,
                        WatchTime    = DateTime.UtcNow
                    });
                }

                xdb.SaveChanges();
            }
        }
        public void MatchZhaopin()
        {
            var resumeQueue = new ConcurrentQueue <OldResumeSummary>();

            var cookieQueue = new ConcurrentQueue <QueueParam>();

            var todayString = DateTime.Today.ToString("yyyy-MM-dd");

            using (var db = new MangningXssDBEntities())
            {
                var companyArr = db.ZhaoPinCompany.Where(w => w.Source.Contains("MANUAL")).Select(s => s.Id).ToArray();

                var paramArr = db.ZhaopinStaff.Where(w => companyArr.Any(a => a == w.CompanyId) && !string.IsNullOrEmpty(w.Cookie)).Select(s => new { s.CompanyId, s.Cookie }).ToArray();

                foreach (var param in paramArr)
                {
                    var task = db.ZhaopinResumeMatchLimit.FirstOrDefault(f => f.CompanyId == param.CompanyId);

                    if (task == null)
                    {
                        continue;
                    }

                    var todayTask = db.ZhaopinResumeMatchStatistic.FirstOrDefault(f => f.CompanyId == param.CompanyId && f.Date == todayString);

                    if (todayTask == null)
                    {
                        todayTask = new ZhaopinResumeMatchStatistic
                        {
                            Date         = todayString,
                            CompanyId    = param.CompanyId,
                            MatchedCount = 0,
                            SearchCount  = 0,
                            WatchCount   = 0
                        };

                        db.ZhaopinResumeMatchStatistic.Add(todayTask);

                        db.SaveChanges();
                    }

                    if (todayTask.SearchCount == task.DailySearchCount || todayTask.WatchCount == task.DailyWatchCount)
                    {
                        continue;
                    }

                    cookieQueue.Enqueue(new QueueParam
                    {
                        CompanyId       = param.CompanyId,
                        Cookie          = param.Cookie,
                        DailySeachCount = task.DailySearchCount,
                        DailyWatchCount = task.DailyWatchCount,
                        MatchCount      = todayTask.MatchedCount,
                        SeachCount      = todayTask.SearchCount,
                        WatchCount      = todayTask.WatchCount + todayTask.MatchedCount
                    });
                }
            }


            Task.Run(() =>
            {
                while (true)
                {
                    if (resumeQueue.Count < 10)
                    {
                        using (var db = new ResumeMatchDBEntities())
                        {
                            var resumeList = db.OldResumeSummary.Where(w => w.ResumeId.Length == 10 && !w.IsMatched && w.Status == 0).Take(1000).ToList();

                            resumeList.ForEach(f =>
                            {
                                resumeQueue.Enqueue(f);
                            });
                        }
                    }

                    Thread.Sleep(TimeSpan.FromSeconds(1));
                }
            });

            for (var j = 0; j < 16; j++)
            {
                Task.Run(() =>
                {
                    using (var db = new ResumeMatchDBEntities())
                    {
                        while (true)
                        {
                            #region 匹配

                            OldResumeSummary resume;

                            if (!resumeQueue.TryDequeue(out resume))
                            {
                                continue;
                            }

                            var startNum = 0;

                            var resumeTemp = resume;

                            resume = db.OldResumeSummary.FirstOrDefault(f => f.Id == resumeTemp.Id);

                            QueueParam cookie;

                            if (!cookieQueue.TryDequeue(out cookie))
                            {
                                return;
                            }

                            try
                            {
                                using (var xdb = new MangningXssDBEntities())
                                {
                                    var filePath = $@"E:\Data\智联招聘\{resume.Template}\{resume.ResumeId}.{Path.GetFileNameWithoutExtension(resume.Template)}";

                                    if (!File.Exists(filePath))
                                    {
                                        LogFactory.Warn($"指定路径不存在!ResumeNumber=>{resume.ResumeId} Path=>{filePath}");

                                        resume.Status = 1;

                                        resume.MatchTime = DateTime.Now;

                                        db.SaveChanges();

                                        continue;
                                    }

                                    var sourceCode = File.ReadAllText(filePath);

                                    //var sourceCode = string.Empty;

                                    var genderMatch = Regex.Match(sourceCode, "(男|女)");

                                    var gender = string.Empty;

                                    if (genderMatch.Success)
                                    {
                                        gender = genderMatch.Value == "男" ? "1" : "2";
                                    }

                                    var matchs = Regex.Matches(sourceCode, "[\u4e00-\u9fa5]{4,11}有限公司[\u4e00-\u9fa5]{0,6}");

                                    var companys = new List <string>();

                                    if (matchs.Count == 0)
                                    {
                                        if (cookie.SeachCount - cookie.WatchCount < 50)
                                        {
                                            Console.WriteLine($"该简历未匹配到公司!ResumeNumber=> {resume.ResumeId}");

                                            resume.Status = 1;

                                            resume.MatchTime = DateTime.Now;

                                            db.SaveChanges();

                                            cookieQueue.Enqueue(cookie);

                                            continue;
                                        }

                                        companys.Add(string.Empty);
                                    }

                                    for (var i = 0; i < matchs.Count; i++)
                                    {
                                        if (i == 2)
                                        {
                                            break;
                                        }

                                        companys.Add(matchs[i].Value);
                                    }

                                    var isMatched = true;

                                    var age = string.Empty;

                                    for (var i = 0; i < companys.Count; i++)
                                    {
                                        var companyName = companys[i];

                                        var statistic = xdb.ZhaopinResumeMatchStatistic.FirstOrDefault(f => f.Date == todayString && f.CompanyId == cookie.CompanyId);

                                        if (statistic == null)
                                        {
                                            continue;
                                        }

                                        var cookieContainer = cookie.Cookie.Serialize(".zhaopin.com");

                                        var start = string.IsNullOrEmpty(companyName) ? startNum * 100 : 0;

                                        var paramDictionary = new Dictionary <string, string>
                                        {
                                            { "keywords", "的" },
                                            { "startNum", $"{start}" },
                                            { "rowsCount", "100" },
                                            { "sortColumnName", "sortUpDate" },
                                            { "sortColumn", "sortUpDate desc" },
                                            { "onlyHasImg", "false" },
                                            { "anyKeyWord", "false" },
                                            { "sex", gender },
                                            { "companyName", companyName },
                                            { "onlyLastWork", "false" },
                                            { "ageStart", age },
                                            { "ageEnd", age }
                                        };

                                        var requestResult = HttpClientFactory.RequestForString("https://ihr.zhaopin.com/resumesearch/search.do", HttpMethod.Post, paramDictionary, cookieContainer);

                                        if (!requestResult.IsSuccess)
                                        {
                                            isMatched = false;

                                            break;
                                        }

                                        var jObject = JsonConvert.DeserializeObject(requestResult.Data) as JObject;

                                        if (jObject["code"] != null)
                                        {
                                            LogFactory.Warn($"CompanyId => {cookie.CompanyId} 搜索异常 异常信息:{(string)jObject["message"]}");

                                            isMatched = false;

                                            return;
                                        }

                                        statistic.SearchCount += 1;

                                        ++cookie.SeachCount;

                                        Console.WriteLine($"CompanyId => {cookie.CompanyId} 搜索公司=> {companyName} 性别=> {genderMatch.Value} 今日请求次数:{cookie.SeachCount} ");

                                        xdb.SaveChanges();

                                        var matchResumes = (JArray)jObject?["results"];

                                        if (matchResumes == null)
                                        {
                                            continue;
                                        }

                                        if (matchResumes.Count == 0)
                                        {
                                            continue;
                                        }

                                        var matchResume = matchResumes.FirstOrDefault(a => ((string)a["number"]).Substring(0, 10) == resume.ResumeId);

                                        var resumes = matchResumes.Where(w => DateTime.Parse((string)w["modifyDate"]) > DateTime.Today.AddDays(-2));

                                        foreach (var item in resumes)
                                        {
                                            var wcount = matchResume == null ? cookie.WatchCount : cookie.WatchCount + 1;

                                            if (cookie.SeachCount <= wcount)
                                            {
                                                break;
                                            }

                                            var number = ((string)item["number"]).Substring(0, 10);

                                            if (xdb.ZhaopinResume.Any(a => a.RandomNumber == number))
                                            {
                                                continue;
                                            }

                                            lock (lockObj)
                                            {
                                                if (xdb.ZhaopinWatchedResume.Any(a => a.ResumeNumber == number))
                                                {
                                                    continue;
                                                }

                                                requestResult = HttpClientFactory.RequestForString($"http://ihr.zhaopin.com/resumesearch/getresumedetial.do?resumeNo={(string)item["id"]}_1&resumeSource=1&key=&{(string)item["valResumeTimeStr"]}", HttpMethod.Get, null, cookieContainer);

                                                if (requestResult.IsSuccess)
                                                {
                                                    var resumeData = JsonConvert.DeserializeObject <dynamic>(requestResult.Data).data;

                                                    var resumeDetail = JsonConvert.DeserializeObject(resumeData.detialJSonStr.ToString());

                                                    var resumeid = resumeData.resumeId != null ? (int)resumeData.resumeId : resumeDetail.ResumeId != null ? (int)resumeDetail.ResumeId : 0;

                                                    statistic.WatchCount += 1;

                                                    Console.WriteLine($"CompanyId => {cookie.CompanyId} 查看简历成功!查看简历份数:{++cookie.WatchCount} ResumeNumber => {number}");

                                                    xdb.ZhaopinWatchedResume.Add(new ZhaopinWatchedResume
                                                    {
                                                        Id           = resumeid,
                                                        ResumeNumber = number,
                                                        CompanyId    = cookie.CompanyId,
                                                        WatchTime    = DateTime.UtcNow
                                                    });

                                                    xdb.SaveChanges();
                                                }
                                            }
                                        }

                                        if (cookie.SeachCount - cookie.WatchCount > 50 && string.IsNullOrEmpty(companyName) && matchResume == null)
                                        {
                                            i--;

                                            if (startNum == 40)
                                            {
                                                if (string.IsNullOrEmpty(age))
                                                {
                                                    age = "18";
                                                }
                                                else
                                                {
                                                    age = (Convert.ToInt32(age) + 1).ToString();
                                                }

                                                startNum = 0;
                                            }
                                            else
                                            {
                                                startNum++;
                                            }

                                            continue;
                                        }

                                        if (matchResume == null)
                                        {
                                            continue;
                                        }

                                        var resumeNo = (string)matchResume["id"] + "_1";

                                        var resumeNumber = ((string)matchResume["number"]).Substring(0, 10);

                                        if (xdb.ZhaopinResume.Any(a => a.RandomNumber == resumeNumber))
                                        {
                                            continue;
                                        }

                                        var valResumeTimeStr = (string)matchResume["valResumeTimeStr"];

                                        requestResult = HttpClientFactory.RequestForString($"http://ihr.zhaopin.com/resumesearch/getresumedetial.do?resumeNo={resumeNo}&resumeSource=1&key=&{valResumeTimeStr}", HttpMethod.Get, null, cookieContainer);

                                        if (!requestResult.IsSuccess)
                                        {
                                            continue;
                                        }

                                        ++cookie.WatchCount;

                                        var resumeJson = JsonConvert.DeserializeObject <dynamic>(requestResult.Data).data;

                                        var detail = JsonConvert.DeserializeObject(resumeJson.detialJSonStr.ToString());

                                        var resumeId = resumeJson.resumeId != null ? (int)resumeJson.resumeId : detail.ResumeId != null ? (int)detail.ResumeId : 0;

                                        if (xdb.ZhaopinMatchedResume.Any(a => a.Id == resumeId))
                                        {
                                            statistic.MatchedCount += 1;

                                            LogFactory.Warn($"匹配到重复简历!ResumeId=>{resumeId} ResumeNumber=>{resumeNumber}");

                                            continue;
                                        }

                                        if (resumeId == 0)
                                        {
                                            LogFactory.Warn($"CompanyId => {cookie.CompanyId} 解析异常!ResumeId 为空, ResumeNumber:{resumeNumber}");

                                            continue;
                                        }

                                        var userId = (int)resumeJson.userDetials.userMasterId;

                                        var user = xdb.ZhaopinUser.FirstOrDefault(f => f.Id == userId);

                                        if (user != null)
                                        {
                                            if (!user.Source.Contains("MANUAL"))
                                            {
                                                user.Id         = userId;
                                                user.Source     = "XSS";
                                                user.ModifyTime = BaseFanctory.GetTime((string)detail.DateModified).ToUniversalTime();
                                                user.CreateTime = BaseFanctory.GetTime((string)detail.DateCreated).ToUniversalTime();
                                                user.Cellphone  = resume.Cellphone;
                                                user.Email      = resume.Email;
                                                user.Name       = resumeJson.userDetials.userName.ToString();
                                                user.UpdateTime = DateTime.UtcNow;
                                                user.Username   = resumeJson.userDetials.email.ToString();
                                            }
                                        }
                                        else
                                        {
                                            xdb.ZhaopinUser.Add(new ZhaopinUser
                                            {
                                                Id         = userId,
                                                Source     = "XSS",
                                                ModifyTime = BaseFanctory.GetTime((string)detail.DateModified).ToUniversalTime(),
                                                CreateTime = BaseFanctory.GetTime((string)detail.DateCreated).ToUniversalTime(),
                                                Cellphone  = resume.Cellphone,
                                                Email      = resume.Email,
                                                Name       = resumeJson.userDetials.userName.ToString(),
                                                UpdateTime = DateTime.UtcNow
                                            });
                                        }

                                        var resumeEntity = xdb.ZhaopinResume.FirstOrDefault(f => f.Id == resumeId);

                                        if (resumeEntity == null)
                                        {
                                            xdb.ZhaopinResume.Add(new ZhaopinResume
                                            {
                                                Id             = resumeId,
                                                RandomNumber   = resumeNumber,
                                                UserId         = userId,
                                                RefreshTime    = BaseFanctory.GetTime((string)detail.DateModified).ToUniversalTime(),
                                                UpdateTime     = DateTime.UtcNow,
                                                UserExtId      = detail.UserMasterExtId.ToString(),
                                                DeliveryNumber = resumeEntity?.DeliveryNumber,
                                                Source         = resumeEntity == null ? "XSS" : resumeEntity.Source
                                            });
                                        }
                                        else
                                        {
                                            resumeEntity.RandomNumber   = resumeNumber;
                                            resumeEntity.UserId         = userId;
                                            resumeEntity.RefreshTime    = BaseFanctory.GetTime((string)detail.DateModified).ToUniversalTime();
                                            resumeEntity.UpdateTime     = DateTime.UtcNow;
                                            resumeEntity.UserExtId      = detail.UserMasterExtId.ToString();
                                            resumeEntity.DeliveryNumber = resumeEntity?.DeliveryNumber;
                                            resumeEntity.Source         = resumeEntity == null ? "XSS" : resumeEntity.Source;
                                        }

                                        var path = $"{ConfigurationManager.AppSettings["Resume.SavePath"]}{DateTime.Now:yyyyMMdd}";

                                        if (!Directory.Exists(path))
                                        {
                                            Directory.CreateDirectory(path);
                                        }

                                        var resumePath = $@"{path}\{resumeId}.json";

                                        resumeJson.userDetials.email = resume.Email;

                                        resumeJson.userDetials.mobilePhone = resume.Cellphone;

                                        File.WriteAllText(resumePath, JsonConvert.SerializeObject(resumeJson));

                                        uploadOssActionBlock.Post(resumePath);

                                        statistic.MatchedCount += 1;

                                        Console.WriteLine($"CompanyId => {cookie.CompanyId} 搜索简历成功!匹配成功 {++cookie.MatchCount} 份, ResumeNumner=>{resumeNumber},ResumeId=>{resumeId}");

                                        xdb.ZhaopinMatchedResume.Add(new ZhaopinMatchedResume
                                        {
                                            Id        = resumeId,
                                            CompanyId = cookie.CompanyId,
                                            MatchTime = DateTime.UtcNow
                                        });

                                        xdb.SaveChanges();

                                        resume.IsMatched = true;

                                        break;
                                    }

                                    if (cookie.SeachCount < cookie.DailySeachCount)
                                    {
                                        cookieQueue.Enqueue(cookie);
                                    }

                                    if (isMatched)
                                    {
                                        resume.Status = 99;

                                        resume.MatchTime = DateTime.Now;
                                    }

                                    db.SaveChanges();
                                }
                            }
                            catch (Exception ex)
                            {
                                //while (true)
                                //{
                                //    if(ex.InnerException == null) break;

                                //    ex = ex.InnerException;
                                //}

                                if (cookie.SeachCount < cookie.DailySeachCount)
                                {
                                    cookieQueue.Enqueue(cookie);
                                }

                                LogFactory.Warn($"程序异常, 异常信息:{ex.Message} 堆栈:{ex.StackTrace}");
                            }

                            #endregion
                        }
                    }
                });
            }
        }
        public void Buquan()
        {
            var queue = new ConcurrentQueue <KeyValuePair <int, KeyValuePair <string, DateTime> > >();

            var index = 0;

            Task.Run(() =>
            {
                while (true)
                {
                    KeyValuePair <int, KeyValuePair <string, DateTime> > temp;

                    if (!queue.TryDequeue(out temp))
                    {
                        Thread.Sleep(10);

                        continue;
                    }

                    using (var db = new MangningXssDBEntities())
                    {
                        var resume = db.ZhaopinResume.FirstOrDefault(f => f.Id == temp.Key);

                        if (resume == null)
                        {
                            LogFactory.Warn($"找不到简历 ResumeId =>{temp.Key}");

                            continue;
                        }

                        var user = db.ZhaopinUser.FirstOrDefault(f => f.Id == resume.UserId);

                        if (user == null)
                        {
                            LogFactory.Warn($"找不到用户  ResumeId =>{temp.Key} UserId =>{resume.UserId}");

                            continue;
                        }

                        if (string.IsNullOrEmpty(temp.Value.Key) && string.IsNullOrEmpty(user.Cellphone))
                        {
                            db.ZhaopinResume.Remove(resume);

                            db.ZhaopinUser.Remove(user);

                            Console.WriteLine($"删除成功!ResumeId=>{temp.Key} {++index}/{buquanTotal}");
                        }
                        else
                        {
                            resume.UserExtId = temp.Value.Key;

                            user.CreateTime = temp.Value.Value;

                            Console.WriteLine($"补全成功!{++index}/{buquanTotal}");
                        }

                        db.SaveChanges();
                    }
                }
            });

            using (var db = new MangningXssDBEntities())
            {
                var idArray = db.ZhaopinResume.Where(w => w.Source == "Watch").Select(s => s.Id).ToArray();

                buquanTotal = idArray.Length;

                foreach (var businessId in idArray)
                {
                    try
                    {
                        var streamContent = newOss.GetObject(newBucket, $"WatchResume/{businessId}").Content;

                        using (var stream = new MemoryStream())
                        {
                            var bytes = new byte[1024];

                            int len;

                            while ((len = streamContent.Read(bytes, 0, bytes.Length)) > 0)
                            {
                                stream.Write(bytes, 0, len);
                            }

                            var jsonContent = Encoding.UTF8.GetString(GZip.Decompress(stream.ToArray()));

                            var resumeData = JsonConvert.DeserializeObject <dynamic>(jsonContent);

                            var resumeDetail = JsonConvert.DeserializeObject <dynamic>((string)resumeData.detialJSonStr);

                            var createDate = BaseFanctory.GetTime((string)resumeDetail.DateCreated).ToUniversalTime();

                            var extId = resumeDetail.UserMasterExtId.ToString();

                            queue.Enqueue(new KeyValuePair <int, KeyValuePair <string, DateTime> >(businessId, new KeyValuePair <string, DateTime>(extId, createDate)));
                        }
                    }
                    catch (Exception ex)
                    {
                        LogFactory.Warn($"Oss 获取简历异常! ResumeId => {businessId} 异常原因 => {ex.Message}");

                        queue.Enqueue(new KeyValuePair <int, KeyValuePair <string, DateTime> >(businessId, new KeyValuePair <string, DateTime>("", DateTime.Now)));
                    }
                }
            }
        }
Beispiel #30
0
        private void ImportDodiInfo()
        {
            var businessManagement = new BusinessManagement();

            //var document = new HtmlAgilityPack.HtmlDocument();

            //document.LoadHtml(File.ReadAllText(@"D:\Badoucai\Dodi\2363\2363038\Mian_2363038.txt"));

            //var userInfo = businessManagement.FormatUserInfomation(document);

            //var business = businessManagement.FormatBusiness(document);

            var pathQueue = new ConcurrentQueue <string>();

            var filePathQueue = new ConcurrentQueue <string>();

            var count = 0;

            var index = 0;

            var pathList = Directory.GetDirectories(@"D:\Badoucai\Dodi\").ToList();

            //pathList.Reverse();

            pathList.ForEach(t => pathQueue.Enqueue(t));

            Task.Run(() =>
            {
                while (true)
                {
                    if (filePathQueue.Count > 1000)
                    {
                        continue;
                    }

                    string path;

                    if (!pathQueue.TryDequeue(out path))
                    {
                        continue;
                    }

                    var files = Directory.GetFiles(path, "*", SearchOption.AllDirectories);

                    count += files.Length;

                    files.ToList().ForEach(t => filePathQueue.Enqueue(t));
                }
            });

            for (var i = 0; i < 16; i++)
            {
                Task.Run(() =>
                {
                    while (true)
                    {
                        string path;

                        if (!filePathQueue.TryDequeue(out path))
                        {
                            continue;
                        }

                        try
                        {
                            var document = new HtmlAgilityPack.HtmlDocument();

                            document.LoadHtml(File.ReadAllText(path));

                            try
                            {
                                var userInfo = businessManagement.FormatUserInfomation(document);

                                var business = businessManagement.FormatBusiness(document);

                                using (var db = new MangningXssDBEntities())
                                {
                                    db.DodiUserInfomation.AddOrUpdate(a => a.Id, userInfo);

                                    db.DodiBusiness.AddOrUpdate(a => a.Id, business);

                                    try
                                    {
                                        db.TransactionSaveChanges();
                                    }
                                    catch (Exception ex)
                                    {
                                        while (true)
                                        {
                                            if (ex.InnerException == null)
                                            {
                                                break;
                                            }

                                            ex = ex.InnerException;
                                        }

                                        Program.SetLog(this.tbx_Log, $"多迪信息SaveChanges异常!异常文件路径:{path}, {ex.Message}");

                                        LogFactory.Warn($"多迪信息SaveChanges异常!异常文件路径:{path}, {ex.Message}");
                                    }
                                }
                            }
                            catch (Exception ex)
                            {
                                continue;
                            }

                            var indexTemp = Interlocked.Increment(ref index);

                            var destPath = path.Replace("Dodi", "Dodi-Success");

                            var destDirectoryPath = Path.GetDirectoryName(destPath);

                            if (!string.IsNullOrEmpty(destDirectoryPath) && !Directory.Exists(destDirectoryPath))
                            {
                                Directory.CreateDirectory(destDirectoryPath);
                            }

                            if (File.Exists(destPath))
                            {
                                File.Delete(destPath);
                            }

                            File.Move(path, destPath);

                            RunInMainthread(() =>
                            {
                                Program.SetLog(this.tbx_Log, $"导入成功!进度:{indexTemp}/{count} {Path.GetFileNameWithoutExtension(path)}");
                            });
                        }
                        catch (Exception ex)
                        {
                            RunInMainthread(() =>
                            {
                                Program.SetLog(this.tbx_Log, $"多迪信息导入异常!异常文件路径:{path}, {ex.Message}");
                            });

                            LogFactory.Warn($"多迪信息导入异常!异常文件路径:{path}, {ex.Message}{Environment.NewLine}{ex.StackTrace}");
                        }
                    }
                });
            }
        }