携程网页版国际机票数据

本文详细解析了如何抓取携程网页版国际机票数据,包括请求分析、transactionid和sign的获取方法,以及Java实现代码。通过模拟网络请求,获取并解析航班数据,实现了对北京到首尔机票信息的查询。
摘要由CSDN通过智能技术生成

目录

携程手机版国内机票数据
携程手机版国际机票数据
携程网页版国内机票数据
携程网页版国际机票数据
去哪儿网手机版机票数据
去哪儿网网页版机票数据
携程手机版机票数据添加代理
去哪儿网网页版机票数据添加代理

概述

携程网页版机票查询的网址是https://flights.ctrip.com/
本篇使用北京到首尔的数据。

请求分析

查看network,可以很容易找到请求地址是https://flights.ctrip.com/international/search/api/search/batchSearch
其中,headers里面有两个略微复杂的请求参数,transactionid 和 sign,这两个参数拿到后即可直接post请求。
其实,国内机票和国际机票查询的居然是同一个地址。

transactionid获取

这个可以通过网络请求直接获取到,比如北京到首尔的数据,通过https://flights.ctrip.com/international/search/api/flightlist/oneway-bjs-sel?_=1&depdate=2021-12-31&cabin=y_s&adult=1&containstax=1
拼接规则就是oneway-出发地三字码-目的地三字码?_=1&depdata=出发日期&cabin=查询舱位&adult=成人数量&containstax=金额是否含税
请求headers中增加accept: application/json,确保返回的是json格式。

模拟的curl如下

curl 'https://flights.ctrip.com/international/search/api/flightlist//oneway-bjs-sel?_=1&depdate=2021-12-31&cabin=y_s&adult=1&containstax=1' \
  -H 'accept: application/json' \
  --compressed

返回结果为

{
    "status":0,
    "msg":"success",
    "data":{
        "adultCount":1,
        "childCount":0,
        "infantCount":0,
        "flightWay":"S",
        "cabin":"Y_S",
        "scope":"i",
        "extensionAttributes":{
            "LoggingSampling":false,
            "isFlightIntlNewUser":false
        },
        "transactionID":"8c12c83315fb42fe8a73b3dd9afab405",
        "flightSegments":[
            {
                "departureCityCode":"BJS",
                "arrivalCityCode":"SEL",
                "departureCityName":"北京",
                "arrivalCityName":"首尔",
                "departureDate":"2021-12-31",
                "departureCountryId":1,
                "departureCountryName":"中国",
                "departureCountryCode":"CN",
                "departureProvinceId":1,
                "departureCityId":1,
                "arrivalCountryId":42,
                "arrivalCountryName":"韩国",
                "arrivalCountryCode":"KR",
                "arrivalProvinceId":0,
                "arrivalCityId":274,
                "departureCityTimeZone":480,
                "arrivalCityTimeZone":540,
                "timeZone":480
            }
        ],
        "directFlight":false,
        "extGlobalSwitches":{
            "useAllRecommendSwitch":true,
            "unfoldPriceListSwitch":true
        },
        "noRecommend":false
    }
}

返回结果的data中有transactionID字段。

sign获取

sign是直接本地js进行的加密,没有进行网络请求,最终结果是32位md5加密后小写。加密规则为

sign = md5(transactionID + 起始地大写三字码+ 降落的大写三字码 + 出发时间yyyy-MM-dd)

以北京到首尔为例,如果transactionID是a24b0ed8040540bab8cea5f1c7dced62,那么最终结果就是

sign=md5(a24b0ed8040540bab8cea5f1c7dced62BJSSEL2021-12-31)
=4e4ca18f296fc7742e262f116a742f3c

航班数据

headers中参数搞定后,就可以直接请求https://flights.ctrip.com/international/search/api/search/batchSearch
请求参数为(参数基本上都来自请求transactionid的接口)

{
    "flightWayEnum":"OW",
    "arrivalProvinceId":0,
    "extGlobalSwitches":{
        "useAllRecommendSwitch":true,
        "unfoldPriceListSwitch":true
    },
    "arrivalCountryName":"韩国",
    "infantCount":0,
    "cabin":"Y_S",
    "cabinEnum":"Y_S",
    "departCountryName":"中国",
    "flightSegments":[
        {
            "departureDate":"2021-12-31",
            "arrivalProvinceId":0,
            "arrivalCountryName":"韩国",
            "arrivalCountryCode":"KR",
            "departureCityName":"北京",
            "departureCityCode":"BJS",
            "departureCountryName":"中国",
            "departureCountryCode":"CN",
            "arrivalCityName":"首尔",
            "arrivalCityCode":"SEL",
            "departureCityTimeZone":480,
            "arrivalCountryId":42,
            "timeZone":480,
            "departureCityId":1,
            "departureCountryId":1,
            "arrivalCityTimeZone":540,
            "departureProvinceId":1,
            "arrivalCityId":274
        }
    ],
    "childCount":0,
    "segmentNo":1,
    "scope":"i",
    "adultCount":1,
    "extensionAttributes":{
        "LoggingSampling":false,
        "isFlightIntlNewUser":false
    },
    "transactionID":"a24b0ed8040540bab8cea5f1c7dced62",
    "directFlight":false,
    "departureCityId":1,
    "isMultiplePassengerType":0,
    "noRecommend":false,
    "army":"",
    "flightWay":"S",
    "arrivalCityId":274,
    "departProvinceId":1
}

响应结果见Java代码后方。

Java代码

和国内机票的基本一致。

	public static void main(String[] args) throws Exception {
		
		String url1 = "https://flights.ctrip.com/international/search/api/flightlist//oneway-bjs-sel?_=1&depdate=2021-12-31&cabin=y_s&adult=1&containstax=1";
		String result1 = Jsoup.connect(url1).header("accept", "application/json").ignoreContentType(true).method(Method.POST).execute().body();
		System.out.println(result1);
		
		JSONObject obj1 = JSON.parseObject(result1);
		JSONObject data = obj1.getJSONObject("data");
		JSONObject flightSegment = data.getJSONArray("flightSegments").getJSONObject(0);
		
		JSONObject param = data;
		param.put("flightWayEnum", "OW"); //单程
		param.put("arrivalProvinceId", flightSegment.getString("arrivalProvinceId"));
		param.put("arrivalCountryName", flightSegment.getString("arrivalCountryName"));
		param.put("cabinEnum", data.getString("cabin"));
		param.put("departCountryName", flightSegment.getString("departCountryName"));
		param.put("segmentNo", "1");
		param.put("departureCityId", flightSegment.getString("departureCityId"));
		param.put("isMultiplePassengerType", "0");
		param.put("army", "");
		param.put("arrivalCityId", flightSegment.getString("arrivalCityId"));
		param.put("departProvinceId", flightSegment.getString("departProvinceId"));
		String transactionid = obj1.getJSONObject("data").getString("transactionID");
		String sign = TextUtils.MD5(transactionid+"BJSSEL2021-12-31").toLowerCase();
		String url2 = "https://flights.ctrip.com/international/search/api/search/batchSearch";
		String result2 = Jsoup.connect(url2)
				.header("sign", sign)
				.header("scope", data.getString("scope"))
				.header("content-type", "application/json;charset=UTF-8")
				.header("accept", "application/json")
				.header("transactionid", transactionid)
				.header("user-agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.55 Safari/537.36")
				.ignoreContentType(true)
				.requestBody(param.toString())
				.method(Method.POST).execute().body();
		System.out.println(result2);
		
		
	}

其中TextUtil中仅使用的MD5加密,可以使用

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lootaa

你的鼓励是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值