亚航app航班价格抓取

2024-02-23 22:32
文章标签 抓取 app 价格 航班 亚航

本文主要是介绍亚航app航班价格抓取,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

亚航app航班价格抓取

条件:去程日期、回程日期、成人数、儿童数、婴儿数、出发机场、到达机场
结果:符合行程的所有航班信息( 主要包括价格、航班号、起飞机场、到达机场、起飞时间、降落时间、舱位等)

抓包分析

在这里插入图片描述

在这里插入图片描述
从上面的Headers和Form视图中可以得知,亚航采用的是https post 请求,请求及响应报文是加密的,请求头中wToken也是一个密文。

解密wToken及报文体

通过jeb反编译客户端,搜索wToken关键字,找到位于

ConstantHelper.ॱˋ(r2);

方法已经经过混淆处理过,可读性并不友好。

可以通过标记的方法,对相应变量作注释,还原涉及的功能函数。
经过分析及标记得知:
1):报文体的加解密位于MCrypt类中
2):wToken的计算位于IJAQAVMPSignComponent的avmpSign方法中

还原关键代码

出于对目标app的安全考虑,MCrypt及IJAQAVMPSignComponent的具体实现代码就不公开了,以免对其造成不良影响

编写调用客户端测试

    //请求userSession,后续接口中需要此参数
public static String requestSession(String wTokenServerURL, String deviceID) throws Exception {byte[] reqParams = createUserSessionData(deviceID);String rs = request(wTokenServerURL, "103", deviceID, reqParams);System.out.println("rs---> " + rs);return (String) ((Map) (JSON.parseObject(rs).get("data"))).get("userSession");}//请求航班价格搜索public static String requestFlightSearch(String wTokenServerURL, String userSession, String deviceID, int adultPax, int childPax, int infantPax, String departureStation, String arrivalStation, String departureDate, String returnDate) throws Exception {byte[] reqParams = createFlightSearchData(userSession, deviceID, adultPax, childPax, infantPax, departureStation, arrivalStation, departureDate, returnDate);return request(wTokenServerURL, "302", deviceID, reqParams);}

写一个main方法执行一下

获取 清迈(CNX) - 武汉(WUH) 2020-01-08 1位成人的价格列表:

public static void main(String[] args) throws Exception {String deviceID = "b20be1e49f423119";String wTokenServerURL = "http://[ip]:[port]";String userSession = requestSession(wTokenServerURL, deviceID);System.out.println("userSession:" + userSession);int adultPax = 1;int childPax = 0;int infantPax = 0;String departureStation = "CNX";String arrivalStation = "WUH";String departureDate = DateFormatUtils.format(DateUtils.addDays(new Date(), 2), "yyyy-MM-dd");String returnDate = "";String rate = requestFlightSearch(wTokenServerURL, userSession, deviceID, adultPax, childPax, infantPax, departureStation, arrivalStation, departureDate, returnDate);System.out.println("rs ---> " + rate);}

解密后的返回结果报文:

{"response": {"responseTime": "2020-01-06 14:22:45","responseCode": 1000,"responseMessage": "Success"},"meta": {"cultureCode": "zh-CN","iosVersion": 1,"androidVersion": 1,"iosCompulsory": 1,"androidCompulsory": 1,"countryCacheVersion": 0,"ssrCacheVersion": 0,"stationCacheVersion": 0,"routeCacheVersion": 0},"data": {"SpecialNote": [[""],[""]],"SpecialNote2": [[""],[""]],"FlightSearch": [[{"IsDirectFlight": true,"JourneySellKey": "FD~ 570~ ~~DMK~01\/08\/2020 07:10~WUH~01\/08\/2020 11:35~~","LowestJourneyFare": 1,"JourneyDiscount": 0,"FlightStatus": 1,"ValuePackAvailable": 1,"HaveLowFare": 1,"HavePremiumFare": 1,"ValuePackageTotal": 830,"ValuePackageTotalOffset": -86,"LessThan24Hrs": 0,"LessThan2Hrs": 0,"ValuePackageSsrList": {"Baggage": [[{"SSRCode": "PBAB","Amount": 670,"SsrCodeType": 0},{"SSRCode": "VBPB","Amount": -68.8,"SsrCodeType": 1}]],"Snack": [[{"SSRCode": "VBPM","Amount": 0,"SsrCodeType": 1},{"SSRCode": "VPML","Amount": 120,"SsrCodeType": 0},{"SSRCode": "VGML","Amount": 120,"SsrCodeType": 0}]],"Seat": [[{"SSRCode": "DUSE","Amount": 99,"SsrCodeType": 0},{"SSRCode": "VBPS","Amount": -17.2,"SsrCodeType": 1}]],"Insurance": [[{"SSRCode": "INSV","Amount": 27,"SsrCodeType": 0},{"SSRCode": "VBIN","Amount": 0,"SsrCodeType": 1}]]},"CityIslandTransfer": false,"TotalSegment": 1,"HaveThruflightSegment": false,"RouteAllowOfferValuepack": true,"HaveComplimentaryInsuranceVP": true,"HaveComplimentaryInsurancePremium": true,"HaveVegetarianVP": true,"HaveNonVegetarianVP": true,"IsIndiaBooking": false,"HaveInflightEntertainment": false,"DepartureStation": "DMK","ArrivalStation": "WUH","DepartureDate": "2020-01-08T00:00:00","TotalJourneyAmount": {"FareType": {"1": {"MinAvailableSeats": "7","MobileExclusive": null,"ReservedDisplay1": null,"ReservedDisplay2": null,"MobilePromo": null,"FareStatus": 1,"FareUniqueID": "ID_2_0_1","ADT": {"OriginalFare": 9044,"FinalFare": 9044,"CurrencyCode": "THB"}},"0": {"MinAvailableSeats": "7","MobileExclusive": null,"ReservedDisplay1": null,"ReservedDisplay2": null,"MobilePromo": null,"FareStatus": 1,"FareUniqueID": "ID_2_0_0","ADT": {"OriginalFare": 7964,"FinalFare": 7964,"CurrencyCode": "THB"}}}},"TransitInfo": null,"Segment": [{"AirlineCompany": "Thai AirAsia","ArrivalStation": "WUH","DepartureStation": "DMK","SegmentSellKey": "FD~ 570~ ~~DMK~01\/08\/2020 07:10~WUH~01\/08\/2020 11:35~~","STA": "2020-01-08T11:35:00","STD": "2020-01-08T07:10:00","International": "true","CarrierCode": "FD","FlightNumber": " 570","OpSuffix": " ","SegmentType": 0,"IsThruflightSegment": false,"DepartureCountryCode": "TH","ArrivalCountryCode": "CN","DepartureTimeZone_UtcOffset": "+0700","ArrivalTimeZone_UtcOffset": "+0800","STD_UTC": "2020-01-08 00:10:00","STA_UTC": "2020-01-08 03:35:00","EstimatedTime": "3 \u5c0f\u65f6 25 \u5206\u949f ","Fare": [{"ClassOfService": "P","RuleNumber": "AAB1","FareBasisCode": "P01H00","FareSequence": "53","FareClassOfService": "P","FareApplicationType": "Route","ProductClass": "EC","FareSellKey": "0~P~ ~AK~P01H00~AAB1~~0~53~~X","AvailableCount": "7","Status": "Active","PaxFare": {"ADT": {"PaxType": "ADT","PaxDiscountCode": "","FareDiscountCode": "","TotalFare": 7964,"ServiceCharges": [{"CurrencyCode": "THB","Amount": "7214.0000","ChargeCode": "","ChargeType": "FarePrice","TicketCode": ""},{"CurrencyCode": "THB","Amount": "750.0000000","ChargeCode": "","ChargeType": "Tax","TicketCode": ""}]}}},{"ClassOfService": "PF","RuleNumber": "AAB1","FareBasisCode": "PF1F00","FareSequence": "52","FareClassOfService": "PF","FareApplicationType": "Route","ProductClass": "HF","FareSellKey": "0~PF~ ~AK~PF1F00~AAB1~~0~52~~X","AvailableCount": "7","Status": "Active","PaxFare": {"ADT": {"PaxType": "ADT","PaxDiscountCode": "","FareDiscountCode": "","TotalFare": 9044,"ServiceCharges": [{"CurrencyCode": "THB","Amount": "8294.0000","ChargeCode": "","ChargeType": "FarePrice","TicketCode": ""},{"CurrencyCode": "THB","Amount": "750.0000000","ChargeCode": "","ChargeType": "Tax","TicketCode": ""}]}}}],"Legs": [{"DepartureStation": "DMK","ArrivalStation": "WUH","STD": "2020-01-08T07:10:00","STA": "2020-01-08T11:35:00","CarrierCode": "FD","FlightNumber": " 570","DepartureStationName": "\u66fc\u8c37 - \u5eca\u66fc","ArrivalStationName": "\u6b66\u6c49","LegsEstimatedTime": "3H25M"}],"StationDisplay": ["DMK","WUH"],"InftAvailability": 10}],"FareProductClassList": {"lowfare": 0,"premiumflex": 1}},{"IsDirectFlight": true,"JourneySellKey": "FD~ 572~ ~~DMK~01\/08\/2020 15:55~WUH~01\/08\/2020 20:20~~","LowestJourneyFare": 0,"JourneyDiscount": 0,"FlightStatus": 1,"ValuePackAvailable": 1,"HaveLowFare": 1,"HavePremiumFare": 1,"ValuePackageTotal": 830,"ValuePackageTotalOffset": -86,"LessThan24Hrs": 0,"LessThan2Hrs": 0,"ValuePackageSsrList": {"Baggage": [[{"SSRCode": "PBAB","Amount": 670,"SsrCodeType": 0},{"SSRCode": "VBPB","Amount": -68.8,"SsrCodeType": 1}]],"Snack": [[{"SSRCode": "VBPM","Amount": 0,"SsrCodeType": 1},{"SSRCode": "VPML","Amount": 120,"SsrCodeType": 0},{"SSRCode": "VGML","Amount": 120,"SsrCodeType": 0}]],"Seat": [[{"SSRCode": "DUSE","Amount": 99,"SsrCodeType": 0},{"SSRCode": "VBPS","Amount": -17.2,"SsrCodeType": 1}]],"Insurance": [[{"SSRCode": "INSV","Amount": 27,"SsrCodeType": 0},{"SSRCode": "VBIN","Amount": 0,"SsrCodeType": 1}]]},"CityIslandTransfer": false,"TotalSegment": 1,"HaveThruflightSegment": false,"RouteAllowOfferValuepack": true,"HaveComplimentaryInsuranceVP": true,"HaveComplimentaryInsurancePremium": true,"HaveVegetarianVP": true,"HaveNonVegetarianVP": true,"IsIndiaBooking": false,"HaveInflightEntertainment": false,"DepartureStation": "DMK","ArrivalStation": "WUH","DepartureDate": "2020-01-08T00:00:00","TotalJourneyAmount": {"FareType": {"1": {"MinAvailableSeats": "7","MobileExclusive": null,"ReservedDisplay1": null,"ReservedDisplay2": null,"MobilePromo": null,"FareStatus": 1,"FareUniqueID": "ID_2_1_1","ADT": {"OriginalFare": 11774,"FinalFare": 11774,"CurrencyCode": "THB"},"INF": {"CurrencyCode": null,"FinalFare": null,"OriginalFare": null}},"0": {"MinAvailableSeats": "7","MobileExclusive": null,"ReservedDisplay1": null,"ReservedDisplay2": null,"MobilePromo": null,"FareStatus": 1,"FareUniqueID": "ID_2_1_0","ADT": {"OriginalFare": 10694,"FinalFare": 10694,"CurrencyCode": "THB"},"INF": {"CurrencyCode": null,"FinalFare": null,"OriginalFare": null}}}},"TransitInfo": null,"Segment": [{"AirlineCompany": "Thai AirAsia","ArrivalStation": "WUH","DepartureStation": "DMK","SegmentSellKey": "FD~ 572~ ~~DMK~01\/08\/2020 15:55~WUH~01\/08\/2020 20:20~~","STA": "2020-01-08T20:20:00","STD": "2020-01-08T15:55:00","International": "true","CarrierCode": "FD","FlightNumber": " 572","OpSuffix": " ","SegmentType": 0,"IsThruflightSegment": false,"DepartureCountryCode": "TH","ArrivalCountryCode": "CN","DepartureTimeZone_UtcOffset": "+0700","ArrivalTimeZone_UtcOffset": "+0800","STD_UTC": "2020-01-08 08:55:00","STA_UTC": "2020-01-08 12:20:00","EstimatedTime": "3 \u5c0f\u65f6 25 \u5206\u949f ","Fare": [{"ClassOfService": "U","RuleNumber": "AAB1","FareBasisCode": "U01H00","FareSequence": "53","FareClassOfService": "U","FareApplicationType": "Route","ProductClass": "EC","FareSellKey": "0~U~ ~AK~U01H00~AAB1~~0~53~~X","AvailableCount": "7","Status": "Active","PaxFare": {"ADT": {"PaxType": "ADT","PaxDiscountCode": "","FareDiscountCode": "","TotalFare": 10694,"ServiceCharges": [{"CurrencyCode": "THB","Amount": "9944.0000","ChargeCode": "","ChargeType": "FarePrice","TicketCode": ""},{"CurrencyCode": "THB","Amount": "750.0000000","ChargeCode": "","ChargeType": "Tax","TicketCode": ""}]},"INF": {"ServiceCharges": null}}},{"ClassOfService": "UF","RuleNumber": "AAB1","FareBasisCode": "UF1F00","FareSequence": "52","FareClassOfService": "UF","FareApplicationType": "Route","ProductClass": "HF","FareSellKey": "0~UF~ ~AK~UF1F00~AAB1~~0~52~~X","AvailableCount": "7","Status": "Active","PaxFare": {"ADT": {"PaxType": "ADT","PaxDiscountCode": "","FareDiscountCode": "","TotalFare": 11774,"ServiceCharges": [{"CurrencyCode": "THB","Amount": "11024.0000","ChargeCode": "","ChargeType": "FarePrice","TicketCode": ""},{"CurrencyCode": "THB","Amount": "750.0000000","ChargeCode": "","ChargeType": "Tax","TicketCode": ""}]},"INF": {"ServiceCharges": null}}}],"Legs": [{"DepartureStation": "DMK","ArrivalStation": "WUH","STD": "2020-01-08T15:55:00","STA": "2020-01-08T20:20:00","CarrierCode": "FD","FlightNumber": " 572","DepartureStationName": "\u66fc\u8c37 - \u5eca\u66fc","ArrivalStationName": "\u6b66\u6c49","LegsEstimatedTime": "3H25M"}],"StationDisplay": ["DMK","WUH"],"InftAvailability": 10}],"FareProductClassList": {"lowfare": 0,"premiumflex": 1}}]],"LowestFareArr": [{"2020-01-09": 10694,"2020-01-07": 5759,"2020-01-08": 7964}],"JourneyDisplay": [["DMK","WUH"]],"FareDiscountAvailable": 0,"MemberDiscountApply": false,"userCurrencyCode": "CNY","displayCurrencyCode": "CNY","exchangeRate": "0.242372000000000000","departureCurrencyCode": "THB","AustraliaSpecialNote": [],"IsUSBooking": false,"IsPHBooking": false,"IsPHDomestic": false,"captchaVerification": 0}
}

