返回博客

2026年如何用 Python 抓取 Amazon ASIN:分步指南

-
How to Efficiently Use an Amazon ASIN Scraper for Product Research
目录
-

抓取 Amazon 产品信息能带来有价值的数据洞察,从价格追踪到市场调研皆可实现。换句话说,如果能有效地从 Amazon 抓取数据,就能构建出丰富的数据集用于分析。而 Amazon 产品目录的核心,正是 ASIN 编码:每件商品独有的标识符。

在这篇分步指南中,我们将展示如何使用 Python 抓取 Amazon ASIN 编号及相关数据。您将了解什么是 ASIN、如何查找它,以及如何构建一个能绕过 Amazon 防护机制的 ASIN 抓取工具。

读完本文后,您将能够从 Amazon 搜索结果中提取 ASIN,并为您的项目收集 Amazon 的 ASIN 信息,同时避开以编程方式抓取 Amazon ASIN 编码时的常见陷阱。

什么是 Amazon ASIN?如何查找它?

ASIN 全称为 Amazon Standard Identification Number(亚马逊标准识别码),本质上是 Amazon 为其商城中每件商品分配的唯一编码。ASIN 是一个由10个字符组成的字母数字编码(可以理解为一个10位的 ASIN 编号),用作商品的标识符。

例如,一件商品的 ASIN 编码可能是 B08Z5NYG12。这个 ASIN 编号就是 Amazon 为该商品分配的编码。在 Amazon 的整个目录中,每件商品的 ASIN 都是唯一的(图书除外,图书使用 ISBN 作为 ASIN)。

您可以通过几种方式找到商品的 ASIN。最简单的方法是查看商品页面的 URL。打开一个 Amazon 商品页面时,该 URL 通常会包含 ASIN 编码。例如,在 URL https://www.amazon.com/dp/B08Z5NYG12 中,/dp/ 后面的那串字符(此处为 B08Z5NYG12)就是该商品的 ASIN。

您也可以向下滚动页面,找到“Product details”(产品详情)部分,Amazon 通常会在那里连同其他信息一起列出商品的 ASIN。

另一种方法(在浏览 Amazon 搜索结果时很实用)是查看页面的 HTML 源码。在 Amazon 的搜索结果页面中,每条商品列表都包裹在一个包含 ASIN 的元素里。具体来说,这些列表元素带有一个 data-asin 属性,其中包含商品的 ASIN 编码。

这意味着您通常可以直接从搜索结果的 HTML 中收集 ASIN,这正是我们在抓取时要做的事情。

为什么 ASIN 编码很有用?对卖家和分析人员来说,ASIN 至关重要。它能让您在 Amazon 的整个目录中追踪和比较商品。您可以用 ASIN 编码来监控库存和定价(例如通过 ASIN 查看某件商品随时间变化的价格)、分析 Amazon 数据以把握市场趋势,或确保您在分析中引用的是准确无误的商品。

在转售工具和联盟营销中,拥有 ASIN 有助于您通过 Amazon 的 API 或抓取到的页面获取商品详情或评价。本质上,ASIN 数据是解锁海量商品信息的钥匙。

用 Python 抓取 ASIN:分步教程

了解了 ASIN 是什么之后,接下来我们来看如何用 Python 抓取 Amazon 的 ASIN 数据。我们将讲解环境搭建、理解 Amazon 的页面结构,以及编写脚本来收集 ASIN 编码和商品信息。本节内容面向熟悉基础数据抓取和网络爬取技术的中级 Python 用户。

前置准备

在开始编写 Amazon 抓取脚本之前,请确保您已准备好合适的 Python 环境。您需要安装 Python 3,并配备一些常用的库。

在本教程中,我们将使用 requests 库来获取页面,并使用 BeautifulSoup(来自 bs4)或 lxml 来解析 HTML 内容。可以通过 pip 安装这些库:

pip install requests beautifulsoup4 lxml

我们还打算使用 Python 内置的 json 模块来输出数据。具备 HTML 基础知识以及使用浏览器开发者工具查看元素的能力会很有帮助。最后,对于涉及大量抓取的较大项目,您应该考虑使用代理,并留意 Amazon 的反抓取机制(后文会详细介绍)。

Amazon 商品页面结构

理解 Amazon 页面的结构对抓取至关重要。典型的 Amazon 商品页面以静态 HTML 的形式返回(之后会加载一些动态内容)。

商品标题、价格、ASIN 等关键信息都存在于这段 HTML 中。如前所述,ASIN 是 URL 的一部分,但它同样出现在页面内容中。页面上的“Product details”(产品详情)部分通常会明确列出“ASIN: <code>”,这是确认 ASIN 编号的一种简便方式。

