跳至内容
免费开始
返回博客

API入门:读取请求并收集数据

Robert Munceanu最后更新于 2 min read
API入门:读取请求并收集数据

开始提取

免费试用 WebScrapingAPI

领取 1,000 个免费 API 积分。无需信用卡。

开始使用
简而言之:API 是一种接口,允许软件调用其他系统的功能。在数据采集方面,你需要学会阅读请求规范,解读响应状态和内容,保护凭证,并在安排更多请求之前验证是否已成功获取目标记录。

某供应商提供了一个产品页面,并为读取该产品目录提供了一个有文档记录的 API。你希望将名称、价格和产品标识符纳入数据集。此时,“API 入门”便成为一个实用的课题:你需要理解程序如何请求数据、会返回什么内容,以及结果是否与你预期的含义一致。

应用程序接口(API)定义了软件如何与某项功能进行交互。并非所有 API 都通过网络访问;编程库也会提供接口。本指南侧重于用于检索数据的 Web API,即你的程序向服务发送请求并解析其响应。MDN 的 API 入门指南对这一更广泛的区别进行了说明。

让我们从一个有文档记录的读取操作和一个预期的记录开始。我们将使用一个虚构的目录,然后分析一个自包含的响应示例。无需账户、API密钥、外部服务或软件安装。目标是提出那些能让你的首次实际集成可靠进行的问题。

通过一个商品目录任务理解初学者所需的 API

假设你的任务是每天早晨记录某款台灯的供应商标价。用户可以打开产品页面直接查看价格,而程序则需要一种可重复的方法来识别该产品,并获取包含相关字段的数据表示。

一份文档完善的 API 可以提供这样的接口。其文档应说明:哪些操作可读取产品信息、标识符如何工作、需要哪些凭据,以及如何解读各字段。您仍需核查覆盖范围:即使受支持的 API,也可能遗漏网站上显示的信息,或采用不同的刷新时间表。

术语

字面含义

虚构目录示例

客户端

发起请求的软件

您的收集脚本

服务器

处理请求的软件

供应商的目录服务

端点

用于API操作的地址

已记录的产品地址

请求

客户端请求工作或数据的消息

读取某类别中的产品

响应

服务器的回复

状态、头部信息以及产品文档

模式

描述数据结构和含义的规则

产品 ID、名称、价格、货币

面向初学者的 API 还应区分受支持的接口与偶然的实现细节。浏览器的开发者工具可能会显示网站使用的请求,但这种发现并不构成公开契约,也不代表允许重用这些请求。请优先使用有文档记录的接口,并遵守其访问条件。

数据抓取和API调用可以作为同一数据管道的输入。数据抓取是从界面或文档中提取信息;调用已文档化的API则是遵循已发布的软件契约。这两者都无法自动保证某个字段是最新的、完整的,或适合您的用途。

在发起请求之前,请定义“成功观察”的标准:一个已知的产品、一个非空的名称、以已知单位和货币表示的价格,以及您收集该信息的时间。该定义将指导后续的每项验证。

选择客户端前请仔细阅读请求规范

HTTP 请求不仅仅是一个 URL。它包含方法、目标、头部,有时还包含正文。每个部分都有其特定功能。在决定发送哪些值或复制其他服务的示例之前,请先阅读提供商的操作说明。

方法描述了请求的语义。GET 用于检索;其他方法则用于不同目的。切勿仅凭名称推断不熟悉端点的效果。HTTP 语义标准定义了实现所基于的通用含义。

URL 标识请求的目标位置。路径可能标识一个产品或集合,而查询参数可提供文档中定义的过滤条件或分页值。请将标识符和游标视为数据。在实现请求时,请使用客户端的 URL 构建功能,以确保空格、标点符号和保留字符被正确编码。

请求头携带元数据。根据协议约定,它们可以指示支持的格式、对客户端进行身份验证,或提供请求的条件。当操作需要时,请求体携带附加内容。将字段放在错误的位置并不等同于正确提供该字段,即使其名称看起来正确。

