Commit e729ebc3 authored by 罗超's avatar 罗超

初始化

parents
Pipeline #131 canceled with stages
bin/
obj/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TicketSpider.Agent
{
public class AgentService
{
}
}
using Newtonsoft.Json.Linq;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TicketSpider.Model;
using TicketSpider.Spiders.EasterLineRule;
using TicketSpider.Uitls;
namespace TicketSpider.Data
{
public class FlightFlow
{
private JArray TARGET_FLIGHT = new JArray();
public async void StartAsync()
{
Console.WriteLine("进入东航刷票模块,开始计算需求.......");
Console.WriteLine("开始模拟登录信息.......");
string loginCookies = AccountManagerHelper.GetInstance();
if (!string.IsNullOrEmpty(loginCookies) && !TaskHelper.cancelTokenSource.IsCancellationRequested)
{
Console.WriteLine("获取登录信息成功, 开始操作乘客信息");
await Task.Run(() => new PassengerHelper().RegistPassengerHandler());
Thread.Sleep(2000);
Console.WriteLine("乘客信息处理完毕,开始执行寻票...");
if (CmdHelper.FLIGHTS.Count == 1)
{
if (CmdHelper.FLIGHTS.FirstOrDefault().DepartDateMode == 1)
{
Task.Factory.StartNew(() => QueryTicketHandler(CmdHelper.FLIGHTS.FirstOrDefault().DepartDate), TaskHelper.cancelTokenSource.Token);
}
else if (CmdHelper.FLIGHTS.FirstOrDefault().DepartDateMode == 2)
{
var dates=CmdHelper.FLIGHTS.FirstOrDefault().DepartDate.Split("~");
var dt1 = DateTime.Parse(dates[0]);
var dt2 = DateTime.Parse(dates[1]);
while (true)
{
Task.Factory.StartNew(() => QueryTicketHandler(dt1.ToString("yyyy-MM-dd")), TaskHelper.cancelTokenSource.Token);
dt1.AddDays(1);
if (dt1 > dt2) break;
}
}
else if (CmdHelper.FLIGHTS.FirstOrDefault().DepartDateMode == 3)
{
var dates = CmdHelper.FLIGHTS.FirstOrDefault().DepartDate;
var dt1 = DateTime.Parse($"{dates}-01");
while (true)
{
Task.Factory.StartNew(() => QueryTicketHandler(dt1.ToString("yyyy-MM-dd")), TaskHelper.cancelTokenSource.Token);
dt1.AddDays(1);
if (dt1.ToString("yyyy/MM") != dates) break;
}
}
}
}
else
{
Console.WriteLine("获取登录信息失败,程序退出...");
Environment.Exit(0);
}
}
public async void QueryTicketHandler(string date)
{
//Setup 2:获取航班数据
var flight = new QueryFlightHelper(0.1M).RunAsync(date).Result;
if (!TaskHelper.cancelTokenSource.IsCancellationRequested) return;
Console.WriteLine("获取机票信息完毕");
Thread.Sleep(1000);
//Setup 4 创建订单
Console.WriteLine("开始创建订单...");
var orderSubmit = await new TicketOrderHelper().RunAsync(flight);
if (!TaskHelper.cancelTokenSource.IsCancellationRequested) return;
if (orderSubmit.result)
{
//Setup 5 弹出付款链接
Console.WriteLine("订单创建成功,正在准备付款页面");
OpenOrderPayPageHandler(orderSubmit.order);
}
else
{
Console.WriteLine("订单提交失败....程序退出");
TaskHelper.GetInstance().UnLockOrderStatus(); //释放锁定
}
}
public void OpenOrderPayPageHandler(JObject order)
{
var flag = false;
ReadOnlyCollection<IWebElement> inputEle = null;
var option = new ChromeOptions();
//option.AddArgument("--incognito");
//option.AddArgument("headless");
option.AddArgument("disable-infobars");
//option.AddArgument("window-size=1920,1080");
//option.AddArgument("user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36");
ChromeDriverService service = ChromeDriverService.CreateDefaultService(Environment.CurrentDirectory);
service.HideCommandPromptWindow = true;
option.PageLoadStrategy = PageLoadStrategy.Eager;
IWebDriver driver = new ChromeDriver(service, option);
var cookies = AccountManagerHelper.GetInstance().Split(";");
driver.Navigate().GoToUrl("https://www.ceair.com/");
Thread.Sleep(2000);
driver.Manage().Cookies.DeleteAllCookies();
foreach (var item in cookies)
{
driver.Manage().Cookies.AddCookie(new Cookie(item.Split("=")[0], item.Split("=")[1]));
}
var param= $"{{\"tdOrderNo\":\"{order["tdOrderNo"].ToString()}\",\"t\":{DateTime.Now.Ticks}}}";
param = Convert.ToBase64String(Encoding.UTF8.GetBytes(param));
param = System.Web.HttpUtility.UrlEncode(param);
driver.Navigate().GoToUrl($"https://www.ceair.com/payment?searchKey={param}ENCODEKEY");
//通知流程结束
TaskHelper.cancelTokenSource.Cancel();
AccountManagerHelper.StopHeartLine();
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TicketSpider.Model
{
public class City
{
public string cityCode { get; set; }
public string cityName { get; set; }
public string firstLetterCn { get; set; }
public string firstLetterEn { get; set; }
public string group { get; set; }
public int isHotArr { get; set; }
public int isHotDep { get; set; }
public string label { get; set; }
public string match { get; set; }
public string nc { get; set; }
public int orderArr { get; set; }
public int orderDep { get; set; }
public string value { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TicketSpider.Model
{
[Serializable]
public class FavorPaxIdDtoList
{
public string id { get; set; }
public string favorPaxId { get; set; }
public string idIssueNation { get; set; }
public string idNo { get; set; }
public string idType { get; set; }
public string idValidDt { get; set; }
public string paxIDType { get; set; }
public string paxYouxiaoqi { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TicketSpider.Model
{
[Serializable]
public class Flight
{
public string? DepartCity { get; set; }
public string? ArriveCity { get; set; }
public int? DepartDateMode { get; set; }
public string? DepartDate { get; set; }
public string? AirlineCode { get; set; }
public string? SeatCode { get; set; }
public string arrCityCode { get; set; }
public string arrCode { get; set; }
public string depCityCode { get; set; }
public string depCode { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TicketSpider.Model
{
[Serializable]
public class Passenger
{
public string id { get; set; }
public string paxName { get; set; }
public string paxNameFirst { get; set; }
public string paxNameLast { get; set; }
public string gender { get; set; }
public string birthday { get; set; }
public string nationality { get; set; }
public string telephoneCode { get; set; }
public string mobile { get; set; }
public string email { get; set; }
public List<FavorPaxIdDtoList> favorPaxIdDtoList { get; set; }
public string ffpAirline { get; set; }
public string ffpNo { get; set; }
public string paxType { get; set; }
}
}
// See https://aka.ms/new-console-template for more information
using Newtonsoft.Json;
using TicketSpider.Data;
using TicketSpider.Model;
using TicketSpider.Spiders;
using TicketSpider.Uitls;
ThreadPool.SetMaxThreads(255, 255);
ThreadPool.SetMinThreads(255, 255);
#region 初始化城市信息
if (!CityService.Load())
{
Console.WriteLine("初始化城市信息失败,检查相关文件");
return;
}
#endregion
#region 航司选择
var airLines = new string[] { "E", "C" };
while (true)
{
Console.WriteLine("请选择要执行的航司,E:东航;C:国航,多个航司使用英语逗号相隔(E,C)");
var airlineStr = Console.ReadLine();
if (!string.IsNullOrEmpty(airlineStr))
{
var airlineIpt = airlineStr.Split(",");
var except = airlineIpt.Except(airLines);
if (except == null || !except.Any())
{
CmdHelper.AIRLINE = airlineIpt;
break;
}
}
Console.WriteLine("输入有误,重新输入");
}
#endregion
#region 命令模式
while (true)
{
Console.WriteLine("请选择命令模式(1 步骤模式,2 命令行模式)");
var modes = new int[] { 1,2};
var mode = Console.ReadLine();
if (!string.IsNullOrEmpty(mode)&&int.TryParse(mode,out CmdHelper.CMD_MODEL))
{
if (modes.Contains(CmdHelper.CMD_MODEL))
{
break;
}
}
Console.WriteLine("输入有误,重新输入");
}
#endregion
#region 步骤命令模式
if (CmdHelper.CMD_MODEL == 1)
{
#region 输入航段
while (true)
{
var model = new Flight();
//出发与目的地
while (true)
{
Console.WriteLine($"请输入航段{CmdHelper.FLIGHTS.Count() + 1}的出发城市与目的城市,使用'-'相隔。(成都-巴黎)");
var cits = Console.ReadLine();
if (!string.IsNullOrEmpty(cits) && cits.Split("-").Length == 2)
{
if (!CityService.Container(cits.Split("-")[0]))
{
Console.WriteLine($"{cits.Split("-")[0]},没有找到机场信息,请重新输入");
}
else if (!CityService.Container(cits.Split("-")[1]))
{
Console.WriteLine($"{cits.Split("-")[1]},没有找到机场信息,请重新输入");
}
else
{
model.DepartCity = cits.Split("-")[0];
model.ArriveCity = cits.Split("-")[1];
break;
}
}
Console.WriteLine("输入错误,重新输入");
}
//日期
while (true)
{
Console.WriteLine($"请输入航段{CmdHelper.FLIGHTS.Count() + 1}出发日期,(单日:2022/05/01,范围:2022/05/01-2022/07/01,月份:2022/07)");
var dateStr = Console.ReadLine();
var dtNow = DateTime.Now;
if (dateStr.Contains("-") && dateStr.Split("-").Length == 2)
{
var dates = dateStr.Split("-");
if (DateTime.TryParse(dates[0], out dtNow) && DateTime.TryParse(dates[1], out dtNow))
{
model.DepartDate = dateStr.Replace("-","~");
model.DepartDateMode = 2;
break;
}
}
else
{
var dates = dateStr.Split("/");
if ((dates.Length == 3 || dates.Length == 2) && DateTime.TryParse(dateStr, out dtNow))
{
model.DepartDate = dateStr;
model.DepartDateMode = dates.Length == 3 ? 1 : 3;
break;
}
}
Console.WriteLine("输入错误,重新输入");
}
//航班
Console.WriteLine($"请输入航段{CmdHelper.FLIGHTS.Count() + 1}需要指定的航班(如:3U8633, 没有直接回车)");
model.AirlineCode = Console.ReadLine() ?? string.Empty;
Console.WriteLine($"请输入航段{CmdHelper.FLIGHTS.Count() + 1}需要指定的仓位代码,多个使用英文逗号相隔(如:\"Y\" \"C,Y\", 没有直接回车)");
model.SeatCode= Console.ReadLine() ?? string.Empty;
CmdHelper.FLIGHTS.Add(model);
var isContinu = false;
while (true)
{
Console.WriteLine($"航段{CmdHelper.FLIGHTS.Count()}添加成功,是否继续添加航段? (Y:继续添加/n:不添加)");
var continu=Console.ReadLine()?? string.Empty;
if (continu == "Y" || continu == "n")
{
isContinu = continu == "Y";
break;
}
Console.WriteLine("输入错误,重新输入");
}
if (!isContinu) break;
}
#endregion
#region 添加乘客
while (true)
{
var model = new Passenger();
while (true)
{
Console.WriteLine($"请输入乘客{CmdHelper.PASSENGETS.Count + 1}的英文姓名(LIU/DONG)");
var name=Console.ReadLine()?? string.Empty;
if (name.Split("/").Length == 2)
{
model.paxNameFirst = name.Split("/")[0];
model.paxNameLast = name.Split("/")[1];
break;
}
Console.WriteLine("输入错误,重新输入");
}
while (true)
{
Console.WriteLine($"请输入乘客{CmdHelper.PASSENGETS.Count + 1}的性别(M 男,F 女)");
var name = Console.ReadLine() ?? string.Empty;
if (name == "M" || name == "F")
{
model.gender = name;
break;
}
Console.WriteLine("输入错误,重新输入");
}
while (true)
{
Console.WriteLine($"请输入乘客{CmdHelper.PASSENGETS.Count + 1}生日 (2022/01/01)");
var name = Console.ReadLine() ?? string.Empty;
var dtnow=DateTime.Now;
if (DateTime.TryParse(name,out dtnow))
{
model.birthday = name;
break;
}
Console.WriteLine("输入错误,重新输入");
}
while (true)
{
Console.WriteLine($"请输入乘客{CmdHelper.PASSENGETS.Count + 1}联系电话 (13080808080)");
var name = Console.ReadLine() ?? string.Empty;
if (name.Length==11)
{
model.mobile = name;
break;
}
Console.WriteLine("输入错误,重新输入");
}
while (true)
{
Console.WriteLine($"请输入乘客{CmdHelper.PASSENGETS.Count + 1}护照号和护照有效期 (EH36523023 2029/08/18)");
var name = (Console.ReadLine() ?? string.Empty).Split(" ");
var dtNow=DateTime.Now;
if (name.Length == 2 && name[0].Length>6 && DateTime.TryParse(name[1],out dtNow))
{
model.favorPaxIdDtoList = new List<FavorPaxIdDtoList>() {
new FavorPaxIdDtoList()
{
idType="PP",
idNo=name[0],
paxYouxiaoqi=name[1]
}
};
break;
}
Console.WriteLine("输入错误,重新输入");
}
CmdHelper.PASSENGETS.Add(model);
var isContinu = false;
while (true)
{
Console.WriteLine($"乘客{CmdHelper.PASSENGETS.Count()}添加成功,是否继续添加乘客? (Y:继续添加/n:不添加)");
var continu = Console.ReadLine() ?? string.Empty;
if (continu == "Y" || continu == "n")
{
isContinu = continu == "Y";
break;
}
Console.WriteLine("输入错误,重新输入");
}
if (!isContinu) break;
}
#endregion
}
#endregion
#region 命令行模式
if (CmdHelper.CMD_MODEL == 2)
{
while (true)
{
Console.WriteLine("请输入命令行,如果需要帮助请输入“H”");
var cmd = Console.ReadLine();
if (cmd == "H")
{
while (true)
{
Console.WriteLine("请选择你需要的帮助信息序号:");
Console.WriteLine("1. 单航段单人机票命令说明");
Console.WriteLine("2. 单航段多人机票命令说明");
Console.WriteLine("3. 多航段单人机票命令说明");
Console.WriteLine("4. 多航段多人机票命令说明");
Console.WriteLine("退出输入:“Q”");
var input = Console.ReadLine();
var keys = new string[] { "1", "2", "3", "4", "Q" };
if (keys.Contains(input))
{
if (input == "1")
{
Console.WriteLine("");
Console.WriteLine("");
Console.WriteLine("***************************单航段单人机票命令说明开始***************************");
Console.WriteLine("");
Console.WriteLine("指定航班和仓位:洛杉矶/北京 2022/05/01~2022/07/31 3U8633 Y-LUO/CHAO 男 1990/12/26 17308037817 EP2020158 2028/05/18");
Console.WriteLine("");
Console.WriteLine("不指定航班,指定仓位:洛杉矶/北京 2022/05/01~2022/07/31 Y-LUO/CHAO 男 1990/12/26 17308037817 EP2020158 2028/05/18");
Console.WriteLine("");
Console.WriteLine("不指定航班和仓位:洛杉矶/北京 2022/05/01~2022/07/31 -LUO/CHAO 男 1990/12/26 17308037817 EP2020158 2028/05/18");
Console.WriteLine("");
Console.WriteLine("命令解析:出发地/目的地 出发日期 航班(不指定留空)仓位(不指定留空)-(表示链接乘客信息) 乘客英文名 性别 生日 电话 护照号 护照到期时间");
Console.WriteLine("");
Console.WriteLine("出发日期说明:单日:2022/05/01,范围:2022/05/01~2022/07/01,月份:2022/07");
Console.WriteLine("");
Console.WriteLine("注意:乘客信息务必准确,以防止开票信息不正确");
Console.WriteLine("");
Console.WriteLine("***************************单航段单人机票命令说明结束***************************");
Console.WriteLine("");
}
else if (input == "2")
{
Console.WriteLine("");
Console.WriteLine("");
Console.WriteLine("***************************单航段多人机票命令说明开始***************************");
Console.WriteLine("");
Console.WriteLine("指定航班和仓位:洛杉矶/北京 2022/05/01~2022/07/31 3U8633 Y-LUO/CHAO 男 1990/12/26 17308037817 EP2020158 2028/05/18,HUANG/KUI 男 1989/02/08 13551126755 EP0218030 2028/02/07");
Console.WriteLine("");
Console.WriteLine("不指定航班,指定仓位:洛杉矶/北京 2022/05/01~2022/07/31 Y-LUO/CHAO 男 1990/12/26 17308037817 EP2020158 2028/05/18,HUANG/KUI 男 1989/02/08 13551126755 EP0218030 2028/02/07");
Console.WriteLine("");
Console.WriteLine("不指定航班和仓位:洛杉矶/北京 2022/05/01~2022/07/31 -LUO/CHAO 男 1990/12/26 17308037817 EP2020158 2028/05/18,HUANG/KUI 男 1989/02/08 13551126755 EP0218030 2028/02/07");
Console.WriteLine("");
Console.WriteLine("命令解析:出发地/目的地 出发日期 航班(不指定留空)仓位(不指定留空)-(表示链接乘客信息) 乘客英文名 性别 生日 电话 护照号 护照到期时间,(英文逗号后面继续按照相同格式添加乘客信息)");
Console.WriteLine("");
Console.WriteLine("出发日期说明:单日:2022/05/01,范围:2022/05/01~2022/07/01,月份:2022/07");
Console.WriteLine("");
Console.WriteLine("注意:乘客信息务必准确,以防止开票信息不正确");
Console.WriteLine("");
Console.WriteLine("***************************单航段多人机票命令说明结束***************************");
Console.WriteLine("");
}
else if (input == "3")
{
Console.WriteLine("");
Console.WriteLine("");
Console.WriteLine("***************************多航段航段单人机票命令说明开始***************************");
Console.WriteLine("");
Console.WriteLine("指定航班和仓位:洛杉矶/北京 2022/05/01~2022/07/31 3U8633 Y,北京/成都 2022/05/01~2022/07/31 3U8633 Y-LUO/CHAO 男 1990/12/26 17308037817 EP2020158 2028/05/18");
Console.WriteLine("");
Console.WriteLine("不指定航班,指定仓位:洛杉矶/北京 2022/05/01~2022/07/31 Y,北京/成都 2022/05/01~2022/07/31 Y-LUO/CHAO 男 1990/12/26 17308037817 EP2020158 2028/05/18");
Console.WriteLine("");
Console.WriteLine("不指定航班和仓位:洛杉矶/北京 2022/05/01~2022/07/31 ,北京/成都 2022/05/01~2022/07/31 -LUO/CHAO 男 1990/12/26 17308037817 EP2020158 2028/05/18");
Console.WriteLine("");
Console.WriteLine("命令解析:出发地/目的地 出发日期 航班(不指定留空)仓位(不指定留空),(英文逗号后面继续按照格式添加航班)-(表示链接乘客信息) 乘客英文名 性别 生日 电话 护照号 护照到期时间");
Console.WriteLine("");
Console.WriteLine("出发日期说明:单日:2022/05/01,范围:2022/05/01~2022/07/01,月份:2022/07");
Console.WriteLine("");
Console.WriteLine("注意:乘客信息务必准确,以防止开票信息不正确");
Console.WriteLine("");
Console.WriteLine("***************************多航段航段单人机票命令说明结束***************************");
Console.WriteLine("");
}
else if (input == "4")
{
Console.WriteLine("");
Console.WriteLine("");
Console.WriteLine("***************************多航段航段多人机票命令说明开始***************************");
Console.WriteLine("");
Console.WriteLine("指定航班和仓位:洛杉矶/北京 2022/05/01~2022/07/31 3U8633 Y,北京/成都 2022/05/01~2022/07/31 3U8633 Y-LUO/CHAO 男 1990/12/26 17308037817 EP2020158 2028/05/18,HUANG/KUI 男 1989/02/08 13551126755 EP0218030 2028/02/07");
Console.WriteLine("");
Console.WriteLine("不指定航班,指定仓位:洛杉矶/北京 2022/05/01~2022/07/31 Y,北京/成都 2022/05/01~2022/07/31 Y-LUO/CHAO 男 1990/12/26 17308037817 EP2020158 2028/05/18,HUANG/KUI 男 1989/02/08 13551126755 EP0218030 2028/02/07");
Console.WriteLine("");
Console.WriteLine("不指定航班和仓位:洛杉矶/北京 2022/05/01~2022/07/31 ,北京/成都 2022/05/01~2022/07/31 -LUO/CHAO 男 1990/12/26 17308037817 EP2020158 2028/05/18,HUANG/KUI 男 1989/02/08 13551126755 EP0218030 2028/02/07");
Console.WriteLine("");
Console.WriteLine("命令解析:出发地/目的地 出发日期 航班(不指定留空)仓位(不指定留空),(英文逗号后面继续按照格式添加航班)-(表示链接乘客信息) 乘客英文名 性别 生日 电话 护照号 护照到期时间,(英文逗号后面继续按照相同格式添加乘客信息)");
Console.WriteLine("");
Console.WriteLine("出发日期说明:单日:2022/05/01,范围:2022/05/01~2022/07/01,月份:2022/07");
Console.WriteLine("");
Console.WriteLine("注意:乘客信息务必准确,以防止开票信息不正确");
Console.WriteLine("");
Console.WriteLine("***************************多航段航段多人机票命令说明结束***************************");
Console.WriteLine("");
}
else
{
break;
}
Console.WriteLine("按任意键返回上级...");
Console.ReadKey();
}
else
{
Console.WriteLine("输入错误,请重新输入");
}
}
}
else
{
var cmds = cmd.Split("-");
if (cmds.Length == 2)
{
#region 解析航段
var flights = cmds[0].Split(",");
var flightList = new List<Flight>();
foreach (var flight in flights)
{
var flightInfo = flight.Split(" ");
if (flightInfo.Length == 4 && flightInfo[0].Split("/").Length==2)
{
//验证时间
var dtNow = DateTime.Now;
var flightModel = new Flight();
if (!CityService.Container(flightInfo[0].Split("/")[0]))
{
Console.WriteLine($"{flightInfo[0].Split("/")[0]},没有找到机场信息,请重新输入");
}
else if (!CityService.Container(flightInfo[0].Split("/")[1]))
{
Console.WriteLine($"{flightInfo[0].Split("/")[1]},没有找到机场信息,请重新输入");
}
else
{
flightModel.DepartCity = flightInfo[0].Split("/")[0];
flightModel.ArriveCity = flightInfo[0].Split("/")[1];
flightModel.AirlineCode = flightInfo[2];
flightModel.SeatCode = flightInfo[3];
var dateStr = flightInfo[1];
if (dateStr.Contains("~") && dateStr.Split("~").Length == 2)
{
var dates = dateStr.Split("~");
if (DateTime.TryParse(dates[0], out dtNow) && DateTime.TryParse(dates[1], out dtNow))
{
flightModel.DepartDate = dateStr;
flightModel.DepartDateMode = 2;
flightList.Add(flightModel);
}
}
else
{
var dates = dateStr.Split("/");
if ((dates.Length == 3 || dates.Length == 2) && DateTime.TryParse(dateStr, out dtNow))
{
flightModel.DepartDate = dateStr;
flightModel.DepartDateMode = dates.Length == 3 ? 1 : 3;
flightList.Add(flightModel);
}
}
}
}
}
#endregion
#region 解析乘客信息
var passengers = cmds[1].Split(",");
var passengerList = new List<Passenger>();
//LUO/CHAO 男 1990/12/26 17308037817 EP2020158 2028/05/18
foreach (var passengerStr in passengers)
{
var pList = passengerStr.Split(" ");
if (pList.Length == 6)
{
if (pList[0].Split("/").Length == 2 && (pList[1] == "男" || pList[1] == "女") && DateTime.TryParse(pList[2], out DateTime dt1) && pList[3].Length == 11 && pList[4].Length > 5 && DateTime.TryParse(pList[5], out DateTime dt2))
{
var passenger = new Passenger()
{
id = "",
paxName = "",
paxNameFirst = pList[0].Split("/")[0],
paxNameLast = pList[0].Split("/")[1],
gender = pList[1]=="男"?"M":"F",
birthday = pList[2].Replace("/",""),
nationality = "CN",
telephoneCode = "86",
mobile = pList[3],
email = "",
ffpAirline = "",
ffpNo = "",
favorPaxIdDtoList = new List<FavorPaxIdDtoList>() {
new FavorPaxIdDtoList() {
id="",
favorPaxId="",
idIssueNation="",
idNo=pList[4],
idType="PP",
idValidDt=pList[5],
paxIDType=""
}
},
paxType = ""
};
passengerList.Add(passenger);
}
}
}
#endregion
if (flightList.Count == flights.Length && passengerList.Count == passengers.Length)
{
var flightAllName = string.Empty;
var passNames = string.Empty;
flightList.ForEach(x => {
if (flightList.IndexOf(x) != flightList.Count - 1 || flightList.IndexOf(x)==0) flightAllName += "/" + x.DepartCity;
if (flightList.IndexOf(x) == flightList.Count - 1) flightAllName += "/" + x.ArriveCity;
});
passengerList.ForEach(x => {
passNames += "/" + x.paxNameFirst + x.paxNameLast;
});
Console.WriteLine($"刷票需求识别成功,本次行程为:{flightAllName.Remove(0,1)} {flightList.Count}段航程,本次乘客为:{passNames.Remove(0, 1)} {passengerList.Count}位乘客");
CmdHelper.FLIGHTS = flightList;
CmdHelper.PASSENGETS = passengerList;
break;
}
Console.WriteLine("命令有误,请检查后重新提交");
}
}
Console.WriteLine("");
}
}
#endregion
#region 初始化机场信息
CmdHelper.FLIGHTS.ForEach(x =>
{
var cityDept = CityService.GetCityHandler(x.DepartCity);
var cityArr = CityService.GetCityHandler(x.ArriveCity);
x.depCityCode = cityDept.cityCode;
x.depCode = cityDept.value;
x.arrCityCode = cityArr.cityCode;
x.arrCode = cityArr.value;
});
#endregion
//Task.Run(() => new FlightFlow().StartAsync());
if (CmdHelper.AIRLINE.Contains("E"))
{
Task.Factory.StartNew(() => new FlightFlow().StartAsync(), TaskHelper.cancelTokenSource.Token);
}
if (CmdHelper.AIRLINE.Contains("C"))
{
Console.WriteLine("暂不支持国航机票嗅探");
}
Console.ReadLine();
Environment.Exit(0);
\ No newline at end of file
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TicketSpider.Model;
namespace TicketSpider.Spiders
{
public class CityService
{
public static List<City> CITIES = new List<City>();
public static bool Load()
{
string cityJsonFile = Environment.CurrentDirectory + "\\zh_CN.json";
if (File.Exists(cityJsonFile))
{
using (StreamReader file = File.OpenText(cityJsonFile))
{
using (JsonTextReader reader = new JsonTextReader(file))
{
try
{
var o = (JArray)JToken.ReadFrom(reader);
CITIES = JsonConvert.DeserializeObject<List<City>>(JsonConvert.SerializeObject(o));
return true;
}
catch (Exception){ }
}
}
}
return false;
}
public static City? GetCityHandler(string city)
{
return CITIES.Where(x => x.cityName == city).FirstOrDefault();
}
public static bool Container(string city)
{
return CITIES.Where(x => x.cityName == city).Count() > 0;
}
}
}
using Newtonsoft.Json.Linq;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Interactions;
using OpenQA.Selenium.Remote;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
namespace TicketSpider.Spiders.EasterLineRule
{
public class AccountManagerHelper
{
private static object lockerSafe= new object();
private static string _loginCookies = null;
private static bool _openHeartTimer = false;
public static string _userId = String.Empty;
public static string GetInstance()
{
if (_loginCookies == null)
{
lock (lockerSafe)
{
if (_loginCookies == null)
{
_loginCookies = string.Empty;
var cnt = 0;
while (cnt<4)
{
cnt++;
var result = RunAsync();
if (result && !_openHeartTimer)
{
_openHeartTimer = true;
Task.Run(() => HeartLine());
break;
}
else
{
Console.WriteLine("开始重新尝试登录");
Thread.Sleep(2000);
}
}
}
}
}
return _loginCookies;
}
public static bool RunAsync()
{
var flag = false;
ReadOnlyCollection<IWebElement> inputEle = null;
var option = new ChromeOptions();
option.AddArgument("--incognito");
option.AddArgument("headless");
option.AddArgument("disable-infobars");
option.AddArgument("window-size=1920,1080");
option.AddArgument("user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36");
ChromeDriverService service = ChromeDriverService.CreateDefaultService(Environment.CurrentDirectory);
service.HideCommandPromptWindow = true;
option.PageLoadStrategy = PageLoadStrategy.Eager;
IWebDriver driver = new ChromeDriver(service, option);
try
{
driver.Navigate().GoToUrl($"https://sso.ceair.com/login/?type=ffp&redirectUrl=https%3A%2F%2Fwww.ceair.com%2F&lang=zh_CN");
driver.Manage().Timeouts().PageLoad=TimeSpan.FromSeconds(15);
inputEle = driver.FindElements(By.TagName("input"));
if (inputEle != null && inputEle.Count > 0)
{
inputEle[0].SendKeys("17308037817");
inputEle[1].SendKeys("36925814");
var loginCount = 0;
//开始模拟登录
while (true)
{
loginCount++;
Console.WriteLine($"正在进行第{loginCount}次模拟登录...");
var login = BeginSliderLoginHandler(driver);
if (login.IsCompleted)
{
Console.WriteLine($"操作完成,正在等待结果");
//睡眠1秒,等待跳转
Thread.Sleep(1 * 1000);
if (driver.Url.Contains("sso.ceair.com/login"))
{
Console.WriteLine($"模拟登录失败,准备重新执行...");
IWebElement silderBoxEle = null;
try
{
driver.FindElement(By.CssSelector(".geetest_popup_ghost"));
}
catch (Exception){}
if (silderBoxEle != null)
{
silderBoxEle.Click();
}
if (loginCount == 4)
{
Console.WriteLine("连续4次失败,请检查账号密码是否正确,系统执行完毕");
break;
}
}
else
{
//处理
foreach (var item in driver.Manage().Cookies.AllCookies)
{
_loginCookies += item.Name + "=" + item.Value + ";";
}
_loginCookies = _loginCookies.Substring(0, _loginCookies.Length - 1);
var jscript = (IJavaScriptExecutor)driver;
var userInfo = JObject.Parse((string)jscript.ExecuteScript("return window.sessionStorage.getItem('user')"));
_userId = userInfo["userId"].ToString();
flag = true;
break;
}
}
else
{
Console.WriteLine("未知异常,程序退出");
break;
}
}
}
}
catch (Exception ex)
{
Console.WriteLine($"获取cooki失败,{ex.Message}");
}
driver.Quit();
return flag;
}
public static Task BeginSliderLoginHandler(IWebDriver driver)
{
var buttonEle = driver.FindElement(By.CssSelector(".global-login-btn"));
Thread.Sleep(1000);
//开始登录
buttonEle.Click();
//等待滑块加载
Thread.Sleep(2000);
var bgCanvas = driver.FindElement(By.CssSelector(".geetest_window"));
((IJavaScriptExecutor)driver).ExecuteScript("document.querySelector(\".geetest_canvas_bg\").style.opacity = 1;document.querySelector(\".geetest_canvas_slice\").style.opacity = 0;");
var bgPng = ((ITakesScreenshot)bgCanvas).GetScreenshot();
var dirpath = $"{Environment.CurrentDirectory}\\geetest";
if (!Directory.Exists(dirpath))
{
Directory.CreateDirectory(dirpath);
}
var filePath = $"{dirpath}\\{DateTime.Now.Ticks}.png";
bgPng.SaveAsFile(filePath, ScreenshotImageFormat.Png);
using (Bitmap? bitmap = (Bitmap)Image.FromFile(filePath))
{
var grey = GetGrey(bitmap) / 10 * 3;
var bgX = GetBoundary(bitmap, grey) - 8;
Console.WriteLine($"读取背景缺口边界X坐标: {bgX}");
Actions action = new Actions(driver);
var sliderButton = driver.FindElement(By.CssSelector(".geetest_slider_button"));
if (sliderButton != null)
{
((IJavaScriptExecutor)driver).ExecuteScript("document.querySelector(\".geetest_canvas_bg\").style.opacity = 1;document.querySelector(\".geetest_canvas_slice\").style.opacity = 1;");
action.ClickAndHold(sliderButton).Build().Perform();
#region 开始拟人移动
var d1 = Math.Round(bgX * 0.8);
var d2 = Math.Round(bgX * 0.1);
var d3 = Math.Round(bgX * 0.1);
action.MoveByOffset((int)d1, 1);
Thread.Sleep(new Random().Next(100) + 150);
action.MoveByOffset((int)d2, 1);
Thread.Sleep(new Random().Next(100) + 150);
action.MoveByOffset((int)d3, 1);
action.MoveByOffset((bgX - (int)d1 - (int)d2 - (int)d3), 1);
Thread.Sleep(2000);
#endregion
action.Release(sliderButton);
action.Build().Perform();
Thread.Sleep(5000);
}
}
File.Delete(filePath);
return Task.CompletedTask;
}
private static int GetGrey(Bitmap bmpobj)
{
var rgb = 0;
for (int i = 0; i < bmpobj.Width; i++)
{
for (int j = 0; j < bmpobj.Height; j++)
{
var currentColor = bmpobj.GetPixel(i, j);
var r = currentColor.R + currentColor.G + currentColor.B;
rgb += r;
}
}
return rgb / (bmpobj.Width * bmpobj.Height);
}
private static int GetBoundary(Bitmap bitmap, int level)
{
int lastY = 0, count = 0, outBoundary=0;
for (int i = 0; i < bitmap.Width; i++)
{
for (int j = 0; j < bitmap.Height; j++)
{
var currentColor = bitmap.GetPixel(i, j);
var r = currentColor.R + currentColor.G + currentColor.B;
if (r < level && lastY + 1 == j)
{
count++;
}
else
{
count = 0;
}
lastY = j;
if (count > 6)
{
outBoundary = i;
break;
}
}
if (outBoundary > 0)
{
break;
}
}
return outBoundary;
}
private static void HeartLine()
{
while (_openHeartTimer)
{
var handler = new HttpClientHandler();
handler.AllowAutoRedirect = false;
handler.UseCookies = true;
handler.CookieContainer = CreateCookie();
handler.AutomaticDecompression = DecompressionMethods.GZip;
handler.ClientCertificateOptions = ClientCertificateOption.Automatic;
var http = new HttpClient(handler);
http.GetAsync("https://www.ceair.com/");
//TODO:检查是否需要重新登录
Thread.Sleep(60 * 1000);
}
}
public static void StopHeartLine()
{
_openHeartTimer = false;
}
private static CookieContainer CreateCookie()
{
var uri = new Uri("https://www.ceair.com");
var cc = new CookieContainer();
foreach (var str in _loginCookies.Split(';'))
{
cc.SetCookies(uri, str);
}
return cc;
}
}
}
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TicketSpider.Spiders.EasterLineRule
{
public class CookiesHelper
{
/// <summary>
/// 获取初始化Cookies
/// </summary>
/// <returns></returns>
public Task<string> GetInitCookie()
{
var cookieStr = string.Empty;
var option = new ChromeOptions();
option.AddArgument("--incognito");
option.AddArgument("headless");
option.AddArgument("disable-infobars");
option.AddArgument("window-size=1920,1080");
option.AddArgument("user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36");
ChromeDriverService service = ChromeDriverService.CreateDefaultService(Environment.CurrentDirectory);
service.HideCommandPromptWindow = true;
option.PageLoadStrategy = PageLoadStrategy.Eager;
IWebDriver driver = new ChromeDriver(service, option);
try
{
var param = "{\"travelType\":\"oneway\",\"passengerNum\":\"1,0,0\",\"depCity\":\"BKK\",\"arrCity\":\"SHA\",\"depValues\":\"BKK\",\"arrValues\":\"PVG, SHA\",\"depCityName\":\"曼谷\",\"arrCityName\":\"上海\",\"date\":\"2022-12-11\",\"cabinClass\":\"ALL\",\"payWay\":\"money\",\"depSelectValue\":\"BKK\",\"arrSelectValue\":\"PVG, SHA\",\"depLabel\":\"\",\"arrLabel\":\"\",\"isArrCity\":true,\"isDepCity\":true,\"arrCn\":\"CN\",\"depCn\":\"TH\",\"t\":" + DateTime.Now.Ticks + "}";
param = System.Web.HttpUtility.UrlEncode(param);
param = Convert.ToBase64String(Encoding.UTF8.GetBytes(param));
driver.Navigate().GoToUrl($"https://www.ceair.com/shopping?searchKey={param}ENCODEKEY");
foreach (var item in driver.Manage().Cookies.AllCookies)
{
cookieStr += item.Name + "=" + item.Value + ";";
}
cookieStr = cookieStr.Substring(0, cookieStr.Length - 1);
}
catch (Exception ex)
{
Console.WriteLine($"获取cooki失败,{ex.Message}");
}
driver.Quit();
return Task.FromResult(cookieStr);
}
}
}
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using TicketSpider.Model;
using TicketSpider.Uitls;
namespace TicketSpider.Spiders.EasterLineRule
{
public class PassengerHelper
{
public static List<Passenger> GLOBAL_USERLIST { get; private set; }
public async void RegistPassengerHandler()
{
GLOBAL_USERLIST = new List<Passenger>();
var registResult = await RegistPassenger(CmdHelper.PASSENGETS);
var passengersArray = await IsHavePassenger();
if (passengersArray.Any())
{
var passengers = passengersArray.ToObject<List<Passenger>>();
CmdHelper.PASSENGETS.ForEach(user => {
passengers.ToList().ForEach(x => {
x.favorPaxIdDtoList.ForEach(y =>
{
if (y.idType == user.favorPaxIdDtoList.First().idType && y.idNo == user.favorPaxIdDtoList.First().idNo)
{
y.idValidDt=user.favorPaxIdDtoList[0].idValidDt;
GLOBAL_USERLIST.Add(x);
}
});
});
});
if (GLOBAL_USERLIST.Any())
{
Console.WriteLine("完成乘客信息锁定");
}
else
{
Console.WriteLine("警告:未能绑定乘客信息");
}
}
else
{
Console.WriteLine("警告:未能绑定乘客信息");
}
}
private async Task<bool> RegistPassenger(List<Passenger> userList)
{
JObject passengers = new JObject();
passengers.Add("paxs", JArray.FromObject(userList));
passengers.Add("singleAlone",false);
passengers.Add("deviceId", "");
var paramster=JsonConvert.SerializeObject(passengers);
var request = CreateRequest();
var url = "https://www.ceair.com/portal/v3/customer/addPassenger";
var content = new StringContent(paramster, System.Text.Encoding.UTF8, "application/json");
var response = await request.PostAsync(url, content);
var result = response.Content.ReadAsStringAsync().Result;
if (result.Contains("A200") || result.Contains("U200127"))
{
return true;
}
return false;
}
private async Task<JArray> IsHavePassenger()
{
var request = CreateRequest();
var resloveResult = new JArray();
var url = "https://www.ceair.com/portal/v3/customer/queryPassengerList";
var content = new StringContent("{\"userId\": " + AccountManagerHelper._userId+ ", \"deviceId\": \"\"}", System.Text.Encoding.UTF8, "application/json");
var response = await request.PostAsync(url, content);
var result = response.Content.ReadAsStringAsync().Result;
if (result.Contains("U200"))
{
try
{
resloveResult = JObject.Parse(result)["resultContent"]as JArray;
}
catch (Exception) { }
}
//if (resloveResult.Any())
//{
// Console.WriteLine($"获取乘客信息成功:{JsonConvert.SerializeObject(resloveResult)}");
//}
return resloveResult;
}
private HttpClient CreateRequest()
{
var handler = new HttpClientHandler();
handler.AllowAutoRedirect = false;
handler.UseCookies = true;
handler.CookieContainer = CreateCookie(AccountManagerHelper.GetInstance());
handler.AutomaticDecompression = DecompressionMethods.GZip;
handler.ClientCertificateOptions = ClientCertificateOption.Automatic;
var http = new HttpClient(handler);
CreateRequestHeaders(ref http);
return http;
}
private CookieContainer CreateCookie(string cookieStr)
{
var uri = new Uri("https://www.ceair.com");
var cc = new CookieContainer();
foreach (var str in cookieStr.Split(';'))
{
cc.SetCookies(uri, str);
}
return cc;
}
private void CreateRequestHeaders(ref HttpClient http)
{
var random = new Random();
http.DefaultRequestHeaders.Add("Accept", "application/json, text/plain, */*");
http.DefaultRequestHeaders.Add("Accept-Encoding", "gzip, deflate, br");
http.DefaultRequestHeaders.Add("Accept-Language", "zh-CN,zh;q=0.9");
http.DefaultRequestHeaders.Add("Cache-Control", "no-cache");
//http.DefaultRequestHeaders.Add("Connection", "keep-alive");
//http.DefaultRequestHeaders.Add("Content-Length", "188");
//http.DefaultRequestHeaders.Add("Content-Type", new MediaTypeHeaderValue("application/json"));
//http.DefaultRequestHeaders.Add("Host", "m.ceair.com");
http.DefaultRequestHeaders.Add("Origin", "https://www.ceair.com");
http.DefaultRequestHeaders.Add("Pragma", "no-cache");
http.DefaultRequestHeaders.Add("Referer", "https://www.ceair.com/leftNavigation/personCenter/passengers");
//http.DefaultRequestHeaders.Add("salesChannel", "NzcwMQ==");
http.DefaultRequestHeaders.Add("sec-ch-ua", "\" Not; A Brand\";v=\"99\", \"Google Chrome\";v=\"97\", \"Chromium\";v=\"97\"");
http.DefaultRequestHeaders.Add("sec-ch-ua-mobile", "?0");
http.DefaultRequestHeaders.Add("sec-ch-ua-platform", "\"Windows\"");
http.DefaultRequestHeaders.Add("Sec-Fetch-Dest", "empty");
http.DefaultRequestHeaders.Add("Sec-Fetch-Mode", "cors");
http.DefaultRequestHeaders.Add("Sec-Fetch-Site", "same-origin");
http.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.99 Safari/537.36");
http.DefaultRequestHeaders.Add("x-tingyun-id", $"DuR5xFLm8eI;r={random.Next(100000000, 999999999)}");
http.DefaultRequestHeaders.Add("site", "zh_CN");
http.DefaultRequestHeaders.Add("shakehand", "535206fb27efbaf75066ff179b975ff6");
http.DefaultRequestHeaders.Add("pragma", "no-cache");
}
}
}
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using TicketSpider.Data;
using TicketSpider.Uitls;
namespace TicketSpider.Spiders.EasterLineRule
{
public class QueryFlightHelper
{
private static decimal REQUEST_QPS=2;
private static int INTERVAL_TIMER = 1000;
//public CookieContainer cookieContainer = new CookieContainer();
public QueryFlightHelper(decimal qps = 2)
{
REQUEST_QPS = qps;
INTERVAL_TIMER = (int)(1000 / REQUEST_QPS);
}
public async Task<JObject> RunAsync(string date)
{
var timerCount = 1;
var flightResult = new JObject();
var cookieContainer = new CookieContainer();
CreateCookie(ref cookieContainer);
while (!TaskHelper.cancelTokenSource.IsCancellationRequested)
{
Console.WriteLine($"正在执行第{timerCount}次航班查询请求");
var result = await Action(date,cookieContainer);
timerCount++;
if (result.result.Contains("S200"))
{
var resloveResult = new JArray();
try
{
resloveResult= JObject.Parse(result.result)["data"]["flightItems"] as JArray;
var realFlight = resloveResult.ToList().Where(x => (x["cabinInfoDescs"] as JArray).Any());
if (realFlight.Any())
{
resloveResult = JArray.FromObject(realFlight);
}
else
{
resloveResult.Clear();
}
}
catch (Exception){}
if (resloveResult.Any())
{
while (!TaskHelper.GetInstance().UpdateTicketStatus() && !TaskHelper.cancelTokenSource.IsCancellationRequested)
{
Console.WriteLine("已获取到机票信息,排队中,等待其他线程释放");
Thread.Sleep(1000);
}
if (TaskHelper.cancelTokenSource.IsCancellationRequested) break;
flightResult = JObject.Parse(result.result);
flightResult["data"]["flightItems"] = resloveResult;
break;
}
}
else
{
Console.WriteLine("未找到机票");
var newCookies = result.cookies.Split(';',StringSplitOptions.RemoveEmptyEntries);
if (newCookies.Any())
{
var uri = new Uri("https://www.ceair.com");
foreach (var cookie in newCookies)
{
var haveCookies = cookieContainer.GetAllCookies().Where(x => x.Name == cookie.Split("=")[0]);
if (haveCookies.Any())
{
haveCookies.First().Value = cookie.Split("=")[1];
}
else
{
cookieContainer.SetCookies(uri, cookie);
}
}
}
//TODO 切换代理
}
Thread.Sleep(INTERVAL_TIMER);
}
//Console.WriteLine($"获取到航班数据");
return flightResult;
}
public async Task<(string result,string cookies)> Action(string date,CookieContainer cookieContainer)
{
var result = string.Empty;
var cookies = string.Empty;
try
{
var handler = new HttpClientHandler();
handler.AllowAutoRedirect = false;
handler.UseCookies = true;
handler.CookieContainer = cookieContainer;
handler.AutomaticDecompression = DecompressionMethods.GZip;
handler.ClientCertificateOptions = ClientCertificateOption.Automatic;
var http = new HttpClient(handler);
CreateRequestHeaders(ref http);
var url = "https://www.ceair.com/portal/v3/shopping/briefInfo";
var f = CmdHelper.FLIGHTS.FirstOrDefault();
var paramStr = $"{{\"adultCount\":1,\"arrCityCode\":\"{f.arrCityCode}\",\"arrCode\":\"{f.arrCode}\",\"arrDate\":\"\",\"childCount\":0,\"depCityCode\":\"{f.depCityCode}\",\"depCode\":\"{f.depCode}\",\"depDate\":\"{date.Replace("/","-")}\",\"infantCount\":0,\"routeType\":\"OW\",\"onlyPlaneFlag\":false,\"cabinLevel\":\"\",\"deviceId\":\"\"}}";
var content = new StringContent(paramStr, System.Text.Encoding.UTF8, "application/json");
var response = await http.PostAsync(url, content);
//var setCookies = response.Headers.GetValues("Set-Cookie");
//foreach (var item in setCookies)
//{
// cookies += item + ";";
//}
result = response.Content.ReadAsStringAsync().Result;
}
catch (Exception e)
{
Console.WriteLine($"查询航班发生异常,异常信息如下:{e.Message}");
}
//FlightDataHelper.TARGET_FLIGHT=resu
return (result,cookies);
}
private void CreateCookie(ref CookieContainer cookieContainer)
{
var cookieStr = new CookiesHelper().GetInitCookie().Result;
var uri = new Uri("https://www.ceair.com");
var cc = new CookieContainer();
foreach (var str in cookieStr.Split(';'))
{
cc.SetCookies(uri, str);
}
cookieContainer = cc;
}
private void CreateRequestHeaders(ref HttpClient http)
{
var random = new Random();
http.DefaultRequestHeaders.Add("Accept", "application/json, text/plain, */*");
http.DefaultRequestHeaders.Add("Accept-Encoding", "gzip, deflate, br");
http.DefaultRequestHeaders.Add("Accept-Language", "zh-CN,zh;q=0.9");
http.DefaultRequestHeaders.Add("Cache-Control", "no-cache");
//http.DefaultRequestHeaders.Add("Connection", "keep-alive");
//http.DefaultRequestHeaders.Add("Content-Length", "188");
//http.DefaultRequestHeaders.Add("Content-Type", new MediaTypeHeaderValue("application/json"));
//http.DefaultRequestHeaders.Add("Host", "m.ceair.com");
http.DefaultRequestHeaders.Add("Origin", "https://www.ceair.com");
http.DefaultRequestHeaders.Add("Pragma", "no-cache");
http.DefaultRequestHeaders.Add("Referer", "https://www.ceair.com/shopping?searchKey=JTdCJTIydHJhdmVsVHlwZSUyMiUzQSUyMm9uZXdheSUyMiUyQyUyMnBhc3Nlbmdlck51bSUyMiUzQSUyMjElMkMwJTJDMCUyMiUyQyUyMmRlcENpdHklMjIlM0ElMjJCS0slMjIlMkMlMjJhcnJDaXR5JTIyJTNBJTIyU0hBJTIyJTJDJTIyZGVwVmFsdWVzJTIyJTNBJTIyQktLJTIyJTJDJTIyYXJyVmFsdWVzJTIyJTNBJTIyUFZHJTJDU0hBJTIyJTJDJTIyZGVwQ2l0eU5hbWUlMjIlM0ElMjIlRTYlOUIlQkMlRTglQjAlQjclMjIlMkMlMjJhcnJDaXR5TmFtZSUyMiUzQSUyMiVFNCVCOCU4QSVFNiVCNSVCNyUyMiUyQyUyMmRhdGUlMjIlM0ElMjIyMDIyLTEyLTExJTIyJTJDJTIyY2FiaW5DbGFzcyUyMiUzQSUyMkFMTCUyMiUyQyUyMnBheVdheSUyMiUzQSUyMm1vbmV5JTIyJTJDJTIyZGVwU2VsZWN0VmFsdWUlMjIlM0ElMjJCS0slMjIlMkMlMjJhcnJTZWxlY3RWYWx1ZSUyMiUzQSUyMlBWRyUyQ1NIQSUyMiUyQyUyMmRlcExhYmVsJTIyJTNBJTIyJTIyJTJDJTIyYXJyTGFiZWwlMjIlM0ElMjIlMjIlMkMlMjJpc0FyckNpdHklMjIlM0F0cnVlJTJDJTIyaXNEZXBDaXR5JTIyJTNBdHJ1ZSUyQyUyMmFyckNuJTIyJTNBJTIyQ04lMjIlMkMlMjJkZXBDbiUyMiUzQSUyMlRIJTIyJTJDJTIydCUyMiUzQTE2NTA4NzYwOTA5MjAlN0Q%3DENCODEKEY");
http.DefaultRequestHeaders.Add("salesChannel", "NzcwMQ==");
http.DefaultRequestHeaders.Add("sec-ch-ua", "\" Not; A Brand\";v=\"99\", \"Google Chrome\";v=\"97\", \"Chromium\";v=\"97\"");
http.DefaultRequestHeaders.Add("sec-ch-ua-mobile", "?0");
http.DefaultRequestHeaders.Add("sec-ch-ua-platform", "\"Windows\"");
http.DefaultRequestHeaders.Add("Sec-Fetch-Dest", "empty");
http.DefaultRequestHeaders.Add("Sec-Fetch-Mode", "cors");
http.DefaultRequestHeaders.Add("Sec-Fetch-Site", "same-origin");
http.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.99 Safari/537.36");
http.DefaultRequestHeaders.Add("site", "zh_CN");
http.DefaultRequestHeaders.Add("shakehand", "535206fb27efbaf75066ff179b975ff6");
http.DefaultRequestHeaders.Add("pragma", "no-cache");
}
}
}
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using TicketSpider.Model;
namespace TicketSpider.Spiders.EasterLineRule
{
public class TicketOrderHelper
{
public async Task<(bool result,JObject order)> RunAsync(JObject ticket)
{
var flag = true;
var passengers = PassengerHelper.GLOBAL_USERLIST;
//此步骤直接使用登录后的cookies
FormatPassengers(ticket, ref passengers);
Console.WriteLine("获取航班详情");
//var details = await GetSingleTicketDetailsAsync(ticket, passengers);
//Thread.Sleep(1000);
Console.WriteLine("创建订单模板");
var verifyFlight = new JObject();
var verifyCount = 3;
while (verifyCount>0)
{
verifyFlight = await GetSingleTicketVerifyFlightInfoAsync(ticket, passengers);
if (verifyFlight.ContainsKey("cacheKey"))
{
break;
}
else
{
Console.WriteLine("创建订单模板失败,准备重试");
if (verifyCount == 1)
{
flag = false;
break;
}
}
verifyCount--;
Thread.Sleep(2000);
}
if (!flag) return (false, new JObject());
Thread.Sleep(2000);
Console.WriteLine("获取联系人信息...");
var concats = new JArray();
var contactCnt = 3;
while (contactCnt > 0)
{
concats = await GetListContactAsync();
if (concats.Any())
{
break;
}
else
{
Console.WriteLine("获取联系人信息,准备重试");
if (contactCnt == 1)
{
flag = false;
break;
}
}
contactCnt--;
Thread.Sleep(1000);
}
if (!flag) return (false, new JObject());
Thread.Sleep(1000);
Console.WriteLine("开始创建订单....");
var order = new JObject();
var orderCnt = 3;
while (orderCnt > 0)
{
order = await CreateBookingAsync(ticket, passengers, concats.First() as JObject, verifyFlight["cacheKey"].ToString());
if (order.ContainsKey("resultCode"))
{
break;
}
else
{
Console.WriteLine("创建订单失败,准备重试");
if (orderCnt == 1)
{
flag = false;
break;
}
}
orderCnt--;
Thread.Sleep(1000);
}
if (!flag) return (false, new JObject());
return (true,order);
}
private async Task<JObject> CreateBookingAsync(JObject ticket, List<Passenger> passengers, JObject contact,string tempOrderId)
{
var order = new JObject();
var request = CreateRequest();
var url = "https://www.ceair.com/portal/v3/booking/";
#region 组装参数
var parameters = new JObject();
var firstFlight = ticket["data"]["flightItems"][0];
var flightSegment = firstFlight["flightInfos"][0]["flightSegments"][0];
var cabin = firstFlight["cabinInfoDescs"][0];
var sort = firstFlight["flightInfos"][0]["flightSort"];
parameters.Add("calculateInfo", null);
parameters.Add("channelType", "");
parameters.Add("depDt", $"{flightSegment["fltDate"].ToString()} {flightSegment["orgTime"].ToString()}");
parameters.Add("depDtCode", flightSegment["orgCode"].ToString());
parameters.Add("deviceId", "");
var favorAddress = @"{
'docaAddressType': 'R',
'docaAddress': '',
'docaCity': '',
'docaNationCode': '',
'docaPostcode': '',
'docaState': ''
}";
parameters.Add("favorAddress", JObject.Parse(favorAddress.Replace("'", "\"")));
var favorContact = @$"{{
'name': '{contact["name"].ToString()}',
'mobile': '{contact["mobile"].ToString()}',
'phoneCountry': '86'
}}";
parameters.Add("favorContact", JObject.Parse(favorContact.Replace("'", "\"")));
parameters.Add("inter", "T");
parameters.Add("invoiceInfoList",new JArray());
parameters.Add("jfType","");
parameters.Add("orderDiscountDetail",null);
parameters.Add("points",false);
parameters.Add("seatInfo",null);
parameters.Add("sxtCouponInfo",null);
parameters.Add("tempOrderId", tempOrderId);
parameters.Add("tripType", "OW");
parameters.Add("useCoupons",null);
parameters.Add("userId",AccountManagerHelper._userId);
parameters.Add("xtypes", new JArray());
var favorPassengerList = new JArray();
var docaAddress=new JObject();
docaAddress.Add("addressD", "");
docaAddress.Add("cityD", "");
docaAddress.Add("countryD", "");
docaAddress.Add("stateD", "");
docaAddress.Add("zipD", "");
passengers.ForEach(x => {
var obj = new JObject();
obj.Add("beneficiary", false);
obj.Add("birthday", x.birthday);
obj.Add("cardType", "");
obj.Add("carrierName", null);
obj.Add("cradle", "");
obj.Add("docaAddress", docaAddress);
obj.Add("email", x.email);
obj.Add("gender", x.gender);
obj.Add("idNo", x.favorPaxIdDtoList[0].idNo);
obj.Add("idType", "PP");
obj.Add("member", false);
obj.Add("mileageCard", "");
obj.Add("name", $"{x.paxNameFirst}/{x.paxNameLast}");
obj.Add("natnCd", "CN");
obj.Add("passengerType", x.paxType);
obj.Add("paxHolderFG", "Y");
obj.Add("paxIdDl", DateTime.Now.AddYears(1).ToString("yyyy-MM-dd"));
obj.Add("paxIdNatnCd", "CN");
obj.Add("phoneCountry", "86");
obj.Add("phoneNumber", x.mobile);
obj.Add("secIdNo", null);
obj.Add("secIdType", "");
favorPassengerList.Add(obj);
});
parameters.Add("favorPassengerList", favorPassengerList);
#endregion
var content = new StringContent(JsonConvert.SerializeObject(parameters), System.Text.Encoding.UTF8, "application/json");
var response = await request.PostAsync(url, content);
var result = response.Content.ReadAsStringAsync().Result;
if (result.Contains("S200"))
{
try
{
order = JObject.Parse(result);
}
catch (Exception) { }
}
return order;
}
private string FormatBrithday(string brith)
{
brith = brith.Insert(4, "-");
brith = brith.Insert(7, "-");
return brith;
}
private void FormatPassengers(JObject ticket, ref List<Passenger> passengers)
{
var firstFlight = ticket["data"]["flightItems"][0];
var sort = firstFlight["flightInfos"][0]["flightSort"];
var arrd = sort["depDate"].ToString();
passengers.ForEach(x => {
x.birthday = FormatBrithday(x.birthday);
var age = CalculateAgeCorrect(x.birthday, arrd);
if (age >= 12)
{
x.paxType = "ADT";
}
else if (age >= 2)
{
x.paxType = "CHD";
}
else
{
x.paxType = "INF";
}
});
}
private int CalculateAgeCorrect(string birth,string arrd)
{
DateTime birthDate, now;
birthDate = DateTime.Parse(birth);
now = DateTime.Parse(arrd);
int age = now.Year - birthDate.Year;
if (now.Month < birthDate.Month || (now.Month == birthDate.Month && now.Day < birthDate.Day)) age--;
return age;
}
private async Task<JObject> GetSingleTicketDetailsAsync(JObject ticket, List<Passenger> passengers)
{
var ticketDetails = new JObject();
var request = CreateRequest();
var url = "https://www.ceair.com/portal/v3/shopping/fareDetail";
#region 组装参数
var firstFlight = ticket["data"]["flightItems"][0];
var flightSegment = firstFlight["flightInfos"][0]["flightSegments"][0];
var cabin = firstFlight["cabinInfoDescs"][0];
var sort = firstFlight["flightInfos"][0]["flightSort"];
var paramerter=new JObject();
paramerter.Add("airlineCode", flightSegment["airlineCode"]);
paramerter.Add("cabinCode", cabin["ccode"].ToString());
paramerter.Add("cabinLevel", cabin["fareLevel"].ToString());
paramerter.Add("cacheKey", ticket["cacheKey"].ToString());
paramerter.Add("currency","CNY");
paramerter.Add("departDateTime",$"{sort["depDate"].ToString()} {sort["depTime"].ToString()}");
paramerter.Add("deviceId","");
paramerter.Add("domesticOrInter", firstFlight["flightInfos"][0]["domesticOrInter"]);
paramerter.Add("flightFareIdList", (firstFlight["flightInfos"][0]["flightFareIds"] as JArray));
paramerter.Add("flightInfoIdList",new JArray() { flightSegment["flightInfoId"] });
paramerter.Add("foldingFlag","1");
paramerter.Add("ifReschedule","0");
string intList= @$"
[{{'itnIndex':'1','segInfos':[{{'segIndex': 1,
'oriEng': '{flightSegment["orgCode"].ToString()}',
'desEng': '{flightSegment["destCode"].ToString()}',
'fltDate': '{flightSegment["fltDate"].ToString()}',
'depTime': '{flightSegment["orgTime"].ToString()}',
'arrTime': '{flightSegment["destTime"].ToString()}',
'carrier': '{flightSegment["carrierCode"].ToString()}',
'carrier_o': '{flightSegment["airlineCode"].ToString()}',
'flightNo': '{flightSegment["flightNo"].ToString()}',
'diType': '{flightSegment["domesticOrInter"].ToString()}',
'classLevel': '',
'classCode': '',
'allCabins': '{flightSegment["allCabins"].ToString()}',
'planType': '{flightSegment["planeType"].ToString()}'}}]}}]";
intList = intList.Replace("'", "\"");
paramerter.Add("itnList",JArray.Parse(intList));
paramerter.Add("orgCode", flightSegment["orgCode"].ToString());
int [] pg = new int[3]{ 0, 0, 0 };
passengers.ForEach(x => {
if (x.paxType == "CHD")
{
pg[1] = pg[1] + 1;
}
else if (x.paxType == "INF")
{
pg[2] = pg[2] + 1;
}
else
{
pg[0] = pg[0] + 1;
}
});
paramerter.Add("passengerCount",string.Join(',',pg));
paramerter.Add("priceSource",cabin["fareInfoDescList"][0]["priceSource"].ToString());
paramerter.Add("productCode", cabin["fareInfoDescList"][0]["productCode"].ToString());
paramerter.Add("routeType","OW");
paramerter.Add("segNum",passengers.Count);
paramerter.Add("sequenceId", flightSegment["sequenceId"].ToString());
#endregion
var content = new StringContent(JsonConvert.SerializeObject(paramerter), System.Text.Encoding.UTF8, "application/json");
var response = await request.PostAsync(url, content);
var result = response.Content.ReadAsStringAsync().Result;
if (result.Contains("S200"))
{
try
{
ticketDetails = JObject.Parse(result)["data"] as JObject;
}
catch (Exception) { }
}
return ticketDetails;
}
private async Task<JObject> GetSingleTicketVerifyFlightInfoAsync(JObject ticket, List<Passenger> passengers)
{
var result=new JObject();
var request = CreateRequest();
var url = "https://www.ceair.com/portal/v3/shopping/verifyFlightInfo";
#region 组装参数
var firstFlight = ticket["data"]["flightItems"][0];
var flightSegment = firstFlight["flightInfos"][0]["flightSegments"][0];
var cabin = firstFlight["cabinInfoDescs"][0];
var sort = firstFlight["flightInfos"][0]["flightSort"];
var paramerter = new JObject();
paramerter.Add("cacheKey", ticket["cacheKey"].ToString());
paramerter.Add("checkFareSource", cabin["fareInfoDescList"][0]["priceSource"].ToString());
paramerter.Add("deviceId", "");
paramerter.Add("fId", ticket["fId"].ToString());
var flightItems = @$"[
{{
'depCode': '{flightSegment["orgCode"].ToString()}',
'arrCode': '{flightSegment["destCode"].ToString()}',
'depDt': '{sort["depDate"].ToString()}',
'odType': 0,
'index': 1,
'flightInfoList': [
{{
'depCode': '{flightSegment["orgCode"].ToString()}',
'arrCode': '{flightSegment["destCode"].ToString()}',
'depDt': '{sort["depDate"].ToString()}',
'carrierO': '{flightSegment["carrierCode"].ToString()}',
'flightNoO': '{flightSegment["carrierNo"].ToString()}',
'carrier': '{flightSegment["airlineCode"].ToString()}',
'flightNo': '{flightSegment["flightNo"].ToString()}',
'depTime': '{flightSegment["orgTime"].ToString()}',
'arriveTime': '{flightSegment["destTime"].ToString()}',
'arriveDate': '{flightSegment["arriDate"].ToString()}',
'sequenceId': '{flightSegment["sequenceId"].ToString()}',
'tripId': null,
'cabin': '{cabin["ccode"].ToString()}',
'pricePointId': null
}}
]
}}
]";
flightItems = flightItems.Replace("'", "\"");
paramerter.Add("flightItems", JArray.Parse(flightItems));
paramerter.Add("flightType", flightSegment["domesticOrInter"].ToString());
paramerter.Add("ifReschedule", "0");
paramerter.Add("originalRoute", null);
paramerter.Add("routeType", "OW");
paramerter.Add("searchOneFlag", false);
paramerter.Add("shoppingKey", null);
int[] pg = new int[3] { 0, 0, 0 };
passengers.ForEach(x => {
if (x.paxType == "CHD")
{
pg[1] = pg[1] + 1;
}
else if (x.paxType == "INF")
{
pg[2] = pg[2] + 1;
}
else
{
pg[0] = pg[0] + 1;
}
});
var preference = @$"{{
'adtCount': {pg[0]},
'chdCount': {pg[1]},
'infCount': {pg[2]},
'currencyCode': 'CNY',
'productCode': '{cabin["fareInfoDescList"][0]["productCode"].ToString()}',
'brandLevel': '{cabin["fareInfoDescList"][0]["brandLevel"].ToString()}',
'onlyPlaneFlag': false
}}";
preference = preference.Replace("'", "\"");
paramerter.Add("preference", JObject.Parse(preference));
#endregion
var content = new StringContent(JsonConvert.SerializeObject(paramerter), System.Text.Encoding.UTF8, "application/json");
var response = await request.PostAsync(url, content);
var resultStr = response.Content.ReadAsStringAsync().Result;
if (resultStr.Contains("S200"))
{
try
{
result = JObject.Parse(resultStr)["data"] as JObject;
}
catch (Exception) { }
}
return result;
}
private async Task<JArray> GetListContactAsync()
{
var result = new JArray();
var request = CreateRequest();
var url = "https://www.ceair.com/portal/v3/customer/listContact";
var content = new StringContent("{\"deviceId\":\"\"}", System.Text.Encoding.UTF8, "application/json");
var response = await request.PostAsync(url, content);
var resultStr = response.Content.ReadAsStringAsync().Result;
if (resultStr.Contains("U200"))
{
try
{
result = JObject.Parse(resultStr)["resultContent"] as JArray;
}
catch (Exception) { }
}
return result;
}
private HttpClient CreateRequest()
{
var handler = new HttpClientHandler();
handler.AllowAutoRedirect = false;
handler.UseCookies = true;
handler.CookieContainer = CreateCookie(AccountManagerHelper.GetInstance());
handler.AutomaticDecompression = DecompressionMethods.GZip;
handler.ClientCertificateOptions = ClientCertificateOption.Automatic;
var http = new HttpClient(handler);
CreateRequestHeaders(ref http);
return http;
}
private CookieContainer CreateCookie(string cookieStr)
{
var uri = new Uri("https://www.ceair.com");
var cc = new CookieContainer();
foreach (var str in cookieStr.Split(';'))
{
cc.SetCookies(uri, str);
}
return cc;
}
private void CreateRequestHeaders(ref HttpClient http)
{
var random = new Random();
http.DefaultRequestHeaders.Add("Accept", "application/json, text/plain, */*");
http.DefaultRequestHeaders.Add("Accept-Encoding", "gzip, deflate, br");
http.DefaultRequestHeaders.Add("Accept-Language", "zh-CN,zh;q=0.9");
http.DefaultRequestHeaders.Add("Cache-Control", "no-cache");
//http.DefaultRequestHeaders.Add("Connection", "keep-alive");
//http.DefaultRequestHeaders.Add("Content-Length", "188");
//http.DefaultRequestHeaders.Add("Content-Type", new MediaTypeHeaderValue("application/json"));
//http.DefaultRequestHeaders.Add("Host", "m.ceair.com");
http.DefaultRequestHeaders.Add("Origin", "https://www.ceair.com");
http.DefaultRequestHeaders.Add("Pragma", "no-cache");
http.DefaultRequestHeaders.Add("Referer", "https://www.ceair.com/leftNavigation/personCenter/passengers");
//http.DefaultRequestHeaders.Add("salesChannel", "NzcwMQ==");
http.DefaultRequestHeaders.Add("sec-ch-ua", "\" Not; A Brand\";v=\"99\", \"Google Chrome\";v=\"97\", \"Chromium\";v=\"97\"");
http.DefaultRequestHeaders.Add("sec-ch-ua-mobile", "?0");
http.DefaultRequestHeaders.Add("sec-ch-ua-platform", "\"Windows\"");
http.DefaultRequestHeaders.Add("Sec-Fetch-Dest", "empty");
http.DefaultRequestHeaders.Add("Sec-Fetch-Mode", "cors");
http.DefaultRequestHeaders.Add("Sec-Fetch-Site", "same-origin");
http.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.99 Safari/537.36");
http.DefaultRequestHeaders.Add("x-tingyun-id", $"DuR5xFLm8eI;r={random.Next(100000000, 999999999)}");
http.DefaultRequestHeaders.Add("site", "zh_CN");
http.DefaultRequestHeaders.Add("shakehand", "535206fb27efbaf75066ff179b975ff6");
http.DefaultRequestHeaders.Add("pragma", "no-cache");
}
}
}
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<None Remove="zh_CN.json" />
</ItemGroup>
<ItemGroup>
<Content Include="zh_CN.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<PackageReference Include="DotnetSpider" Version="5.0.9" />
<PackageReference Include="Selenium.WebDriver" Version="4.1.0" />
<PackageReference Include="Selenium.WebDriver.ChromeDriver" Version="100.0.4896.6000" />
<PackageReference Include="Serilog.AspNetCore" Version="3.4.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="3.1.1" />
<PackageReference Include="Serilog.Sinks.RollingFile" Version="3.3.0" />
<PackageReference Include="Serilog.Sinks.PeriodicBatching" Version="2.3.0" />
<PackageReference Include="System.Drawing.Common" Version="6.0.0" />
</ItemGroup>
</Project>

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.1.32210.238
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TicketSpider", "TicketSpider.csproj", "{53EAE111-750E-4BB3-8E84-3EC67776A4DC}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{53EAE111-750E-4BB3-8E84-3EC67776A4DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{53EAE111-750E-4BB3-8E84-3EC67776A4DC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{53EAE111-750E-4BB3-8E84-3EC67776A4DC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{53EAE111-750E-4BB3-8E84-3EC67776A4DC}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {8F140037-DD2A-4035-B86C-323926118022}
EndGlobalSection
EndGlobal
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TicketSpider.Model;
namespace TicketSpider.Uitls
{
public static class CmdHelper
{
/// <summary>
/// 航司
/// </summary>
public static string[]? AIRLINE = null;
/// <summary>
/// 命令模式
/// </summary>
public static int CMD_MODEL=0;
/// <summary>
/// 航班信息
/// </summary>
public static List<Flight> FLIGHTS = new List<Flight>();
/// <summary>
/// 乘客信息
/// </summary>
public static List<Passenger> PASSENGETS = new List<Passenger>();
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TicketSpider.Model;
namespace TicketSpider.Uitls
{
public static class DemoModelHelper
{
public static List<Passenger> GetTempPassenger()
{
var list=new List<Passenger>();
list.Add(new Passenger() {
id="",
paxName="罗超",
paxNameFirst="LUO",
paxNameLast="CHAO",
gender="M",
birthday="19901226",
nationality="CN",
telephoneCode="86",
mobile="17308037817",
email="",
ffpAirline="",
ffpNo="",
favorPaxIdDtoList=new List<FavorPaxIdDtoList>() {
new FavorPaxIdDtoList() {
id="",
favorPaxId="",
idIssueNation="",
idNo="EH7982905",
idType="PP",
idValidDt="",
paxIDType=""
}
},
paxType=""
});
list.Add(new Passenger()
{
id = "",
paxName = "康琪",
paxNameFirst = "Kang",
paxNameLast = "Qi",
gender = "F",
birthday = "20020316",
nationality = "CN",
telephoneCode = "86",
mobile = "17708004866",
email = "",
ffpAirline = "",
ffpNo = "",
favorPaxIdDtoList = new List<FavorPaxIdDtoList>() {
new FavorPaxIdDtoList() {
id="",
favorPaxId="",
idIssueNation="",
idNo="EH7982908",
idType="PP",
idValidDt="",
paxIDType=""
}
},
paxType = ""
});
return list;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
namespace TicketSpider.Uitls
{
public class HttpClientHelper
{
private static HttpClientHelper httpClientHelper = null;
private HttpClient httpClient;
/// <summary>
/// 构造方法私有,用于单例
/// </summary>
private HttpClientHelper() { }
/// <summary>
/// 获取当前类的实例
/// </summary>
/// <returns></returns>
public static HttpClientHelper GetInstance()
{
if (httpClientHelper != null)
{
return httpClientHelper;
}
else
{
HttpClientHelper httpClientHelper = new HttpClientHelper();
//取消使用默认的Cookies
HttpClientHandler handler = new HttpClientHandler() { UseCookies = false };
httpClientHelper.httpClient = new HttpClient(handler);
return httpClientHelper;
}
}
/// <summary>
/// Get方法请求
/// </summary>
/// <param name="url">请求地址</param>
/// <returns></returns>
public HttpResponseMessage Get(string url, List<KeyValuePair<string, string>> headers = null)
{
HttpRequestMessage request = new HttpRequestMessage()
{
RequestUri = new Uri(url),
Method = HttpMethod.Get,
};
if (headers != null && headers.Count > 0)
{
request.Headers.Clear();
foreach (var header in headers)
{
request.Headers.Add(header.Key, header.Value);
}
}
HttpResponseMessage response = httpClient.SendAsync(request).Result;
return response;
}
/// <summary>
/// Get方法请求
/// </summary>
/// <param name="url">请求地址</param>
/// <returns></returns>
public async Task<(HttpResponseMessage response, CookieContainer cookies)> GetAsync(string url, List<KeyValuePair<string, string>> headers = null)
{
var handler = new HttpClientHandler();
var cookieContainer = new CookieContainer();
handler.CookieContainer = cookieContainer;
HttpRequestMessage request = new HttpRequestMessage()
{
RequestUri = new Uri(url),
Method = HttpMethod.Get,
};
if (headers != null && headers.Count > 0)
{
request.Headers.Clear();
foreach (var header in headers)
{
request.Headers.Add(header.Key, header.Value);
}
}
var response = await httpClient.SendAsync(request);
return (response,cookieContainer);
}
/// <summary>
/// Post方法请求 application/x-www-form-urlencoded格式
/// </summary>
/// <param name="url">请求地址</param>
/// <param name="paramList">参数集合</param>
/// <returns></returns>
public HttpResponseMessage Post(string url, List<KeyValuePair<String, String>> paramList, List<KeyValuePair<string, string>> headers = null)
{
FormUrlEncodedContent formUrlEncodedContent = new FormUrlEncodedContent(paramList);
if (headers != null && headers.Count > 0)
{
formUrlEncodedContent.Headers.Clear();
foreach (var header in headers)
{
formUrlEncodedContent.Headers.Add(header.Key, header.Value);
}
}
HttpResponseMessage response = httpClient.PostAsync(new Uri(url), formUrlEncodedContent).Result;
return response;
}
public async Task<HttpResponseMessage> PostAsync(string url, List<KeyValuePair<String, String>> paramList, List<KeyValuePair<string, string>> headers = null)
{
FormUrlEncodedContent formUrlEncodedContent = new FormUrlEncodedContent(paramList);
if (headers != null && headers.Count > 0)
{
formUrlEncodedContent.Headers.Clear();
foreach (var header in headers)
{
formUrlEncodedContent.Headers.Add(header.Key, header.Value);
}
}
return await httpClient.PostAsync(new Uri(url), formUrlEncodedContent);
}
/// <summary>
/// Post方法请求 raw data
/// </summary>
/// <param name="url">请求地址</param>
/// <param name="content">raw data</param>
/// <returns></returns>
public HttpResponseMessage Post(string url, string content, List<KeyValuePair<string, string>> headers = null)
{
StringContent stringContent = new StringContent(content, Encoding.UTF8);
if (headers != null && headers.Count > 0)
{
stringContent.Headers.Clear();
foreach (var header in headers)
{
stringContent.Headers.Add(header.Key, header.Value);
}
}
HttpResponseMessage response = httpClient.PostAsync(new Uri(url), stringContent).Result;
return response;
}
/// <summary>
/// Post方法请求 raw data
/// </summary>
/// <param name="url">请求地址</param>
/// <param name="content">raw data</param>
/// <returns></returns>
public async Task<HttpResponseMessage> PostAsync(string url, string content, List<KeyValuePair<string, string>> headers = null)
{
StringContent stringContent = new StringContent(content, Encoding.UTF8,"");
if (headers != null && headers.Count > 0)
{
stringContent.Headers.Clear();
foreach (var header in headers)
{
stringContent.Headers.Add(header.Key, header.Value);
}
}
return await httpClient.PostAsync(new Uri(url), stringContent);
}
/// <summary>
/// 释放httpclient
/// </summary>
public void Release()
{
httpClient.Dispose();
}
/// <summary>
/// 设置默认请求头
/// </summary>
/// <param name="name"></param>
/// <param name="value"></param>
public void SetDefaultHeaders(string name, string value)
{
httpClient.DefaultRequestHeaders.Add(name, value);
}
/// <summary>
/// 删除默认请求头
/// </summary>
/// <param name="name"></param>
public void RemoveDefaultHeaders(string name)
{
httpClient.DefaultRequestHeaders.Remove(name);
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TicketSpider.Uitls
{
public class TaskHelper
{
public static CancellationTokenSource cancelTokenSource = new CancellationTokenSource();
private static TaskHelper taskHelper=null;
private static object taskHelperLock = new object();
private static object ticketLock = new object();
//public event Action CancelEvent;
private static bool TICKET_EXSITS = false;
public bool UpdateTicketStatus()
{
lock (ticketLock)
{
if (!TICKET_EXSITS)
{
TICKET_EXSITS = true;
return true;
}
else return false;
}
}
public void UnLockOrderStatus()
{
TICKET_EXSITS = false;
}
public static TaskHelper GetInstance()
{
if (taskHelper == null)
{
lock (taskHelperLock)
{
if (taskHelper == null) taskHelper = new TaskHelper();
}
}
return taskHelper;
}
public void FinishTask()
{
cancelTokenSource.Cancel();
}
public void WatchCancel()
{
while (!cancelTokenSource.IsCancellationRequested)
{
Thread.Sleep(1000);
}
Console.WriteLine("警卫:所有线程立即停止");
//CancelEvent?.Invoke();
}
}
}
using OpenQA.Selenium.Remote;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TicketSpider.Uitls
{
public class WebSiteHtmlLoader : IDisposable
{
private readonly RemoteWebDriver _remoteWebDriver;
public WebSiteHtmlLoader(RemoteWebDriver remoteWebDriver)
{
if (remoteWebDriver == null) throw new ArgumentNullException("remoteWebDriver");
_remoteWebDriver = remoteWebDriver;
}
public string GetRenderedHtml(Uri webSiteUri)
{
if (webSiteUri == null) throw new ArgumentNullException("webSiteUri");
_remoteWebDriver.Navigate().GoToUrl(webSiteUri);
return _remoteWebDriver.PageSource;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool disposing)
{
if (disposing)
{
if (_remoteWebDriver != null)
{
_remoteWebDriver.Quit();
}
}
}
}
}
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment