[ExpertFlyer已恢复,邮箱注册登录即可]ExpertFlyer挂掉之后的平替:Amadeus API小白学习日记

置顶以下坛友提供的两个网站。配合食用,效果更佳。

注:seats.aero貌似能看到靠窗商务舱的占用情况
(如下图,同一航班对比,左边seats.aero 右边bulkhead)


原文:
计算机小白,只有少量读写代码基础。抛砖引玉,希望大佬提供更优化的解决方案!

简介: expertflyer.com免费版提供的座位查询功能非常实用,尤其是查询指定舱位的availability,以及座位具体是occupied还是blocked
工具: 文本编辑器(如UltraEdit)、命令行工具(如MacOS的Terminal)、ChatGPT(免费版即可)

具体方法:
Step 1: 注册Amadeus账号以及获取token

  • 在Amadeus官网https://developers.amadeus.com注册账号->邮箱验证->成功登录
  • 右上角用户名下面菜单中点击My Self-Service Workspace,然后点击Create new app,随便输入App name后点击Create
  • 跳至新界面,下拉可以看到生成的API Key和API Secret
  • 获取token,在命令行工具(e.g., Terminal)中输入下方指令
获取token代码

curl “https://test.api.amadeus.com/v1/security/oauth2/token”
-H “Content-Type: application/x-www-form-urlencoded”
-d “grant_type=client_credentials&client_id={client_id}&client_secret={client_secret}”

系统会返回如下信息
    {
        "type": "amadeusOAuth2Token",
        "username": "[email protected]",
        "application_name": "flight-search-test",
        "client_id": "xxxxxxxxxx",
        "token_type": "Bearer",
        "access_token": "13M5QzxDra2C71bYhvk211jmqBlK",
        "expires_in": 1799,
        "state": "approved",
        "scope": ""
    }

其中access_token就是我们需要的token,可以看到expires_in:1799,有效时间是半小时。

注:获取token指令来源为(图1):

Step 2: 查询航班(Flight Offers Search)

在命令行工具(e.g., Terminal)中运行下面的指令

查找航班代码(以JL60为例)

curl -X POST “https://test.api.amadeus.com/v2/shopping/flight-offers”
-H “Authorization: Bearer YOUR_ACCESS_TOKEN”
-H “Content-Type: application/json”
-d ‘{
“Operatingflight”: [
{
“carrierCode”: “JL”,
“number”: “60”
}
],
“TravelClass”: [“BUSINESS”],
“originDestinations”: [
{
“id”: “1”,
“originLocationCode”: “KIX”,
“destinationLocationCode”: “LAX”,
“departureDateTimeRange”: {
“date”: “2025-01-29”,
“time”: “17:50:00”
}
}
],
“travelers”: [
{
“id”: “1”,
“travelerType”: “ADULT”,
“dateOfBirth”: “1990-01-01”,
“gender”: “MALE”
}
],
“sources”: [“GDS”],
“maxPrice”: “5000”,
“nonstop”: true
}’ > flight_offers.json

  • 此代码把查找结果输出至./flight_offers.json,如果想在命令行工具中输出(不建议)或者更换路径,可更改最后> flight_offers.json的部分。

  • 替换YOUR_ACCESS_TOKEN为上一步生成的有效时间为半小时的token

  • 替换carrierCode(航空公司二字码), number(航班号码), originLocationCode(出发机场),destinationLocationCode(到达机场)

  • 最后一行的>flight_offers.json为输出至文件,文件名为flight_offers.json,如果不加这部分,则直接在命令行中显示

(不知为什么,输出结果中除了想要的JL60,还包含许多其他的航班,需要进一步在Step 3中手工筛选)

Step 3: 理解输出的航班信息flight_offers.json
用UltraEdit等文本编辑工具打开生成的flight_offers.json,可以看到输出的航班信息全部叠在一起杂乱无章。

  1. 首先用Ctrl+F查找功能,在搜索框中输入"carrierCode":“JL”,“number”:“60”,在一群字符中找到了想要的航班(图2)。

  2. 选中该信息所在的行以及上下各一行(共选中3行),复制粘贴到ChatGPT中,并请它提取出与JL60相关的代码,ChatGPT会自动排版并生成好想要的信息(图3)。

至此,我们利用Flight Offers Search功能搜索到了2025年1月29日JL60的信息,Offer ID是73,也就是第73个Offer。下一步需要利用这个Offer的信息查找座位信息。

Step 4: 查找座位信息(SeatMap Display)
这一步,我们利用查找其他航班座位信息的代码为模板,让ChatGPT生成查找我们需要的航班座位信息的代码

模板(查找1月22日JL60座位信息的代码)

curl -X POST “https://test.api.amadeus.com/v1/shopping/seatmaps”
-H "Authorization: Bearer YOUR_ACCESS_TOKEN "
-H “Content-Type: application/json”
-d ‘{
“data”: [
{
“type”: “flight-offer”,
“id”: “75”,
“source”: “GDS”,
“instantTicketingRequired”: false,
“nonHomogeneous”: false,
“oneWay”: false,
“lastTicketingDate”: “2024-11-05”,
“numberOfBookableSeats”: 9,
“itineraries”: [
{
“duration”: “PT10H10M”,
“segments”: [
{
“departure”: {
“iataCode”: “KIX”,
“terminal”: “1”,
“at”: “2025-01-22T17:50:00”
},
“arrival”: {
“iataCode”: “LAX”,
“terminal”: “B”,
“at”: “2025-01-22T11:00:00”
},
“carrierCode”: “JL”,
“number”: “60”,
“aircraft”: {
“code”: “789”
},
“operating”: {
“carrierCode”: “JL”
},
“duration”: “PT10H10M”,
“id”: “52”,
“numberOfStops”: 0,
“blacklistedInEU”: false
}
]
}
],
“price”: {
“currency”: “EUR”,
“total”: “1740.81”,
“base”: “1462.00”,
“fees”: [
{
“amount”: “0.00”,
“type”: “SUPPLIER”
},
{
“amount”: “0.00”,
“type”: “TICKETING”
}
],
“grandTotal”: “1740.81”
},
“pricingOptions”: {
“fareType”: [
“PUBLISHED”
],
“includedCheckedBagsOnly”: true
},
“validatingAirlineCodes”: [
“JL”
],
“travelerPricings”: [
{
“travelerId”: “1”,
“fareOption”: “STANDARD”,
“travelerType”: “ADULT”,
“price”: {
“currency”: “EUR”,
“total”: “1740.81”,
“base”: “1462.00”
},
“fareDetailsBySegment”: [
{
“segmentId”: “52”,
“cabin”: “BUSINESS”,
“fareBasis”: “KNX70ZN8”,
“class”: “U”,
“includedCheckedBags”: {
“quantity”: 2
}
}
]
}
]
}
]
}’ > seat_maps.json

  1. 将上述代码复制粘贴进ChatGPT,并让它结合上面的模板以及之前提取的JL60航班信息,重新生成代码(图4)。

  2. ChatGPT生成的curl请求代码可能需要手动修改舱位(比如JL的商务舱奖励票为U,则修改为"class": “U”。其他舱位可参考舱位信息可参考航空舱位介绍 - 美国信用卡指南

  3. 将ChatGPT生成的curl请求代码复制粘贴进命令行工具中运行(即可看到输出的座位信息(保存在seat_maps.json文件中)。又是这样一串又臭又长没有排版的输出结果(图5)

图5. Amadeus API生成的座位信息(未排版)

没有关系,将所有内容粘贴进ChatGPT,请它分析,就可以知道每一个座位的信息了!(如图6所示,座位是否被其他客人occupied,还是blocked了)

29 个赞

我时常在想之后码农副业能不能做一个travel agent

2 个赞

給自己查票有無限的耐心。給別人查票總是敷衍了事。

3 个赞

ExpertFlyer啥时候挂了

红迪上有个老哥搓了一个简易代替网站,可以(免费)查座位图

bulkhead.me

10 个赞

需求量太小,副业估计不太行,可以叱咤论坛 :troll:

有玉出现了 :mobaidalao:

这个查询结果一片空白啊 :yaoming:

试过,但是test.api返回的数据不太准,想上prod还需要一堆认证
可能得自己开始当travel agent才行吧)

gds系统还挺复杂的,一不小心搞错了罚款底儿掉。一张票代理费很少,航司要不没代理费要不给的少,不走量的话累死,而且退改也麻烦。甜酸茶大佬之前已经有过总结

1 个赞

你心不诚

expertflyer 已经确定挂了?

test好像就是自己玩玩?权当业余爱好了…

我试了好像还不错啊

Body
{
    "data": [
        {
            "type": "flight-offer",
            "id": "1",
            "itineraries": [
                {
                    "segments": [
                        {
                            "departure": {
                                "iataCode": "JFK",
                                "at": "2024-11-01T00:00:00"
                            },
                            "arrival": {
                                "iataCode": "HND"
                            },
                            "carrierCode": "JL",
                            "number": "5",
                            "id": "1"
                        }
                    ]
                }
            ],
            "travelerPricings": [
                {
                    "travelerId": "1",
                    "travelerType": "ADULT",
                    "fareDetailsBySegment": [
                        {
                            "segmentId": "1",
                            "cabin": "BUSINESS",
                            "class": "U"
                        }
                    ]
                }
            ]
        }
    ]
}

不需要那么多内容,只需要日期,航班号,舱位(物理舱位和RBD)就可以了。也不需要Flight Offers里出来的东西

2 个赞

应该没有那么多验证,你看到的那个是Flight Order Creation要验证吧,那个不用管,是给实际需要生成PNR的才需要用到

1 个赞

看样子是Row多了就不显示部分Row了

2 个赞

这个能拿到里程仓位数据才是绝杀
Seat关注量太少了

只是自己查一下的话用Amadeus的Postman包就行了,自己fork一下就能用了

不过这个seatmap只是查有没人选了那个座位吧,查不了Award Availability? ExpertFlyer上面那些Award是用Amadeus查的吗?

当然不是,不是通过GDS查的,一般TA能接触到的GDS都是看不到大多数航司的里程舱位的

1 个赞