对于这个虚构的目录,请用通俗语言编写一份请求工作表:读取操作、类别过滤、预期表示形式、所需的凭据方法、超时以及已记录的分页行为。将未知条目作为文档中的待解答问题保留。不要用其他提供商的惯例来填充这些条目。

请将客户端工具视为该工作表的辅助工具。命令行客户端、Python 库和 SDK 在构建请求时具有不同的便利性和默认设置。当您准备实现请求层时,我们的 Python HTTP 客户端指南可帮助您进行比较。

首次实际测试应规模小且仅限读取。如有条件,请使用提供商的测试环境或允许的示例记录,然后在扩展请求范围之前检查响应。

将响应视为状态和数据契约

HTTP 响应包含状态码、标头,以及可能包含的正文。传输成功与业务记录有效是两种不同的观察结果。您的采集器在接受数据之前应同时验证这两点。

状态码概括了 HTTP 层面的请求结果。成功的状态码并不能保证正文包含您的任务所需的精确字段。相反,失败的状态码可能包含结构化的错误正文,其中会说明缺失的参数或过期的凭据。

观察项

接下来应检查什么

不应做何假设

无 HTTP 响应

连接、DNS、TLS 或超时迹象

目录为空

身份验证错误

已记录的凭据要求

重复输入相同的凭据即可修复此问题

权限被拒绝

账户范围和资源访问权限

每次拒绝都意味着网络被封锁

速率限制响应

提供商限制与延迟指南

增加并行请求数量会有帮助

意外内容处理成功

媒体类型、架构和页面标识

任何返回的正文均可视为有效数据

有效的空集合

已应用的过滤器和完成状态

空集合始终表示集合获取失败

请求头有助于解释请求体。诸如 application/json 等媒体类型可标识表示格式,但您仍需处理格式错误或意外内容。由其他组件生成的错误可能以与您请求不同的格式返回。

JSON 是一种文本格式,包含对象、数组、字符串、数字、布尔值和 null 等值。它本身并非 API,也不会自动提供业务含义。JSON 标准定义了格式;而特定字段代表分、欧元、日期还是其他内容,则由提供方定义。

初学者在学习 API 时,应避免将“解析成功”等同于“正确”。解析后需检查必填字段、类型、单位和身份信息。同时应区分缺失、null、零和空文本。合同可能为每种情况赋予不同的含义,而自动默认值可能会抹去这种区别。

将凭证和访问权限作为独立事项处理

API 密钥是某些服务用于识别或验证调用者的凭证。其他接口则使用访问令牌、签名请求或其他机制。提供商的文档应明确说明所需的方法以及凭证应放置的位置。

身份验证和授权针对不同的问题。身份验证用于确定调用者是谁或是什么。授权则决定该调用者是否可以对该资源执行此操作。一个有效的密钥并不一定意味着可以访问每个端点或每个账户的数据。

以虚构的商品目录为例,供应商可能允许公开产品描述,但将仓库库存量限制为特定客户可见。如果价格查询操作成功而库存查询操作失败,请首先核对文档中记录的权限。不要假设有效的凭证意味着第二个请求也必须被允许。

请勿在文章示例、提交的文件、共享的截图以及常规日志中泄露密钥。在实现客户端时,请使用环境变量或部署环境中的经批准的密钥机制。若因诊断需要,请记录凭据标识符,而非密钥值本身。

面向初学者的 API 应明确说明一点:浏览器环境与服务器端程序面临的风险不同。嵌入在浏览器执行的代码中的密钥,对运行该浏览器的人来说是可见的。不要仅仅因为变量名为“private”,就将其视为由服务器持有的凭据。

在安排任务之前,请阅读凭据生命周期文档。确定凭据的过期或轮换方式、系统如何获取替换凭据,以及由哪位所有者负责解决访问失败问题。定时收集器在身份验证失效时需要明确的失败状态,而不是陷入重复发送相同被拒请求的循环。

在分享问题报告时,请包含操作、状态、时间以及经过脱敏处理的错误详情。这些事实有助于服务提供商进行调查,同时不会泄露可访问您数据的凭据。

