返回知识中心
网络

机票价格抓取的四个固定输入

把货币、区域设置、销售点和设备固定住,票价差异才是价格差异;并在每次抓取时把这四项与报价一起记录下来。

BotBrowser Team

文档中心

想直接进入 网络 文档吗?

这篇文章属于知识中心的指南库。若你要步骤化配置、参考说明和持续更新,请直接进入对应 docs 分区。

只有当每个请求背后的环境保持恒定时,机票价格抓取才会产生可用的序列。票价是按货币、区域设置、销售点和设备报出的,改动其中任何一项都可能改变数字,而市场本身毫无变化。BotBrowser 文档说明了由配置文件驱动的区域设置、时区与语言输入,以及地理对齐的出口,因此一次抓取可以声明它所代表的环境。它不提供票价、不订票、不控制航空公司的定价逻辑,也不保证报价会再次出现。存在持牌票价数据源或代理 API 时,应当使用那条路径。

决定请求收到哪张票价的四项构造输入:货币、声明的区域设置、销售点与设备,各自附带固定它的方式,并附一份把可比价格变化与环境变化区分开的差异分类。

摘要

  • 票价是按特定的货币、区域设置、销售点和设备报出的。四项都要固定,否则测到的差异有一部分是环境差异。
  • 货币是请求或账户设置,不是浏览器配置文件的取值。区域设置与语言来自配置文件。销售点是站点参数,必须与出口区域和账户一致。
  • 把四项随每一次报价一起记录,而不是每次运行记一次。
  • 按哪一项发生变化来给差异分类。货币变化不是票价变动,无论数字变化多大。
  • 存在持牌票价数据源或代理 API 时优先使用。一次浏览器运行既不会产生监控许可,也无法订票。

目录

会改变票价的四项输入

一次航班搜索携带的不只是出发地、目的地和日期。它还携带货币、语言偏好、行程所面向的市场,以及可能选中另一组报价的设备类别。这四项不能互相替代,一组让它们变化的监控序列,测量自己的配置和测量票价一样多。

输入在哪里设置可能改变什么
货币请求参数或账户设置报价金额及其取整方式
区域设置配置文件中的区域设置与语言列表页面语言、格式,有时还有报价集合
销售点站点参数、出口区域与账户三者共同决定适用哪一套库存与规则
设备视口与配置文件中的设备取值布局,有时是仅移动端可见的报价

schema.org 的 Offer 类型在这里给出了有用的词汇形状。它定义了 price,并建议搭配 priceCurrency,使用 ISO 4217 代码而不是含糊的符号,同时提醒不要在数值内部使用分隔符。这条指引谈的是发布报价,却直接对应到抓取问题:记录成 $412 的票价不是事实,而 412 USD 是可比较的观察。

第二项与第三项最容易被混为一谈。区域设置是浏览器声明的东西。销售点是站点为哪个市场定价,通常由站点参数、请求看起来来自的区域以及账户自身的设置共同推导。让浏览器声明德语,本身并不会让票价变成德国销售点的票价;从德国地址出口,本身也不会设定货币。

货币值得单独一段,因为它是最常被隐含掉的输入。站点可能接受显式货币参数、从销售点推导,或从账户偏好读取,这三条路径可能互相矛盾。矛盾时页面通常显示一种货币而结账显示另一种,或者同一货币套用了不同汇率。请记录页面实际显示的货币,而不是请求索要的货币,并把销售点记录在旁边,因为正是这一对才让金额可复现。

取整是更小但持续存在的噪声源。从一种货币换算到另一种的票价按该货币特有的精度取整,有些货币取整到整数单位,另一些保留两位小数。因此同一张票价在同一货币下的两次抓取应当完全一致;若相差不足一个单位,差异通常来自换算而非票价变化,记录应当这样标注,而不是把这个零头当作变动。

税费属于同一类问题。显示的金额可能含税、不含税,或只含取决于销售点的某个子集,而包含范围一变,看起来就和价格变化一模一样。页面说明时,请记录显示金额包含什么,并把该字段与金额放在一起。一组从含税显示切换到不含税显示的序列,会呈现一个与票价毫无关系的台阶。

配置文件究竟固定了哪几项

BotBrowser 的时区、区域设置与语言文档描述了在配置代理时从出口 IP 自动推导,以及对手动设置时区、区域设置与语言的覆盖,其中手动覆盖需要 ENT Tier1 许可。GeoIP 文档描述了把出口地址翻译成地理默认值,并直白说明了精度边界:国家级映射通常可靠,城市级映射可能落到邻近城市或区域。