不过,当我们的目标是收集大量 ASIN 时,其实没必要逐一抓取每个商品页面来获取 ASIN。从列表页或搜索页获取 ASIN 效率更高。

Amazon 的搜索结果页面本质上是商品列表。搜索页上的每条商品列表通常带有 data-asin 属性(或类似属性,如 data-csa-c-asin),其中包含 ASIN 编码。通过获取搜索结果页的 HTML,我们可以一次性收集多个 ASIN。

从搜索结果页抓取 ASIN

要批量抓取 Amazon ASIN 编码,搜索结果页是最好的切入点。假设我们想获取“laptop”这个查询的第一页结果的 ASIN,可以使用该查询对应的 Amazon 搜索 URL,例如:

https://www.amazon.com/s?k=laptop

当您在浏览器中打开这个页面时,会看到一系列商品结果。而在底层,该页面的 HTML 中包含了每条商品列表的 ASIN。

使用 Python,我们可以向该 Amazon 搜索 URL 发送一个 HTTP GET 请求。请务必包含有效的 User-Agent 请求头,这样 Amazon 才会返回正常页面(如果请求看起来可疑或缺少合适的 User-Agent 字符串,Amazon 可能会返回验证码或错误)。例如:

import requests
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36",
    "Accept-Language": "en-US,en;q=0.9"
}
url = "https://www.amazon.com/s?k=laptop"
response = requests.get(url, headers=headers)
html_content = response.text

现在,html_content 中保存着“laptop”搜索结果的 HTML。接下来,我们解析这段 HTML,找出页面上所有的 ASIN。我们要查找所有带 data-asin 属性的元素,因为这些元素携带着 ASIN 编码。使用 BeautifulSoup:

from bs4 import BeautifulSoup
soup = BeautifulSoup(html_content, "lxml")
asin_elements = soup.find_all(attrs={"data-asin": True})
asins = [elem["data-asin"] for elem in asin_elements if elem["data-asin"]]
print(asins)

这会打印出页面上找到的 ASIN 列表。我们会过滤掉空字符串(Amazon 有时会在非实际商品的布局容器上使用 data-asin="")。通常,一页搜索结果能获得20个左右或更多的 ASIN。这样我们就在不逐一点击每件商品的情况下,成功从搜索结果的 HTML 中提取出了 ASIN。

有一点需要注意:搜索页通常包含赞助商品或其他非商品元素。上面的方法会抓取所有带 data-asin 属性的内容。如果想更精确,可以将选择器细化为类似这样:

soup.select("div.s-result-item[data-asin]")

这样就只会定位实际的商品结果容器。

抓取商品数据

收集 Amazon ASIN 数据很有用,但我们往往需要的不只是编码本身,还想抓取 Amazon 上每件商品的数据。一旦您有了一份 ASIN 列表(例如上一步得到的结果),就可以用它们来获取每件商品的页面,并提取标题、价格、评分等详情。

要访问商品页面,需在 URL 中使用对应的 ASIN。Amazon 商品页面可以通过包含 ASIN 的 URL 格式访问,例如:

https://www.amazon.com/dp/ASINCODE

将 ASINCODE 替换为实际的编码。例如,如果我们有一个 ASIN B08Z5NYG12,那么商品页面的 URL 就是:

https://www.amazon.com/dp/B08Z5NYG12

我们从前面的列表中取一个 ASIN,并获取它的商品页面:

asin = asins[0]  # first ASIN from our list
product_url = f"https://www.amazon.com/dp/{asin}"
product_resp = requests.get(product_url, headers=headers)
product_html = product_resp.text

此后,product_html 中包含该 ASIN 对应商品详情页的 HTML。现在我们解析这段 HTML,提取出所需的 Amazon 数据。例如,要获取商品标题和价格:

prod_soup = BeautifulSoup(product_html, "lxml")
title_elem = prod_soup.find(id="productTitle")
price_elem = prod_soup.find("span", {"class": "a-price-whole"})
title = title_elem.get_text(strip=True) if title_elem else "N/A"
price = price_elem.get_text(strip=True) if price_elem else "N/A"
print(title, price)

这里,我们查找 id 为 "productTitle" 的元素(它保存着 Amazon 页面上的商品名称),以及 class 为 "a-price-whole" 的元素(它是价格显示的一部分)。get_text(strip=True) 调用会返回去除多余空白的文本内容。如果找不到这些元素(可能商品已下架,或页面结构有所不同),我们就默认使用“N/A”。

