174 lines
6.8 KiB
PHP
174 lines
6.8 KiB
PHP
<?php
|
|
|
|
$url = "https://apis.ihg.com/graphql/v1/hotels";
|
|
|
|
$headers = [
|
|
'sec-ch-ua-platform: "Windows"',
|
|
'Referer: https://www.ihg.com.cn/',
|
|
'sec-ch-ua: "Microsoft Edge";v="147", "Not.A/Brand";v="8", "Chromium";v="147"',
|
|
'ihg-language: zh-CN',
|
|
'sec-ch-ua-mobile: ?0',
|
|
'x-ihg-api-key: se9ym5iAzaW8pxfBjkmgbuGjJcr3Pj6Y',
|
|
'IHG-SessionId: 6cc0bb0f-8850-4302-9d4b-80e2f2ef4860',
|
|
'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0',
|
|
'Accept: application/json, text/plain, */*',
|
|
'Content-Type: application/json; charset=UTF-8',
|
|
'IHG-TransactionId: 50fef06e-2f3b-416c-a6af-69ba809c7666',
|
|
];
|
|
|
|
/**
|
|
$data = <<<JSON
|
|
{"operationName":"GetHotelDetails","variables":{"detailsInput":{"rebrandStartDate":"2026-04-28","geoLocation":{"lat":30.274086,"lon":120.155071,"radius":1336},"geoLocationDistance":{"distanceType":"STRAIGHT_LINE","distanceUnit":"KM"},"size":120,"fallbackSearch":{"minHotels":1,"maxRadius":100,"incrementRadiusBy":70},"sortBy":"DISTANCE"},"mediaArgs":{"formats":[{"aspectHeight":"3","aspectWidth":"4"},{"aspectHeight":"5","aspectWidth":"16"}]}},"query":"query GetHotelDetails(\$detailsInput:HotelArgs\$mediaArgs:MediaArgs){getHotels(input:\$detailsInput){hotelInfo{hotelCode callCenter{phoneNumber}address{street1 street2 street3 city zip state{code name}country{name code}checkInAddress{city country line1 state zipcode}}location{boardTypes{boardType}}distanceFrom{kilometers miles}marketing{optOutDateWeb optInDateWeb marketingText{welcomeMessage}}brandInfo{SPBrandName brandCode brandName chainCode futureBrandInfo{rebrandingDate hotelName chainCode brandName brandCode}spTransitionalBrandIdentifier}greenEngage{certificationPrograms{certifiedByGloballyRecognizedSustainableProgram environmentalCertificationProgram{listItem}}lowCarbon{lowCarbonHotelDescription isLowCarbonHotel}lowCarbonReady{lowCarbonReadyHotelDescription isLowCarbonReadyHotel}}room{hotelHighlights{hotelDisclaimer}}badges{name id}facilities{name id}parking{complimentaryDailySelfParking parkingDescription carParkingAvailable valetParkingAvailable}policies{pet{petsAllowed guideDogsOrServiceAnimalsAllowed description}}stripes{id name}renovationAlertsList{alertType flagEndDate flagStartDate other}profile{name webNonBrandedHotelLogo{url}seoCity nonIhgCrsUrl independentNonIHGWebsiteURL hotelLogo{originalUrl}averageReview tpiLevel2Violator primaryImageUrl{originalUrl}latLong{lon lat}hotelStatus preSellDate dateOpened totalReviews vatIncluded}media(input:\$mediaArgs){primaryPhotos{allPhotos{type primary caption originalUrl formats{url aspectHeight aspectWidth}}}}foodAndBeverage{complimentaryBreakfastDetails{complimentaryGrabAndGoBreakfast}}restaurant{onSiteRestaurantsCount}tax{taxAndFeeDetail serviceCharge{startAndEndDate{startDate endDate}description}}}}}"}
|
|
JSON;
|
|
*/
|
|
|
|
$query = <<<'GRAPHQL'
|
|
query GetHotelDetails($detailsInput: HotelArgs, $mediaArgs: MediaArgs){
|
|
getHotels(input:$detailsInput){
|
|
hotelInfo{
|
|
hotelCode
|
|
callCenter{phoneNumber}
|
|
address{
|
|
street1 street2 street3 city zip
|
|
state{code name}
|
|
country{name code}
|
|
checkInAddress{city country line1 state zipcode}
|
|
}
|
|
location{boardTypes{boardType}}
|
|
distanceFrom{kilometers miles}
|
|
marketing{optOutDateWeb optInDateWeb marketingText{welcomeMessage}}
|
|
brandInfo{
|
|
SPBrandName brandCode brandName chainCode
|
|
futureBrandInfo{rebrandingDate hotelName chainCode brandName brandCode}
|
|
spTransitionalBrandIdentifier
|
|
}
|
|
greenEngage{
|
|
certificationPrograms{
|
|
certifiedByGloballyRecognizedSustainableProgram
|
|
environmentalCertificationProgram{listItem}
|
|
}
|
|
lowCarbon{lowCarbonHotelDescription isLowCarbonHotel}
|
|
lowCarbonReady{lowCarbonReadyHotelDescription isLowCarbonReadyHotel}
|
|
}
|
|
room{hotelHighlights{hotelDisclaimer}}
|
|
badges{name id}
|
|
facilities{name id}
|
|
parking{
|
|
complimentaryDailySelfParking
|
|
parkingDescription
|
|
carParkingAvailable
|
|
valetParkingAvailable
|
|
}
|
|
policies{
|
|
pet{petsAllowed guideDogsOrServiceAnimalsAllowed description}
|
|
}
|
|
stripes{id name}
|
|
renovationAlertsList{alertType flagEndDate flagStartDate other}
|
|
profile{
|
|
name
|
|
webNonBrandedHotelLogo{url}
|
|
seoCity
|
|
nonIhgCrsUrl
|
|
independentNonIHGWebsiteURL
|
|
hotelLogo{originalUrl}
|
|
averageReview
|
|
tpiLevel2Violator
|
|
primaryImageUrl{originalUrl}
|
|
latLong{lon lat}
|
|
hotelStatus
|
|
preSellDate
|
|
dateOpened
|
|
totalReviews
|
|
vatIncluded
|
|
}
|
|
media(input:$mediaArgs){
|
|
primaryPhotos{
|
|
allPhotos{
|
|
type
|
|
primary
|
|
caption
|
|
originalUrl
|
|
formats{url aspectHeight aspectWidth}
|
|
}
|
|
}
|
|
}
|
|
foodAndBeverage{
|
|
complimentaryBreakfastDetails{complimentaryGrabAndGoBreakfast}
|
|
}
|
|
restaurant{onSiteRestaurantsCount}
|
|
tax{
|
|
taxAndFeeDetail
|
|
serviceCharge{
|
|
startAndEndDate{startDate endDate}
|
|
description
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
GRAPHQL;
|
|
|
|
$data = json_encode([
|
|
'operationName' => 'GetHotelDetails',
|
|
'variables' => [
|
|
'detailsInput' => [
|
|
'rebrandStartDate' => '2026-04-28',
|
|
'geoLocation' => [
|
|
'lat' => 30.274086,
|
|
'lon' => 120.155071,
|
|
'radius' => 1336,
|
|
],
|
|
'geoLocationDistance' => [
|
|
'distanceType' => 'STRAIGHT_LINE',
|
|
'distanceUnit' => 'KM',
|
|
],
|
|
'size' => 120,
|
|
'fallbackSearch' => [
|
|
'minHotels' => 1,
|
|
'maxRadius' => 100,
|
|
'incrementRadiusBy' => 70,
|
|
],
|
|
'sortBy' => 'DISTANCE',
|
|
],
|
|
'mediaArgs' => [
|
|
'formats' => [
|
|
['aspectHeight' => '3', 'aspectWidth' => '4'],
|
|
['aspectHeight' => '5', 'aspectWidth' => '16'],
|
|
],
|
|
],
|
|
],
|
|
'query' => $query,
|
|
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
|
|
|
|
|
|
$ch = curl_init($url);
|
|
|
|
curl_setopt_array($ch, [
|
|
CURLOPT_RETURNTRANSFER => true,
|
|
CURLOPT_POST => true,
|
|
CURLOPT_HTTPHEADER => $headers,
|
|
CURLOPT_POSTFIELDS => $data,
|
|
CURLOPT_ENCODING => '', // 支持 gzip / br / deflate
|
|
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_2_0, // 对应 --http2
|
|
]);
|
|
|
|
$response = curl_exec($ch);
|
|
|
|
if ($response === false) {
|
|
echo "Curl error: " . curl_error($ch);
|
|
exit;
|
|
}
|
|
|
|
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
|
curl_close($ch);
|
|
|
|
if ($httpCode !== 200) {
|
|
echo "HTTP Error: $httpCode\n";
|
|
echo $response;
|
|
exit;
|
|
}
|
|
|
|
// 保存为 hotel.json
|
|
file_put_contents(__DIR__ . '/hotel.json', $response);
|
|
|
|
echo "保存成功 -> hotel.json\n"; |