这覆盖了表格中区域设置那一半,以及销售点的一部分。它不覆盖货币,也没有完全覆盖销售点,因为站点可以在与所服务语言无关的情况下接受货币参数,这属于站点行为,而不是有文档的浏览器输入。一个假定「配置文件会处理一切」的监控设计,实际只固定了四项中的两项,却以为固定了四项。

输入配置文件是否固定需要显式检查
货币否请求参数或账户设置
区域设置配置后是页面实际报告的语言列表
销售点部分站点自己给出的市场指示
设备配置后是视口与页面报告的设备取值

实际后果是:检查必须按每次抓取做,而不是按配置做。一开始配置正确的运行,只要有人改了请求参数、加了覆盖项,或为某个区域换了代理,就会漂移。在报价那一刻记录四项,是唯一能知道究竟哪几项生效的办法。

设备类别是最会隐藏的一项。桌面视口与移动视口可能返回不同报价集合,有些航空公司会放出仅移动端存在的票价,桌面路径上根本不存在。那不是同一报价两次观察之间的价格变化,而是另一个报价。请把视口与设备类别一起记录,让后来的读者能判断两次抓取是否用了同一个视口,并把报价集合的变化当作设备效应而不是票价变动。

环境内部还有时间维度。促销期内的一次抓取与一小时后的另一次抓取可能不同,因为促销结束了;这是来源侧变化,四项输入正确地报告为未变。这是正确的结果:记录正在发挥作用,排除了抓取作为解释。要避免的是反向错误,把货币切换能解释的差异归咎于来源。

最后一条习惯成本很低,值得写出。请在票价页面加载之前记录四项,而不是之后,并把加载前的值留在记录里。页面可能在自身客户端初始化期间改掉区域设置或货币,因此报价之后读到的值描述的是最终状态,而不是请求携带的状态。两者不同时都记下来,就把一处令人困惑的差异变成了有据可查的转变。

每次抓取都记录这四项

票价监控的抓取记录很小。它需要行程、带货币的报价金额、四项输入以及观察时间。其余都是辅助细节。

字段内容为什么在记录里
itinerary_key请求的航线、日期与舱位定义比较的对象
amount带小数点的数值只有配合货币才可比较
currencyISO 4217 代码避免把符号读成金额
accept_language抓取时声明的语言列表显示生效的区域设置
point_of_sale站点指示的市场把市场与语言分开
device_class桌面或移动,附视口把布局与票价分开
observed_at抓取时间(UTC)排序观察并暴露排期变化
alignmentaligned 或发生变化的那一项阻止不可比的行进入序列

表中有两处很容易记错。amount 应当是带小数点的数值而不是格式化字符串,因为字符串携带所在区域的分隔符习惯,一旦序列跨两个区域就变得含糊。point_of_sale 应当是站点指示的内容,而不是操作方的意图:站点没有兑现的意图,正是最值得抓出来的情形。

下面的记录构造器比较同一行程的两次抓取,并报告哪些输入保持不变。用例是构造的。

// Constructed fixture: two captures of one itinerary, one input changed.
const captureA = {
  itineraryKey: 'YYZ-LHR 2026-12-10 Y',
  amount: 812.4,
  currency: 'CAD',
  acceptLanguage: 'en-CA,en',
  pointOfSale: 'CA',
  deviceClass: 'desktop',
  observedAt: '2026-11-10T09:00:00Z',
};
const captureB = {
  itineraryKey: 'YYZ-LHR 2026-12-10 Y',
  amount: 512.1,
  currency: 'EUR',
  acceptLanguage: 'en-CA,en',
  pointOfSale: 'CA',
  deviceClass: 'desktop',
  observedAt: '2026-11-10T09:00:30Z',
};

const FIELDS = ['currency', 'acceptLanguage', 'pointOfSale', 'deviceClass'];
const changed = FIELDS.filter(f => captureA[f] !== captureB[f]);
const alignment = changed.length === 0 ? 'aligned' : `input_changed:${changed.join(',')}`;

const lines = [
  `itinerary=${captureA.itineraryKey}`,
  `a=${captureA.amount} ${captureA.currency} b=${captureB.amount} ${captureB.currency}`,
  `currency=${captureA.currency}->${captureB.currency} locale=${captureA.acceptLanguage}`,
  `pos=${captureA.pointOfSale} device=${captureA.deviceClass}`,
  `changed=${changed.join(',') || 'none'} alignment=${alignment}`,
  `observed_at=${captureA.observedAt}->${captureB.observedAt}`,
];
console.log(lines.join('\n'));

下面的构造输出正是这个练习的目的。金额下降了约 37%,而分类说明这次下跌根本不是票价变动。