最后,我们来存储收集到的数据。可以在 Python 中将所有内容整合成一份字典列表,然后写入一个 JSON 文件:

products_data = []
for asin in asins:
    product_url = f"https://www.amazon.com/dp/{asin}"
    prod_resp = requests.get(product_url, headers=headers)
    prod_soup = BeautifulSoup(prod_resp.text, "lxml")
    title_elem = prod_soup.find(id="productTitle")
    price_elem = prod_soup.find("span", {"class": "a-price-whole"})
    title = title_elem.get_text(strip=True) if title_elem else "N/A"
    price = price_elem.get_text(strip=True) if price_elem else "N/A"
    products_data.append({
        "asin": asin,
        "title": title,
        "price": price
    })

# Save results to a JSON file
with open("amazon_products.json", "w") as f:
    json.dump(products_data, f, indent=4)

我们的 Amazon 抓取脚本会遍历每个 ASIN,抓取对应的商品页面,并将数据字典追加到列表中。然后我们将这个列表写入 amazon_products.json。该文件中的每一条记录都会包含对应商品的 ASIN 及提取出的详情。

使用代理

持续抓取 Amazon 而不被封锁并不容易。如果您试图从同一个 IP 地址在短时间内抓取过多页面或商品列表,Amazon 很可能会检测到这种异常流量,并开始封锁请求。作为防护手段,它们可能会向您返回 CAPTCHA 验证或 HTTP 503 错误。如果您想深入了解如何应对这些挑战,可以参考我们关于绕过 Amazon CAPTCHA的指南。到了这一步,使用代理就变得至关重要。

代理可以让您的请求看起来像是来自不同的 IP 地址。通过在一个 IP 池中轮换,Amazon 将更难识别出单一的流量来源。对于任何真正意义上的大规模 ASIN 网络爬取,代理都是必不可少的。

这里有几种代理方案可供选择:

  • 住宅代理通过真实用户设备(住宅 IP)转发您的请求。由于看起来像普通客户流量,它们对 Amazon 来说通常更可靠,但速度可能更慢、成本也更高。
  • 数据中心代理速度快、价格低,但许多数据中心 IP 段已被 Amazon 识别,更容易被封锁或触发验证。
  • ISP 代理是由互联网服务提供商提供、用于抓取用途的 IP 地址,兼具住宅代理和数据中心代理的部分优点。

在 Python 代码中,我们可以通过向 requests.get 传入一个 proxies 字典来指定代理。例如:

proxies = {
    "http": "http://USERNAME:PASSWORD@proxy-address:port",
    "https": "http://USERNAME:PASSWORD@proxy-address:port"
}
response = requests.get(url, headers=headers, proxies=proxies)

您需要根据所使用的代理服务填写USERNAME、PASSWORD、代理地址和端口。像MarsProxies这样的服务提供可自动处理轮换的端点,让每个请求都能通过不同的 IP 地址发出。

完整代码

综合以上内容,下面是完整的 Python 脚本,该 Amazon 爬虫会搜索关键词、收集 ASIN 编号,然后结合请求头和可选的代理抓取每个产品的标题和价格:

import requests
from bs4 import BeautifulSoup
import json
import time
import random

# Setup headers and (optional) proxies
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/110.0.0.0 Safari/537.36",
    "Accept-Language": "en-US,en;q=0.9"
}
proxies = {
    # "http": "http://USERNAME:PASSWORD@proxy.server:port",
    # "https": "http://USERNAME:PASSWORD@proxy.server:port"
}

query = "laptop"
search_url = f"https://www.amazon.com/s?k={query}"
res = requests.get(search_url, headers=headers, proxies=proxies)
soup = BeautifulSoup(res.text, "lxml")

# Extract ASINs from search results
asins = []
for item in soup.select("div.s-result-item[data-asin]"):
    asin = item.get("data-asin")
    if asin:
        asins.append(asin)

print(f"Found {len(asins)} ASINs for search '{query}'")
products_data = []

# Fetch each product page
for asin in asins:
    product_url = f"https://www.amazon.com/dp/{asin}"
    prod_res = requests.get(product_url, headers=headers, proxies=proxies)
    prod_soup = BeautifulSoup(prod_res.text, "lxml")
    title_elem = prod_soup.find(id="productTitle")
    price_elem = prod_soup.find("span", {"class": "a-price-whole"})
    title = title_elem.get_text(strip=True) if title_elem else "N/A"
    price = price_elem.get_text(strip=True) if price_elem else "N/A"
    products_data.append({
        "asin": asin,
        "title": title,
        "price": price
    })
    time.sleep(random.uniform(1.0, 3.0))  # polite delay