练习解读自包含响应

假设虚构的目录合约规定 price_minor 表示一个整数(单位为美分), currency 表示货币类型,且 next_cursor 当该结果无下一页时,[value] 要么是不透明的延续值,要么为 null。这些规则专为本练习设计,切勿将其推断应用于其他 API。

以下是一个响应正文的测试 fixture,并非应发送至任何处的请求:

{
  "items": [
    {
      "id": "lamp-17",
      "name": "Desk lamp",
      "price_minor": 2400,
      "currency": "EUR"
    }
  ],
  "next_cursor": null
}

从标识符开始。该项标识 lamp-17,因此你的记录应保留该值,而非使用其在数组中的位置作为产品标识符。名称是一个独立字段,其变更不会导致生成不同的产品。

接下来,应用所述的单位规则。金额为 24.00 欧元,因为本练习明确将该整数定义为分。若无此定义,除以一百将仅是猜测。请在任何格式化的显示值旁保留原始整数和货币,以便后续转换仍可追溯。

然后检查后续内容。Null 表示在此虚构合同下没有下一页。这并不证明供应商的整个库存中只有一种产品;请求可能选择了某个类别或其他过滤条件。完整性始终指代一个已定义的请求范围。

最后,在脑海中构想一些负面情况:移除名称、用文字替换整数,或提供意料之外的货币。确定你的收集器会拒绝或隔离哪些情况。请求主体即使违反了所有有用的业务规则,仍可能保持有效的 JSON 格式。

这项练习抓住了 API 入门的核心:语法、含义和接受度是相互独立的层。真实的实现应使这些层可观察,从而使不熟悉的响应成为可分类的失败,而非看似合理但实际上错误的记录。

在不丢失含义的情况下收集多页数据

API 通常会将较大的集合划分为多页。提供方可能会使用页码、偏移量、游标或链接。请学习文档中记载的延续机制,而不是假设递增一个数字就能检索到所有数据。

游标对消费者而言通常是不透明的:你应按照指示返回给定的值,而不对其进行解释或修改。它可能包含提供方可能更改的状态信息。同样,“下一页”链接也让服务端来指定目标位置。REST 架构指南解释了为何在资源导向型接口中,受支持的过渡机制至关重要。

对于虚构的目录,请在保留延续值的同时保留请求过滤器。一个类别的游标可能不适用于另一个类别。请记录已接受的项目标识符,并定义如何处理重复项,特别是在不断变化的目录可能在收集过程中移动记录的情况下。

速率限制根据提供商的策略限制请求量。 429 Too Many Requests 响应会指示速率限制状态,但该状态并不定义提供商如何统计使用量。RFC 6585 描述了 429 状态码,并指出响应中可包含 Retry-After 指导信息。

请遵循适用的延迟指导,并限制重试次数。应将重复出现的权限错误与临时服务故障区别对待。同时需考虑整个任务:多个工作者各自发出少量请求,其总和可能超过允许的速率。

面向初学者的 API 应包含“完成”的定义。是到达了文档中记载的最后一页,还是因时间限制而停止,抑或是在接收部分记录后失败?请将该分类信息与运行记录一同保存。“收集了 500 种产品”并不能揭示请求范围中包含的是 500 种还是更多。

在已接收的数据被持久化存储后保存进度,并设计重启行为以避免跳过工作。请在输出中保留收集时间窗口,因为对不断变化的数据源进行长时间遍历,可能代表的是随时间推移的观测结果,而非某个精确的快照。

从单次成功请求转向可靠的工作流

一次成功的响应仅证明在特定条件下一次交互有效。计划任务收集器还必须处理数据变更、访问权限过期、部分运行以及输出失败等情况。应有意识地逐步增加这些职责,而非首先增加请求量。

从一份简短的接受报告开始。报告中应包含请求范围、采集时间、已接受记录数、被拒绝记录数、延续状态以及(如适用)故障类别。避免在报告中包含原始密钥或不受限制的响应正文。