itinerary=YYZ-LHR 2026-12-10 Y
a=812.4 CAD b=512.1 EUR
currency=CAD->EUR locale=en-CA,en
pos=CA device=desktop
changed=currency alignment=input_changed:currency
observed_at=2026-11-10T09:00:00Z->2026-11-10T09:00:30Z

按发生变化的输入来读价格差异

差异的大小说明不了原因。有用的问题是哪些输入保持不变,因为这决定了这对抓取能支持什么。

保持不变的输入观察差异能支持什么
四项完全相同金额不同该环境下可比的价格变化
只有货币不同金额不同换算或重新定价,不是票价变动
只有销售点不同金额不同两个市场;彼此都不是对方的基线
只有设备类别不同金额或报价集合变化依赖设备的报价,不是票价变化

只有第一行能支持票价序列。第二行是实践中最常见的错误,因为货币切换会把数字改动一个很大的倍数,得到的图表看起来像剧烈波动。第三行是市场比较,必须建成两条序列而不是一条。第四行是仅移动端报价冒充价格变化的地方。

还有两点提醒属于读法而不是记录。第一,报价不是可订价格:税费与可售情况可能在报价与结账页之间变化。第二,环境未变的重复抓取仍可能不同,因为航空公司自身的库存或票价规则变了;这是真实的观察,应当标注为来源侧变化,而不是抓取错误。

价格监控架构 覆盖一般价格序列的调度与变化检测。旅行场景增加的是:这四项输入彼此之间的独立性比零售更强,因为零售中单个商品页通常隐含一种货币和一种区域设置。配置文件与路由一致性记录 是销售点出口那一半的恰当补充。 可用性日历需要按日期为键而不是按商品为键,可用性模型 说明了如何让这份日历在多次抓取之间保持可比。

何时应改用持牌票价数据源

多数航空公司与大型代理都提供持牌路径:票价分发数据源、代理 API,或约定的数据导出。这些路径以已定义的 schema、已声明的更新频率,以及一份说明数据可用于什么的许可,提供同样的行程。存在这样的路径时,浏览器运行通常是错误的工具,因为它为一个已经提供受支持路径的来源,产出更不稳定的序列并带来更多法律暴露。

不存在这类路径时,诚实的问题是:究竟是什么授权了这次观察。一个可用的浏览器会话不是答案。适用的航空公司或代理条款说了算,而它们经常限制自动访问、票价数据转售和缓存价格的展示。请把运行的依据与抓取一起记录,让后来的读者继承答案而不是假定。

schema.org 的 FlightReservation 类型从另一侧提醒同一条界线。它为预订定义了词汇,含 bookingTime、乘客字段,以及指向航班的 reservationFor。它描述预订可以如何表示;它不说明票价是否可被监控,也不说明结账时的报价会是多少。

这套词汇仍然有助于命名抓取保持分离的东西。预订不是报价,报价也不是票价规则。当一份记录把三者混在一起,后来的比较就无法判断航空公司改的是价格、行程,还是附带条件。请让行程键描述所请求的内容,让金额与货币描述所报出的内容,让四项环境输入描述报价是如何取得的。

常见问题

货币变化是价格变化吗?

不是。它改变金额的单位,通常也改变取整方式。中途切换货币的序列测量的是这次切换,因此每条序列只保留一种货币,或用已声明的汇率换算并记录换算。

浏览器配置文件能固定销售点吗?

只能部分固定。配置文件控制区域设置、语言,以及通过代理体现的表面区域。站点的销售点常常是单独的参数或账户设置,因此请核实站点指示的内容,而不是操作方的意图。

同一行程总是返回同一价格吗?

不是。库存与票价规则会变化,报价也不是结账总额。环境未变的重复抓取仍可能不同,而那个差异属于来源。

BotBrowser 提供票价或订票吗?

不提供。它提供有文档的浏览器输入,让一次抓取可以声明自己的环境。它不提供票价数据、不订票,也不保证报价。

来源

实践结论

在第一次抓取之前,先决定这组序列代表哪种货币、区域设置、销售点与设备。每次抓取都核实这四项,因为配置文件完全固定其中两项、部分固定一项,并把它们与报价金额、观察时间记录在一起。按发生变化的输入给每个差异分类,并把货币切换当作环境变化而不是票价变动。存在持牌票价数据源或代理 API 时,使用它,并把浏览器运行排除在设计之外。

#机票价格抓取#票价监控#浏览器自动化

本文属于指南: 代理配置总览:浏览器网络决策图

在 BotBrowser 里跑一遍同样的检查

加载 profile,让刚读到的这些信号在浏览器内部保持一致,并在正式上线前先在自己的机器上确认结果。