# Save data to JSON
with open("products_data.json", "w") as f:
    json.dump(products_data, f, indent=4)

该脚本会在 Amazon 上执行搜索、从结果中提取 ASIN 编号,然后抓取每个产品页面的标题和价格,并打印找到的 ASIN 编号数量,再将所有收集到的数据保存到products_data.json中。如果您有代理信息,请记得填入,并可根据需要调整延迟和字段。

大规模 ASIN 数据抓取的进阶方法

当需要处理成百上千个产品时,基础的抓取方式可能已经不够用。大规模 ASIN 数据抓取会带来一系列新的挑战,需要借助额外的工具或策略:

  • CAPTCHA 绕过策略

在高请求量下,Amazon 很可能会向您的爬虫弹出 CAPTCHA 验证。例如,页面可能突然要求您“输入字符”以证明自己不是机器人。此时可以借助第三方 CAPTCHA 识别服务自动完成验证(这类服务通常提供 API:您发送图片,它们返回识别出的文字)。

  • 无头浏览器

当 Amazon 的反爬机制让简单脚本失效时,使用 Selenium(搭配 Chrome 或 Firefox)或 Puppeteer 这类无头浏览器会有所帮助。无头浏览器实际上运行着真实的浏览器引擎,只是没有可见窗口,能够执行 JavaScript 并遵循真实用户的浏览路径(包括加载图片、等待页面渲染等)。

  • 使用 asyncio 或多线程实现并行请求

如果需要处理大量 ASIN 编号,逐个处理会非常慢。Python 的 asyncio 或多线程可以帮助并行发送多个请求。像 aiohttp 结合 asyncio 这样的库可以让您异步地同时抓取多个页面。

  • 数据的存储与管理

当通过 ASIN 编号收集到大量产品数据时,建议使用数据库或结构化存储方式。例如,可以使用 SQLite 或 MySQL 数据库,以 ASIN 作为键来存储产品数据。

常见问题排查

即使有周全的方案,在抓取 Amazon 时仍可能遇到一些常见问题:

空白页面或登录页面

Amazon 可能不会返回预期内容,而是返回空白页面,或将您重定向到登录/验证页面,这通常意味着您的请求已被标记。排查时,请检查响应内容是否确实包含登录页面的 HTML,或是否出现“启用 JavaScript”“允许 Cookie”之类的提示。

HTTP 503 错误(服务不可用)

出现 503 状态码并伴随 Amazon 错误页面,说明请求已被拦截。Amazon 会用 503 响应来限流或封锁爬虫。遇到 503 时,应采用退避策略:暂停抓取几分钟,再以更低的速度或更换新 IP 继续。这是一个明确的信号,提示您需要降低请求频率。

CAPTCHA 页面

如果突然出现要求输入 CAPTCHA 的页面(即使 HTTP 状态码仍是 200 OK),说明您的爬虫已被拦截验证。这类页面的 HTML 通常体积小得多,会包含“captcha”字样,或带有路径中含 /captcha/ 的图片。此时您需要解决验证(通过代码处理可能并不简单),或者放弃当前代理/IP 并更换新的,同时可能还需要降低请求速度。

数据不完整或元素缺失

如果解析器找不到某些元素(例如价格或标题),可能是页面格式略有不同(比如促销商品的价格可能位于不同的 span 类中,或者缺货商品根本没有价格)。请始终采用防御性编码,检查备用选择器或条件(例如先查找 “a-price-whole”,如果找不到,再尝试某些促销页面中可能使用的 “a-size-medium a-color-price”)。

封禁提示或频繁重定向

Amazon 可能会临时封禁某个 IP,并持续显示“Sorry, we just need to make sure you're not a robot”的提示。即使您放慢请求速度,这条提示往往依然存在,因为该 IP 的信誉已经受到影响。解决方法是更换全新的代理或 IP。

抓取 Amazon 面临的挑战

由于 Amazon 拥有成熟的反爬机制,抓取 Amazon 比抓取许多其他网站更具挑战性。以下是一些主要挑战:

  • IP 封锁

如果某个 IP 地址发出过多请求或访问页面过快,Amazon 会察觉到异常,通常会对该地址实施临时或长期封禁。被封禁的 IP 之后只会看到 Amazon 的 CAPTCHA 页面或错误信息。

  • CAPTCHA 验证挑战

Amazon 会通过 CAPTCHA 提示来验证可疑流量,可能是图片验证码,也可能是其他类型的验证题。在抓取过程中遇到 CAPTCHA,是您的爬虫已被识别为机器人活动的明确信号。正如前文所述,处理 CAPTCHA 并不容易,往往需要借助外部服务或由真人完成。

  • 速率限制

