从 Amazon 商品页面抓取价格,听起来很简单,但一旦要大规模自动化,就会遇到重重挑战。页面在客户端渲染,标记会随布局变化而改变,同一件商品可能同时显示促销价、定价、优惠券价和订阅立省价。过去的解决方案是一堆脆弱的 CSS 选择器或 XPath,Amazon 一有改动就会失效。AI 改变了这一计算方式:不再需要描述价格在 DOM 中的位置,而是直接将页面内容交给模型,用普通英语告诉它你想要什么。
本指南将向你展示如何用可靠的方式使用 AI 抓取 Amazon 价格。使用 Crawling API 获取并渲染公开的商品页面,转换为整洁的 Markdown,然后将该内容传递给大型语言模型,由模型以结构化 JSON 格式返回价格及相关字段。这种分工正是关键所在:Crawlbase 负责在真实浏览器和可信 IP 后面完成抓取和渲染,模型负责读取和结构化。每个工具只做自己真正擅长的部分。
为什么要将 AI 与抓取层配合使用
语言模型擅长读取杂乱内容并按需返回结构化数据。但它无法抓取网页,没有 HTTP 客户端、没有浏览器、没有代理池,也无法绕过 Amazon 这类网站的反爬虫防护。给它一个 URL,它打不开;给它你自己抓到的原始 HTML,它会从你实际获取的内容中提取,而在 Amazon 上,这通常是一个几乎空白的外壳或 CAPTCHA 页面。
抓取层填补的正是这一空白。Amazon 在浏览器中渲染价格和库存信息,并会迅速识别自动化流量,因此简单的 requests.get 通常会返回一个 200 响应,但其中没有任何你想要的数据。你需要一个能运行页面 JavaScript 的浏览器,以及一个被网站识别为真实访客的 IP。你可以自己搭建无头浏览器加轮换住宅代理,但维护这套方案本身就是大部分工作量。Crawling API 将两者合为一次调用:发送带有 JavaScript token 的 URL,它渲染页面并返回处理完毕的内容,供模型直接使用。
保持边界清晰。Crawlbase 抓取并渲染 Amazon 页面,输出整洁的 Markdown。模型提取价格及相关字段。在这套设计中,模型从不接触网络,Crawlbase 也从不尝试理解数据。混淆这两项职责是此类流水线感觉不稳定的最常见原因。
抓取 Amazon 价格合法吗?
这取决于 Amazon 的服务条款、你所在的司法管辖区,以及你对数据的用途。Amazon 的条款限制自动化访问,因此无论你的工具多么谨慎,抓取行为都可能违反这些条款。本文的任何代码都不会改变这一现实,它只是让技术层面的工作得以实现。请认真对待法律问题,而不是走过场。
有几条原则值得坚守。只收集公开数据:任何人无需登录即可在商品页面看到的价格、标题、评分和库存信息。遵守 Amazon 的 robots.txt 及其明确的请求频率预期,并将请求量控制在不会给服务器造成压力的范围内。如果你打算将数据用于商业目的,请先获得许可或签订官方数据协议,而不是默认沉默即为同意。永远不要收集个人数据,包括与个人客户账户绑定的任何信息,或可归因于可识别个人的评论。
本演示故意将范围限定在公开商品数据,因为这是保持工作合法性的边界。它不涉及登录后的任何内容、账户或订单数据、支付流程,也不涉及任何绕过身份验证的尝试。如果你的项目需要的不只是公开商品页面,正确的做法是与 Amazon 签订官方 API 或数据协议,而不是打造一个更聪明的爬虫。
你将构建什么
一个小型、可运行的 Python 脚本,接收一个 Amazon 商品 URL,通过 Crawling API 获取渲染后的页面(转为整洁的 Markdown),将 Markdown 连同提取提示词发送给语言模型,最后将结构化结果写入 JSON 文件。我们将用一个真实的商品页面进行演示,但同样的脚本适用于你替换进去的任何公开 Amazon URL。
配置环境
你需要 Python 3.8 或更高版本。确认版本,创建虚拟环境以隔离项目依赖,然后安装所需库。
python --version python -m venv amazon_env source amazon_env/bin/activate pip install openai crawlbase python-dotenv
在 Windows 上,用 amazon_env\Scripts\activate 替代 source 命令来激活环境。三个依赖各司其职:crawlbase 是 Crawling API 的官方客户端,openai 是语言模型的客户端,python-dotenv 从本地文件加载密钥,使其不会硬编码在脚本中。
你需要两个凭据。从模型提供商的控制台获取 API 密钥,并在注册 Crawlbase 后从 Crawlbase 控制台获取 JavaScript (JS) token。将两者存入项目目录中的 .env 文件。
OPENAI_API_KEY=your_model_api_key_here CRAWLBASE_JS_TOKEN=your_crawlbase_js_token_here
Crawlbase 提供两种 token 类型。普通 token 抓取静态 HTML;JavaScript (JS) token 先在真实浏览器中渲染页面。Amazon 在客户端加载价格,因此这里选 JS token 才是正确的。在客户端渲染的页面上使用普通 token,返回的是和直接抓取一样的空壳,模型自然无法提取一个从未出现过的价格。
第一步:获取渲染后的 Amazon 页面
Crawling API 可以将页面直接转换为 Markdown 后返回,这正是你在发送给语言模型之前所需要的格式。Markdown 剔除了导航栏、脚本和样式噪声,只保留可读内容。这降低了发送给模型的 token 数量,让调用更划算,提取也更准确。传入 format: 'markdown',API 就会返回干净的文本而非原始 HTML。
import os from dotenv import load_dotenv from crawlbase import CrawlingAPI load_dotenv() api = CrawlingAPI({"token": os.environ["CRAWLBASE_JS_TOKEN"]}) url = "https://www.amazon.com/dp/B0CHX1W1XY" def fetch_markdown(target_url): options = {"format": "markdown", "ajax_wait": "true", "page_wait": 3000} response = api.get(target_url, options) return response["body"].decode("utf-8") page_markdown = fetch_markdown(url) print(page_markdown[:500])
两个等待选项对 Amazon 这样的客户端渲染目标至关重要。ajax_wait 告知 API 等待异步内容加载完成,page_wait 在页面加载后再等待固定毫秒数,确保延迟渲染的价格元素在捕获前出现。三秒是一个合理的起点;如果价格没有返回,适当增加这个值。运行脚本后,输出中应能看到真实的商品标记,而非空壳,这表明在编写任何一行提取逻辑之前,渲染已成功工作。
AI 模型能读取页面,但无法抓取页面。Crawling API 通过一次调用填补这一空白:传入 JS token,它在真实浏览器中渲染 Amazon 页面,在服务器端轮换住宅 IP,并返回整洁的 HTML 或适合 LLM 使用的 Markdown,省去你自己运行无头浏览器集群和代理池的麻烦。先在免费套餐上指向一个公开商品页面试试。
第二步:将内容发送给模型并要求返回 JSON
拿到整洁的 Markdown 后,在提示词中描述你需要的字段,让模型完成提取。实现可靠流水线的关键在于强制 JSON 输出。OpenAI 客户端支持 JSON 响应格式,设置后模型返回可解析的 JSON,而不是包裹在代码围栏中的散文。仅此一个设置就消除了大多数人对 LLM 提取脆弱性的抱怨。
from openai import OpenAI client = OpenAI(api_key=os.environ["OPENAI_API_KEY"]) def extract_fields(content): prompt = f"""You are a data extraction tool. From the Amazon product page content below, extract the product title, current price, list price, currency, rating, review count, and availability. Return only JSON with keys: title, price, list_price, currency, rating, reviews, availability. Use null for any field not present. CONTENT: {content} """ response = client.chat.completions.create( model="gpt-4o-mini", messages=[{"role": "user", "content": prompt}], response_format={"type": "json_object"}, ) return response.choices[0].message.content raw_json = extract_fields(page_markdown) print(raw_json)
这个提示词有几个设计要点。它说明了角色("data extraction tool"),让模型保持简洁;它列出了你需要的确切字段,使 schema 在每次运行中保持稳定;它还告知模型对缺失字段使用 null,这样一个没有定价的商品就不会破坏输出。传入 Markdown 而非原始 HTML,意味着模型将注意力集中在内容上,而不是样板代码。如果你需要更丰富的 schema,列出更多字段并描述模糊的字段;模型无需额外设置即可处理嵌套对象和数组。
第三步:解析并保存结构化结果
由于你要求了 JSON 响应格式,响应文本已经是有效的 JSON。将其解析为 Python 字典并写入磁盘。用 try/except 包裹解析过程,这样偶发的格式错误响应会记录原始文本而不是中断运行。
import json def save_json(raw, path="amazon_price.json"): try: data = json.loads(raw) except json.JSONDecodeError: print("Model did not return valid JSON:") print(raw) return with open(path, "w") as f: json.dump(data, f, indent=2) print(f"Saved {path}") save_json(raw_json)
完整脚本
以下是所有内容整合到一个可运行文件中的完整版本。在 .env 中填入你的两个凭据,将 URL 改为你关心的商品,并根据需要调整提示词中的字段。
import os import json from dotenv import load_dotenv from crawlbase import CrawlingAPI from openai import OpenAI load_dotenv() api = CrawlingAPI({"token": os.environ["CRAWLBASE_JS_TOKEN"]}) client = OpenAI(api_key=os.environ["OPENAI_API_KEY"]) url = "https://www.amazon.com/dp/B0CHX1W1XY" def fetch_markdown(target_url): options = {"format": "markdown", "ajax_wait": "true", "page_wait": 3000} response = api.get(target_url, options) return response["body"].decode("utf-8") def extract_fields(content): prompt = f"""You are a data extraction tool. From the Amazon product page content below, extract the product title, current price, list price, currency, rating, review count, and availability. Return only JSON with keys: title, price, list_price, currency, rating, reviews, availability. Use null for any field not present. CONTENT: {content} """ response = client.chat.completions.create( model="gpt-4o-mini", messages=[{"role": "user", "content": prompt}], response_format={"type": "json_object"}, ) return response.choices[0].message.content def main(): markdown = fetch_markdown(url) raw = extract_fields(markdown) try: data = json.loads(raw) except json.JSONDecodeError: print("Model did not return valid JSON:", raw) return with open("amazon_price.json", "w") as f: json.dump(data, f, indent=2) print(json.dumps(data, indent=2)) if __name__ == "__main__": main()
输出示例
运行 python amazon_scraper.py,你将获得整洁的结构化数据,写入 amazon_price.json 并同步输出到控制台。
{ "title": "Echo Dot (5th Gen) Smart speaker with Alexa", "price": "$34.99", "list_price": "$49.99", "currency": "USD", "rating": "4.7", "reviews": "128,540", "availability": "In Stock" }
注意你没有编写的内容:没有 CSS 选择器,没有 XPath,没有将促销价与定价分离的逐字段解析逻辑。你描述了字段,模型找到了它们。将同一个脚本指向另一个商品,甚至是搜索结果页面,它无需改动代码即可适应,这正是AI 数据提取方式相对手工调试选择器的真正优势。若想在不同模型上使用同样的模式,参见如何借助 Gemini AI 进行网络抓取。
扩展到多个商品
一个页面只是演示;真实的价格监控任务需要对一批商品运行。形式不变:循环遍历 URL,通过 Crawling API 获取每个页面,用模型提取,并汇总行数据。扩展时有两点需要注意。模型按 token 计费,因此发送 Markdown 而非完整 HTML 可降低每次调用的成本;Crawling API 自身有吞吐量管理,你不必自己维护代理或浏览器实例。
urls = [ "https://www.amazon.com/dp/B0CHX1W1XY", "https://www.amazon.com/dp/B09B8V1LZ3", ] results = [] for u in urls: markdown = fetch_markdown(u) raw = extract_fields(markdown) try: row = json.loads(raw) row["url"] = u results.append(row) except json.JSONDecodeError: print(f"Skipped {u}: invalid JSON") with open("prices.json", "w") as f: json.dump(results, f, indent=2)
如果你专门针对 Amazon 进行反复抓取,值得将此方案与 Crawling API 进行比较,后者针对包括 Amazon 在内的受支持网站直接返回预解析的 JSON,无需 LLM,速度更快,成本也更低。本指南中的 AI 方案是应对奇特布局、一次性商品,或专用解析器无法暴露的字段时的灵活后备方案。关于为何 Markdown 是模型的理想输入格式,参见适用于网络抓取的 LLM 就绪 Markdown。
上线前需了解的局限性
AI 加 Crawlbase 的流水线很灵活,但并非万能。请牢记以下几点。
token 成本会积累。模型按发送和接收的 token 计费。发送完整 HTML 而非 Markdown 可能让账单成倍增长却毫无收益,因此务必精简输入。对于非常大的页面,在模型调用前只提取相关部分。
它比基于规则的解析慢。LLM 的往返时间比 BeautifulSoup 或 Cheerio 选择器要长。对于高频、低延迟的任务,如按秒监控价格,专用解析器或 Scraper API 更胜一筹。AI 方案在布局多变或频繁改动时才真正发光。
模型可能出错。Amazon 页面内容密集且重复,模型偶尔可能抓取到相关商品的价格,或将促销价与定价混淆。强制 JSON 输出并明确字段名称能大幅减少这种情况,但对于任何关键任务,在信任结果前请将解析后的字典与预期 schema 进行验证。
对于在大规模下保持畅通,Crawling API 为你处理 IP 轮换和渲染。如果你更希望通过轮换池路由自己的流量,Smart AI Proxy 以直连代理端点的形式提供相同的住宅 IP 轮换。无论哪种方式,更广泛的操作手册都在如何在不被封锁的情况下抓取网站中,更广泛的电商背景见电商网络抓取。
核心要点
- 分工合作。Crawlbase 负责抓取和渲染 Amazon 页面;模型负责提取价格及相关字段。两个工具各司其职,这种分离正是流水线可靠运行的根本。
-
使用 JS token 和 Markdown 格式。JS token 渲染 Amazon 的客户端价格;
format: 'markdown'返回简洁、低 token 的内容,是模型的理想输入。 - 强制 JSON 输出。将响应格式设为 JSON 对象并指定确切字段名,确保每次运行的结果都可解析。
- 无需选择器。用普通英语描述字段,同一个脚本即可跨商品布局适配,无需重写提取代码。
- 坚守公开数据。遵守 Amazon 的服务条款和 robots.txt;不涉及账户、订单数据、绕过身份验证,速度优先时使用 Scraper API。
常见问题
AI 模型能独立抓取 Amazon 价格吗?
抓取部分不行。语言模型能读取并结构化你提供的内容,但它没有 HTTP 客户端、浏览器或代理池,无法打开 Amazon URL 或绕过反爬虫防护。你需要将它与 Crawling API 这样的抓取层配对,后者渲染页面并返回整洁的 Markdown;模型再从这些内容中提取价格和其他字段。
为什么要在将 Amazon 页面发送给模型之前将其转为 Markdown?
Markdown 剔除了导航栏、脚本和样式噪声,只保留可读内容。这降低了发送给模型的 token 数量,既节省成本,又提高了准确性,因为模型将注意力集中在实际商品详情上,而不是样板代码。Crawling API 可以通过 format: 'markdown' 直接返回 Markdown,无需额外的转换步骤。
Amazon 需要使用普通 token 还是 JS token?
使用 JS token。Amazon 在客户端渲染其价格,普通 token 返回的是空壳,模型无从提取。JS token 先在真实浏览器中渲染页面,确保内容到达模型时价格和库存信息已存在。
Amazon 应该用 Scraper API 吗?
通常是的。Crawling API 无需 LLM 即可为 Amazon 返回预解析的 JSON,对于日常价格监控而言速度更快、成本更低。本指南中的 AI 方案是应对非常规布局、一次性商品,或解析器未暴露的字段时的灵活后备。许多团队将 Scraper API 用于大批量任务,将 AI 流水线用于边缘情况。
从 Amazon 抓取价格合法吗?
这取决于 Amazon 的服务条款、你的司法管辖区和你的目的,其条款限制自动化访问。严格限定在公开商品数据范围内,如价格、标题和评分,遵守 robots.txt 和频率预期,不触碰账户、订单数据、支付流程或身份验证。商业复用请获取许可或签订官方数据协议,而不是依赖爬虫。
抓取 Amazon 价格时如何避免被封锁?
降低每个 IP 的请求频率,变换抓取的商品而不是反复攻击同一 URL,并通过轮换住宅 IP 路由流量,以免单个地址触发频率限制。Crawling API 为你管理轮换和可信 IP 池;如果你自己搭建栈,这部分是值得投入的。监控状态码,一旦开始遇到挑战就退出。
大规模爬取任何站点,无需与基础设施对抗。
Crawlbase 负责处理代理、指纹和 CAPTCHA,让你的团队专注于交付数据流水线,而非维护爬取管道。1,000 次请求免费,无需信用卡。