保持源数据检索与数据交付之间的区别。如果记录在本地已被接受但导出失败,适当的恢复措施可能是重新发送已保存的输出,而不是再次获取源数据。第二次检索可能会产生不同的观测结果,不应在未提示的情况下替换原始结果。

明确数据时效性的处理规则。已存储的响应不能仅因其曾经有效就自动视为最新。HTTP 缓存有关于重用和验证的规则,详见 RFC 9111。对于您的数据集,还应说明下游消费者可容忍的观测数据时效上限。

在安排任务前,先对一套简短的故障场景进行测试:无效凭证、缺少必填字段、有效结果为空,以及分页运行中止。应使用测试数据或受控测试环境,而非向数据提供方产生不必要的流量。每种情况都应导致明确的结果。

当这些结果有了明确的责任人时,“面向初学者的 API”便升华为运维工程。明确指定谁负责处理访问问题、谁负责更新模式映射,以及谁决定是否应交付不完整的运行结果。自动化采集指南将这些检查与调度及恢复流程相连接。

将首个生产工作流的范围控制得较窄。一个范围明确且验证可靠的简小采集器,比一个范围宽泛、成功退出却掩盖了数据缺失问题的采集器更容易扩展。

关键要点

  • 在选择客户端之前,请仔细阅读已记录的请求契约,包括方法、目标、参数、头部信息和所需凭据。
  • 分别检查响应状态、表示格式和业务字段;有效的 JSON 并不等同于有效的生产记录。
  • 保留标识符、原始值、单位和采集上下文,以确保数据转换过程易于理解且可逆。
  • 在将单次成功请求视为可转为定时任务之前,应先定义分页完成条件、速率限制处理及重启行为。
  • 使用明确的故障分类并保护机密信息,以确保维护工作不依赖于复制敏感的请求跟踪记录。

常见问题

API 与数据库是一回事吗?

不。数据库用于存储和管理数据,而 API 则提供了一个用于使用功能或信息的接口。一个服务可以组合多个数据库,或在不暴露这些细节的情况下计算出结果。调用方应依赖于已发布的 API 契约,而不是猜测响应代表的是哪个内部表。

调用 API 需要浏览器吗?

不一定。许多有文档记录的 Web API 可以通过服务器端的 HTTP 客户端调用,而无需渲染页面。具体需要什么取决于提供方的身份验证和交互要求。浏览器对于查阅文档可能很有帮助,但使用浏览器并不能替代对请求契约的理解或正确处理响应。

每个 API 都会按请求收费吗?

不一定。访问安排因提供商和服务而异,因此请查阅具体的套餐和使用条款。不要假设失败的请求是免费的,也不要认为试用版与其它套餐的限制相同。请在集成时记录相关的使用规则,以确保计划中的工作保持在预期范围内。

结论

您的第一个里程碑是一个能够解释清楚的记录:该记录来自哪项操作、每个字段的含义、何时获取的,以及为何通过了验证。这比一个仅输出陌生请求体并成功退出的脚本更有价值。

对于真实的提供商,请参照其文档重复上述虚构的目录练习。记录请求输入,保留原始响应的含义,并确定终止数据收集的确切条件。然后在添加更多页面或安排定时任务之前,先测试一个失败的案例。这样可以让初学者的 API 操作立足于可检查的行为。

如果所需信息只能通过网页获取,请考虑将 WebScrapingAPI 的 Scraper API 作为数据采集选项。对该输入也应保持同样的习惯:保护凭据、检查响应、验证提取的记录,并保留足够的上下文信息,以便他人能够理解结果。

关于作者

Robert Munceanu, 全栈开发工程师 @ WebScrapingAPI

Robert Munceanu

全栈开发工程师

罗伯特·蒙塞阿努(Robert Munceanu)是 WebScrapingAPI 的全栈开发工程师,他在产品各领域均有贡献,并协助构建了支持该平台的可靠工具和功能。

开始构建

准备好扩展您的数据收集规模了吗?

加入2,000多家企业,使用WebScrapingAPI在无需任何基础设施开销的情况下,以企业级规模提取网络数据。