这篇关于亚航app航班价格抓取的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/740136

相关文章

macOS怎么轻松更换App图标? Mac电脑图标更换指南

《macOS怎么轻松更换App图标?Mac电脑图标更换指南》想要给你的Mac电脑按照自己的喜好来更换App图标?其实非常简单,只需要两步就能搞定,下面我来详细讲解一下... 虽然 MACOS 的个性化定制选项已经「缩水」,不如早期版本那么丰富,www.chinasem.cn但我们仍然可以按照自己的喜好来更换

React实现原生APP切换效果

《React实现原生APP切换效果》最近需要使用Hybrid的方式开发一个APP,交互和原生APP相似并且需要IM通信,本文给大家介绍了使用React实现原生APP切换效果,文中通过代码示例讲解的非常... 目录背景需求概览技术栈实现步骤根据 react-router-dom 文档配置好路由添加过渡动画使用

PHP抓取网站图片脚本

方法一: <?phpheader("Content-type:image/jpeg"); class download_image{function read_url($str) { $file=fopen($str,"r");$result = ''; while(!feof($file)) { $result.=fgets($file,9999); } fclose($file); re

MFC中App,Doc,MainFrame,View各指针的互相获取

纸上得来终觉浅,为了熟悉获取方法,我建了个SDI。 首先说明这四个类的执行顺序是App->Doc->Main->View 另外添加CDialog类获得各个指针的方法。 多文档的获取有点小区别,有时间也总结一下。 //  App void CSDIApp::OnApp() {      //  App      //  Doc     CDocument *pD

ConstraintLayout布局里的一个属性app:layout_constraintDimensionRatio

ConstraintLayout 这是一个约束布局,可以尽可能的减少布局的嵌套。有一个属性特别好用,可以用来动态限制宽或者高app:layout_constraintDimensionRatio 关于app:layout_constraintDimensionRatio参数 app:layout_constraintDimensionRatio=“h,1:1” 表示高度height是动态变化

App Store最低版本要求汇总

1,自此日期起: 2024 年 4 月 29 日 自 2024 年 4 月 29 日起,上传到 App Store Connect 的 App 必须是使用 Xcode 15 为 iOS 17、iPadOS 17、Apple tvOS 17 或 watchOS 10 构建的 App。将 iOS App 提交至 App Store - Apple Developer 2,最低XCode版本 Xcod

用Java抓取CSDN主页上的图片

一,步骤一:获取网页源码 1,定义要爬取的页面的URL对象 //定义即将访问的链接String url="http://www.csdn.net";//获取CSDN的URL对象URL realURL = new URL(url); 2,获得这个链接的一个连接对象 URLConnection connection = realURL.openConnection();

鸿蒙自动化发布测试版本app

创建API客户端 API客户端是AppGallery Connect用于管理用户访问AppGallery Connect API的身份凭据,您可以给不同角色创建不同的API客户端,使不同角色可以访问对应权限的AppGallery Connect API。在访问某个API前,必须创建有权访问该API的API客户端。 1.登录AppGallery Connect网站,选择“用户与访问”。选择左侧

Xinstall助力App全渠道统计,参数传递下载提升用户体验!

在移动互联网时代,App已成为我们日常生活中不可或缺的一部分。然而,对于App开发者来说,如何有效地推广和运营自己的应用,却是一个不小的挑战。尤其是在面对众多渠道、复杂的数据统计和用户需求多样化的情况下,如何精准地触达目标用户,提升用户的下载、安装和活跃度,更是考验着每一个运营者的智慧。 今天,我们就来揭秘一个能够帮助App开发者解决这些痛点的神器——Xinstall。作为一家一站式App全渠道

Flask 创建app 时候传入的 static_folder 和 static_url_path参数理解

Flask 在创建app的时候 是用 app = Flask(__name__) 来创建的,不传入 static_folder参数的话 ,默认的静态文件的位置是在 static目录下 我们可以进入 Flask的源码里面查看 ctrl+鼠标左键进入 这是Flask的 __init__源码(后面还有一些,我就选了需要的代码)     def __init__(self,import_