Amazon 可能不会直接封禁您,但如果请求过多,会对响应进行限速,您可能会遇到响应变慢或只返回部分数据的情况。

此外还存在“软封锁”的情况:当 Amazon 怀疑是爬虫时,会返回过时或简化版的页面来误导您。因此,通过添加延迟、遵守速率限制、避免抓取过快至关重要。

  • JavaScript 与动态内容

虽然 Amazon 的大部分内容由服务器端渲染,但部分功能仍会用到动态内容(例如切换产品选项时更新价格,或滚动页面时加载更多评论)。

如果所需数据是在首次页面加载之后通过 JavaScript 加载的,基于简单 requests 的爬虫将无法获取到它。此时可以尝试在网络请求中找到对应的 API 端点,模拟这些 XHR(Ajax)请求,或者使用无头浏览器让页面完全渲染后再抓取。

抓取 Amazon 的 ASIN 编号合法吗?

网络爬取的合法性本身是一个灰色地带,但就 ASIN 编号而言,可以这样理解:

公开数据与私有数据

ASIN 编号以及 Amazon 上的基本产品信息是公开的:只要无需登录就能在浏览器中看到,就属于公开数据。在许多司法管辖区,抓取此类公开数据(如产品标题、价格、ASIN 编号等)通常是合法的。

真正越界的行为是获取非公开数据(例如他人的个人账户信息)或绕过登录验证。只要收集的是任何普通用户都能在网站上看到的数据,法律风险就相对较低。

Amazon 的服务条款

虽然抓取公开数据并不违法,但可能违反 Amazon 的网站条款。Amazon 的使用条款明确禁止在未经许可的情况下使用自动化工具抓取其网站数据。

如果违反这些条款,Amazon 可能会采取相应措施,例如封禁您的账户或 IP。通常情况下,企业会通过技术手段(封锁,极端情况下发送法律警告函)来执行条款,而非直接提起诉讼,尤其是在抓取行为用于个人或学术用途时。

值得一提的是,美国一起知名判例(hiQ Labs 诉 LinkedIn 案)的判决倾向于支持抓取公开数据。不过,Amazon 作为一个私营平台,仍有权根据自身意愿切断访问权限。

保持合规

如果想避免麻烦,可以考虑使用 Amazon 官方 API(如 Product Advertising API)合法获取产品数据。这类 API 虽然有使用政策和限制,但能确保您的合规性。如果确实需要抓取,请遵循以下原则:

  • 不要尝试抓取敏感信息。
  • 不要向 Amazon 发送不合理的大量流量(这可能被视为拒绝服务攻击)。
  • 使用数据时应尊重用户隐私和 Amazon 的权益(例如,抓取并重新发布 Amazon 的全部内容很可能会让您陷入麻烦)。

总的来说,抓取 Amazon ASIN 编号本身并不违法,许多企业和研究人员都在这样做。但请注意,这确实违反了 Amazon 的服务条款,因此 Amazon 有权通过技术手段对您进行封锁。只要坚持抓取公开数据并合理使用,法律风险就能保持在较低水平。

ASIN 和 SKU 是一回事吗?

不是。ASIN 是 Amazon 为其商品目录中的产品分配的标识符(10 位字符代码),而 SKU(库存单位)通常是卖家或零售商用于追踪自身库存的内部编码。换句话说,同一产品在 Amazon 平台上的 ASIN 是统一的,而 SKU 往往因卖家或仓储系统不同而各不相同。

Amazon 上的每个产品都有 ASIN 吗?

是的,Amazon 上的每个产品列表都有对应的 ASIN。每当有新产品加入 Amazon 的商品目录,系统就会为其生成一个 ASIN。如果多个卖家销售同一件商品,他们都会使用同一个 ASIN。对于图书而言,ASIN 通常与其 ISBN-10 或 ISBN-13 相同,对应图书的标准编号。

不使用代理抓取 Amazon 有哪些风险?

不使用代理进行 Amazon ASIN 数据抓取,意味着所有请求都来自同一个 IP 地址。如果这个 IP 短时间内发出大量请求,这并不符合普通购物者的行为模式,Amazon 的系统会很快察觉到异常。

可能面临以下风险:您的 IP 被暂时或永久禁止访问 Amazon、频繁遇到 503 错误或 CAPTCHA 验证、最终难以获取所需数据。本质上,如果不使用代理(及相应的应对措施),爬虫在被 Amazon 彻底封锁之前的生命周期会非常短。

了解更多
-

相关文章