
Sora Fujimoto
AI Solutions Architect

AIトラベルエージェントにとって、ホテル価格モニタリングデータは、各レートが比較可能で、最新かつソースに追跡可能である場合にのみ価値があります。表示される1泊の価格は、税金が含まれていない、宿泊者数に依存する、会員資格が必要、または隣接するオファーとは異なるキャンセルポリシーを持つことがあります。したがって、正しいアーキテクチャは、公式ホテルおよびトラベルAPIから始まり、すべてのオファーを共通のスキーマに変換し、透明性のある滞在合計を計算し、収集タイムスタンプと条件を記録します。許可されたブラウザ収集は、文書化されたギャップを埋めるために使用できますが、CAPTCHAの復元は制限された例外として扱うべきであり、主な取得方法としては使用しないでください。このガイドは、レートアラート、柔軟な日付の推奨、均等性分析、イタinerary計画のための実用的なモニタリングパイプラインを構築しますが、予約における同意、ソースの条件、および人間の承認を維持します。
エージェントがゲストが受け取る内容と適用される制約を知るまで、レートは比較可能ではありません。最低限、次をキャプチャしてください。
from dataclasses import dataclass, field
from datetime import datetime, timezone
@dataclass
class HotelOffer:
property_id: str
property_name: str
source: str
check_in: str
check_out: str
adults: int
children: int
room_type: str
meal_plan: str | None
refundable: bool | None
cancellation_deadline: str | None
currency: str
nightly_base: float
taxes: float
fees: float
total_price: float
rate_key: str | None
collected_at: str = field(
default_factory=lambda: datetime.now(timezone.utc).isoformat()
)
合計価格は、要求された滞在と宿泊者数を表す必要があります。税金や必須手数料が不明な場合は、オファーを不完全としてラベル付けし、最も安価なオプションとしてランク付けしないでください。
CapSolver web-scrapingブログには一般的な収集パターンが記載されており、CapSolver web-scraping FAQでは一般的な運用上の質問がカバーされています。
公式APIは明示的なスキーマ、認証、商用条件を提供します。Sabre Get Hotel Rate Info APIは、複数のサプライ元からリアルタイムのプロパティレート取得を記述しています。このレスポンスには、平均1泊料金、通貨、税前および税後金額、手数料、ルーム詳細、食事プラン、保証要件、キャンセル条件、およびレートキーが含まれる場合があります。
GoogleのHotel Pricesドキュメントは、ホテルリスト、空室状況、料金および在庫、取引、レートルール、クエリ、日付/時刻形式のパートナーリソースを定義しています。現在のAmadeus Enterprise APIポータルは、承認されたエンタープライズカスタマー向けのホテル関連APIへのアクセスを提供しています。
| データソース | 最適な用途 | 強み | 制約 |
|---|---|---|---|
| ホテルまたはチェーンAPI | 第三者空室状況と直接料金 | 明確な所有権と最新在庫 | 1つのサプライヤーに限定される |
| GDSまたはトラベルAPI | 多サプライヤー料金検索 | 構造化されたオファーと予約キー | 契約と認証が必要 |
| パートナーフィード | 大規模な在庫と価格更新 | 効率的なバッチ処理 | パートナー承認とフィードルール |
| 許可された公開ページ | 検証またはギャップカバレッジ | ゲスト向け表示を反映 | レイアウト変更とトラフィック検証 |
パートナーフィードを一般的なパブリックエンドポイントとして扱わないでください。プロバイダの契約、キャッシュポリシー、表示ルール、予約要件に従ってください。
異なるソースは異なる構造を返します。すべてのソースを小さなアダプタの後ろに配置し、同じHotelOfferモデルを返してください。
import requests
from decimal import Decimal
class HotelRateAdapter:
def __init__(self, base_url: str, token: str):
self.base_url = base_url.rstrip("/")
self.token = token
def search(
self,
property_id: str,
check_in: str,
check_out: str,
adults: int = 2,
currency: str = "USD",
) -> list[HotelOffer]:
response = requests.post(
f"{self.base_url}/hotel-rates/search",
headers={
"Authorization": f"Bearer {self.token}",
"Accept": "application/json",
},
json={
"propertyId": property_id,
"checkIn": check_in,
"checkOut": check_out,
"adults": adults,
"currency": currency,
},
timeout=30,
)
response.raise_for_status()
return [self._normalize(item) for item in response.json()["offers"]]
def _normalize(self, raw: dict) -> HotelOffer:
base = Decimal(str(raw["price"]["base"]))
taxes = Decimal(str(raw["price"].get("taxes", 0)))
fees = Decimal(str(raw["price"].get("fees", 0)))
return HotelOffer(
property_id=raw["propertyId"],
property_name=raw["propertyName"],
source=raw["source"],
check_in=raw["checkIn"],
check_out=raw["checkOut"],
adults=raw["occupancy"]["adults"],
children=raw["occupancy"].get("children", 0),
room_type=raw["room"]["name"],
meal_plan=raw.get("mealPlan"),
refundable=raw.get("refundable"),
cancellation_deadline=raw.get("cancellationDeadline"),
currency=raw["price"]["currency"],
nightly_base=float(base),
taxes=float(taxes),
fees=float(fees),
total_price=float(base + taxes + fees),
rate_key=raw.get("rateKey"),
)
上記のエンドポイントとフィールドマッピングはアダプタ境界を表しており、あなたの承認されたプロバイダの正確な契約に置き換えてください。本番コードでプロバイダフィールドを発明しないでください。
価格比較のエラーは通常、算術ではなく、条件の不一致から生じます。同じプロパティ、滞在日、宿泊者数、ルームカテゴリ、レート制限を共有するオファーのみをグループ化してください。
from dataclasses import asdict
def comparison_key(offer: HotelOffer) -> tuple:
return (
offer.property_id,
offer.check_in,
offer.check_out,
offer.adults,
offer.children,
offer.room_type.strip().lower(),
(offer.meal_plan or "unknown").strip().lower(),
offer.refundable,
)
def comparable_snapshot(offers: list[HotelOffer]) -> list[dict]:
return sorted(
[asdict(o) for o in offers],
key=lambda item: (
item["total_price"],
item["source"],
),
)
通貨をタイムスタンプ付きのソースで変換し、元の金額を保持してください。明示的な調整またはユーザーの好みなしに、払い戻し可能な朝食料金を払い戻し不可のルームのみの料金と比較しないでください。
CapSolver Pythonスクレイピングガイドはアダプタの構築に役立ち、CapSolver用語集はチーム間で用語を標準化するのに役立ちます。
ホテル料金はプロパティ、日付、在庫圧力、予約窓口によって変化します。同じ頻度ですべてのプロパティをポーリングするのではなく、ポリシー駆動のスケジュールを使用してください。
from datetime import date
def monitoring_interval_days(check_in: date, today: date) -> int:
days_out = (check_in - today).days
if days_out <= 3:
return 1
if days_out <= 14:
return 2
if days_out <= 60:
return 4
return 7
プロダクションスケジューラーは、プロバイダの制限、プロパティの優先順位、最近の価格変動性、ユーザーのアラート設定も考慮する必要があります。ジョイターアプリケーションの開始時間を調整して、リクエストの突発を回避してください。
小さな通貨または丸めの違いでアラートを発信しないでください。すべての合計と重要なポリシー変更を比較してください。
from decimal import Decimal
def detect_offer_change(previous: HotelOffer, current: HotelOffer) -> dict:
old_total = Decimal(str(previous.total_price))
new_total = Decimal(str(current.total_price))
amount_change = new_total - old_total
pct_change = (
(amount_change / old_total * 100) if old_total else Decimal("0")
)
policy_changed = any([
previous.refundable != current.refundable,
previous.cancellation_deadline != current.cancellation_deadline,
previous.meal_plan != current.meal_plan,
])
return {
"amount_change": float(amount_change),
"percent_change": round(float(pct_change), 2),
"policy_changed": policy_changed,
"alert": abs(pct_change) >= Decimal("5") or policy_changed,
}
しきい値はアプリケーションに応じて調整してください。企業のトラベルプログラムでは小さなポリシー変更に注意を払うかもしれませんが、消費者のアラートではより大きな合計価格の削減に焦点を当てます。
承認されたワークフローの一部は、公開された表示価格を検証するか、契約されたAPIで入手できないフィールドを収集する必要があります。サイトの利用規約とあなたの契約が許可している場合にのみブラウザフォールバックを使用してください。
ユーザーが提供したCapSolver Agentドキュメントは、ブラウザ復元をcapsolver-coreのdetect()とsolve_on_page()にマッピングしています:
import os
from capsolver_core import Capsolver
cap = Capsolver(
api_key=os.environ["CAPSOLVER_API_KEY"],
default_timeout=180,
)
async def recover_rate_check(page) -> dict:
challenge = await cap.detect(page)
if not challenge:
return {"handled": False, "reason": "No supported challenge detected"}
result = await cap.solve_on_page(page)
return {"handled": True, "result": result}
同じ許可されたブラウザコンテキストを保持し、保守的なリクエストレートを維持し、1回の制限付き復元試行後に停止してください。CapSolver CAPTCHA解決FAQは一般的なタスクライフサイクルを説明し、CapSolverトラブルシューティングFAQは一般的な失敗状況をカバーしています。
ボーナスコード: CapSolverダッシュボードでコード WEBS を使用すると、すべてのチャージで追加の5%ボーナスが得られます。
AIトラベルエージェントは、単なるプロバイダペイロードではなく、簡潔で証拠に基づいたスナップショットを受け取るべきです。
def build_agent_snapshot(offers: list[HotelOffer]) -> dict:
complete = [
offer for offer in offers
if offer.total_price > 0 and offer.currency and offer.room_type
]
complete.sort(key=lambda offer: offer.total_price)
return {
"query": {
"property_id": complete[0].property_id if complete else None,
"check_in": complete[0].check_in if complete else None,
"check_out": complete[0].check_out if complete else None,
},
"best_flexible_offer": asdict(complete[0]) if complete else None,
"alternatives": [asdict(o) for o in complete[1:6]],
"warnings": [
"予約前に料金が変更される可能性があります。",
"チェックアウト時に合計、空室状況、キャンセル条件を確認してください。",
],
}
エージェントに価格と柔軟性のトレードオフを説明するようにプロンプトしてください。プロバイダの予約または価格確認エンドポイントが確認していない限り、部屋が予約されていることや、料金が保証されていることを主張しないでください。
モニタリングは読み取り専用です。予約は在庫を変更し、財務義務を生み、通常個人データが必要です。これらの機能を別々のサービスに保持し、予約エンドポイントを呼び出す前に明示的な確認を必要とします。
| ステージ | 自動化レベル | 必要なコントロール |
|---|---|---|
| レート収集 | 自動化 | 承認されたソースとレートリミット |
| 正規化 | 自動化 | スキーマ検証と出典 |
| アラート生成 | 自動化 | ユーザー定義のしきい値 |
| 推奨 | 補助 | 透明な比較基準 |
| 価格再確認 | 自動化(購入前) | 新たなプロバイダ確認 |
| 予約および支払い | 人間確認 | 認証と明示的な承認 |
この境界は、AIエージェントが古いモニタリング観測を意図しない購入に変えることを防ぎます。
プロパティマッチ信頼度、ソースの遅延、不明な税金、通貨変換時間、重複するレートキー、パーサーのバージョン、収集エラーを追跡してください。ライセンス許可がある場合、元のプロバイダレスポンスまたは整合性ハッシュを保持してください。プロパティがソース間で自信を持ってマッチできない場合、名前だけでレコードをマージするのではなく、レビューにルーティングしてください。
有益なメトリクスには、各ソースの成功観測数、不完全価格レート、中央値収集遅延、重要な価格変更率、チャレンジ遭遇率、人間レビュー量が含まれます。これらのメトリクスは、推奨に影響を与える前にデータ品質の問題を明らかにします。
認可されたAPI、フィード、ウェブサイト、アカウントのみを使用してください。パートナー契約、ウェブサイトの利用規約、キャッシュ制限、地域ごとの消費者価格ルール、プライバリーリクエストを遵守してください。明示的な承諾なしに、プライベート予約データやロイヤルティアカウント情報を収集しないでください。利用可能な場合、公式の構造化インターフェースを優先し、ブラウザトラフィックを最小限に抑えます。
信頼性のあるホテル価格モニタリングデータは、ページから数値を収集するだけでは得られません。AIトラベルエージェントは、正規化された滞在条件、すべてを含む合計、ポリシー詳細、タイムスタンプ、ソースの出典が必要です。公式ホテルおよびGDSAPIを基盤とし、許可されたブラウザチェックは制限付きギャップカバレッジを提供し、サポートされるチャレンジがセッションを中断する場合、CapSolverは制御された復元層として機能します。
最初の承認されたワークフローをCapSolverで構築し、その後プロバイダー固有のアダプター、価格変動のしきい値、予約アクション前の必須再確認を追加してください。
少なくとも物件ID、滞在日、宿泊者数、部屋タイプ、食事プラン、払い戻し可能かどうか、キャンセル期限、通貨、税、手数料、総価格、ソース、収集タイムスタンプを保存してください。
まず公式APIやパートナーフィードを使用してください。ブラウザ収集は、構造化されたアクセスが必須フィールドを提供できない場合に限り、許可された公開ページまたは承認されたQAおよび検証タスクに限定してください。
予約期間、価格の変動性、プロバイダーの制限、アラートの緊急性に基づいたポリシーを使用してください。近い日程の予約は頻繁にチェックし、遠い日程の予約はそれほど頻繁にはチェックしないでください。
いいえ。予約の前にプロバイダーを通じて価格と空室状況を再確認し、予約または支払い義務の作成前に明示的なユーザーの確認を求めてください。
CapSolverは、認可されたブラウザセッションでのサポートされているチャレンジの制御された復元レイヤーです。プロバイダーのアクセス権、レートリミット、API、または予約確認を置き換えるものではありません。
スケーラブルなRustウェブスクレイピングアーキテクチャを学びましょう。リクエスト、スクレイパー、非同期スクレイピング、ヘッドレスブラウザスクレイピング、プロキシローテーション、およびコンプライアンス対応のCAPTCHA処理で。

2026年のデータ・アズ・ア・サービス(DaaS)を理解する。その利点、ユースケース、およびリアルタイムの洞察と拡張性を通じて企業を変革する方法について探る。
