用 Python 抓取 Target.com:3 种真正有效的方法

最后更新于 April 16, 2026

Target.com 看起来像是那种“很容易抓”的网站——直到你真的上手。你如果曾经用 Requests 和 BeautifulSoup 很快写过一段 Python 脚本,拿去抓 Target 商品页,结果价格字段返回 None,那你一点都不孤单。

我测试过主流零售网站的各种抓取方案,可以很负责地说:Target 一直都是最难啃的站点之一。它每月有 ,商品数据也很丰富——价格、评分、库存、评论一应俱全——但 Target 基于 React 的前端渲染,再加上 Akamai 的反爬检测,意味着最朴素的做法几乎会立刻翻车。不过,好消息是:确实有 3 种 Python 方法能用。我会一一讲清楚,解释为什么第一次尝试总会失败,并在最后给你一个不用写代码的捷径,适合不想被 Python 折腾的人。

为什么你第一次抓 Target.com 时总是返回 None

先别急着看解决方案,先看问题本身。下面这段代码,就是大多数新手最容易写出来的版本:

1import requests
2from bs4 import BeautifulSoup
3> This paragraph contains content that cannot be parsed and has been skipped.
4price = soup.select_one('[data-test="current-price"]')
5print(price)  # None

输出是什么?None。每次都是。

这不是你的代码有 bug,而是 requests.get() 从 Target 拿到的 HTML 基本只是个空壳——一个 React 的“骨架页面”,它在告诉你:“先加载这段 JavaScript,真正内容会由它渲染出来。”商品价格、评分、评论和库存信息,都会在初始页面加载后由 JavaScript 动态注入。由于 Python 的 Requests 库不会执行 JavaScript,这些元素根本不会出现在返回结果里。

不少开发者都在论坛里遇到过这个坎。一个 说得很直白:“元素显示为 None,是因为它是通过 JavaScript 渲染的,而 requests 无法获取由 JavaScript 渲染后的 HTML。” 也印证了这一点:“当你向 Target URL 发送 HTTP 请求时,返回的 HTML 里几乎没有什么有价值的数据。”

即便你解决了 JavaScript 渲染的问题,还有第二层阻碍:Target 的 Akamai 反爬系统会先识别你的 TLS 握手指纹,甚至在任何 HTML 内容交换之前,就已经把 Python 的 requests 库标记出来了。这个问题我们后面马上展开。

为什么 Target.com 对 Python 来说这么难抓

Target 不只是“一个用了 JavaScript 的网站”。它是一套分层防御系统——而你只有理解每一层,才知道该选哪种抓取方式。

JavaScript 渲染的商品数据

Target.com 基于 React 构建。当你在真实浏览器里打开商品页或搜索页时,流程大致是这样的:

  1. 服务器先返回一个极简的 HTML 外壳
  2. JavaScript 包被加载并执行
  3. 前端调用 Target 内部的 Redsky API
  4. 商品数据(价格、评分、图片、库存)渲染进 DOM

如果你跳过第 2–4 步——而 requests.get() 恰恰就是这样——拿到的就只是空页面。,静态 HTTP 请求在 Target 上大约只能抓到可用数据的 。剩下的 70% 需要 JavaScript 执行,或者直接访问 API。

搜索结果页更麻烦。初始 HTML 里通常只显示少量商品,剩下的要等你滚动后才加载。

Target 的反爬防线:不只是“用代理”这么简单

很多抓取教程一提到反爬,就轻飘飘来一句“用代理就行了”。但 Target 的防御机制远没有这么简单。

TLS 指纹识别(最关键的一层)。 在 HTTPS 握手阶段,客户端会发送一个 “Client Hello” 包,里面包含 TLS 版本、密码套件、扩展项和椭圆曲线等信息。这些参数会被哈希成一个 JA3 指纹。Python 的 requests 库会生成一个 ——8d9f7747675e24454cd9b7ed35c58707——反爬数据库一眼就能识别出来。Chrome 会发送 16 个按浏览器逻辑排序、并带有 GREASE 值的密码套件;而 Python 会发送 60 多个,而且顺序完全不像浏览器。拦截往往会在任何 HTTP 内容交换之前发生。

IP 信誉评分。 Akamai 会把 IP 划分到不同信任等级。数据中心 IP 在 里,会被打上“明显负面信任分”,因为它们很可能被机器人使用。住宅 IP 则更容易拿到正面评分。对 Target 来说,数据中心 IP 段通常会被直接标记。

JavaScript 指纹识别。 Akamai 会注入 JavaScript,收集你的 JS 引擎规格、硬件能力、操作系统信息、字体、插件以及行为数据(打字速度、鼠标移动、点击时机)。这些信息会生成 _abck cookie——一种有状态的指纹令牌。没有有效的 _abck,请求就会被拦下。

速率限制。 Target 大概在每个 IP 每分钟 30–60 次请求时就会触发 429 错误。有些用户还会收到 ,但内容其实是 “Pardon Our Interruption” 拦截页——这让自动化识别更棘手。

。而单独看 Akamai 绕过难度,则被

用 Python 抓 Target.com 的 3 种方法(对比版)

网上很少有文章会把这三种可行方案放在一篇里认真比较。下面我直接给你结论:

This paragraph contains content that cannot be parsed and has been skipped.

接下来我们逐个搭建。

方法 1:用 Python Requests 和 BeautifulSoup 抓 Target.com

这个方法抓不到搜索页里由 JavaScript 渲染的价格。不过它速度快、轻量,而且如果你知道该去哪里找,能提取到的内容比你想象中多。

关键在于:Target 会把一部分商品数据嵌在 <script> 标签里,里面包含 __PRELOADED_QUERIES____TGT_DATA__ 变量。这个 JSON 数据块里包括商品名称、描述、特征,有时在单品页里也会带价格。你还可以从搜索结果 HTML 中抓到商品标题和 URL。

第一步:配置 Python 环境

新建项目目录并安装依赖:

1mkdir target-scraper && cd target-scraper
2python -m venv venv
3source venv/bin/activate  # Windows 上用:venv\activate
4pip install requests beautifulsoup4 curl_cffi

这里建议用 curl_cffi 替代标准 requests。它能伪装浏览器的 TLS 指纹,这是绕过 Target 封锁最关键的一步。curl_cffi 的反爬绕过成功率达到 ,而标准 requests 只有 ——提升了 15 倍。

第二步:抓取 Target 搜索结果

Target 的搜索 URL 很简单:https://www.target.com/s?searchTerm={keyword}

1from curl_cffi import requests as cureq
2from bs4 import BeautifulSoup
3import time, random
4> This paragraph contains content that cannot be parsed and has been skipped.
5url = "https://www.target.com/s?searchTerm=bluetooth+headphones"
6resp = cureq.get(url, headers=headers, impersonate="chrome124")
7soup = BeautifulSoup(resp.text, "html.parser")
8> This paragraph contains content that cannot be parsed and has been skipped.
9你会拿到商品名称和 URL。价格?大概率不会出现在这段 HTML 里。这很正常。
10### 第三步:从商品页中提取嵌入的 JSON 数据
11单个商品页会把更丰富的数据嵌在 `__TGT_DATA__` 脚本标签里:
12```python
13import re, json
14product_url = "https://www.target.com/p/some-product/-/A-12345678"
15resp = cureq.get(product_url, headers=headers, impersonate="chrome124")
16soup = BeautifulSoup(resp.text, "html.parser")
17> This paragraph contains content that cannot be parsed and has been skipped.
18`__TGT_DATA__` 里的 JSON 会包含商品名称、描述、特征,很多时候也会带价格。具体层级会变,所以你需要先打印出来,再按实际结构继续往下取。
19### 第四步:处理分页
20Target 搜索结果的分页参数是 `Nao`。第 1 页是 `Nao=0`,第 2 页是 `Nao=24`,第 3 页是 `Nao=48`,以此类推(每次加 24):
21```python
22for page in range(0, 120, 24):  # 前 5 页
23    paginated_url = f"https://www.target.com/s?searchTerm=bluetooth+headphones&Nao={page}"
24    resp = cureq.get(paginated_url, headers=headers, impersonate="chrome124")
25    # 解析并提取……
26    time.sleep(random.uniform(2, 5))  # 友好一点

第五步:保存抓取结果

1import csv
2with open("target_products.csv", "w", newline="", encoding="utf-8") as f:
3    writer = csv.DictWriter(f, fieldnames=["title", "url", "price", "description"])
4    writer.writeheader()
5    for product in products:
6        writer.writerow(product)

你能拿到什么: 商品标题、URL、描述,以及嵌入式元数据。你拿不到什么: 搜索结果页里动态加载的价格和评分。要这些,就得用方法 2 或 3。

方法 2:用 Selenium 或 Playwright 抓 Target.com

无头浏览器可以渲染 JavaScript、加载动态内容,并模拟真实用户行为。这种方法能抓到价格、评分和评论。

至于 Selenium 和 Playwright 选哪个:——到 2026 年分别是 ——而且基准测试显示它快 (20 页 11 秒 vs. 28 秒)。这里我还是以 Selenium 为例,因为它社区更大、教程更多;但如果你是从零开始,Playwright 是更好的新选择。

第一步:安装 Selenium 和 ChromeDriver

1pip install selenium webdriver-manager

webdriver-manager 会自动处理 ChromeDriver 版本匹配,不用再头疼“ChromeDriver 版本不一致”的问题:

1from selenium import webdriver
2from selenium.webdriver.chrome.service import Service
3from selenium.webdriver.chrome.options import Options
4from webdriver_manager.chrome import ChromeDriverManager
5options = Options()
6options.add_argument("--headless=new")
7options.add_argument("--window-size=1920,1080")
8options.add_argument("--disable-blink-features=AutomationControlled")
9options.add_argument("--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36")
10driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()), options=options)

第二步:加载 Target 页面并等待内容渲染

1from selenium.webdriver.common.by import By
2from selenium.webdriver.support.ui import WebDriverWait
3from selenium.webdriver.support import expected_conditions as EC
4driver.get("https://www.target.com/s?searchTerm=bluetooth+headphones")
5# 等待商品卡片渲染完成(显式等待 > time.sleep)
6WebDriverWait(driver, 15).until(
7    EC.presence_of_element_located((By.CSS_SELECTOR, '[data-test="product-title"]'))
8)

显式等待非常重要。time.sleep(10) 在页面加载快的时候会白白浪费时间,在页面加载慢的时候又不够用——两头不讨好。WebDriverWait 会每 500 毫秒轮询一次,直到元素出现或超时。

第三步:滚动页面以加载全部商品

Target 会随着滚动懒加载商品。不滚动的话,你可能只会看到 4–5 个商品,而不是整页内容:

1import time
2last_height = driver.execute_script("return document.body.scrollHeight")
3for _ in range(10):
4    driver.execute_script("window.scrollBy(0, 300);")
5    time.sleep(1.5)
6    new_height = driver.execute_script("return document.body.scrollHeight")
7    if new_height == last_height:
8        break
9    last_height = new_height

:滚动 10 次、每次延迟 1.5 秒,能抓到 8 个以上商品;而不滚动通常只有 4–5 个。每次滚动建议 200–300 像素,这样更像真人操作。

第四步:从渲染后的页面提取商品数据

1products = []
2cards = driver.find_elements(By.CSS_SELECTOR, '[data-test="@web/site-top-of-funnel/ProductCardWrapper"]')
3for card in cards:
4    try:
5        title = card.find_element(By.CSS_SELECTOR, '[data-test="product-title"]').text
6    except:
7        title = "N/A"
8    try:
9        price = card.find_element(By.CSS_SELECTOR, '[data-test="current-price"]').text
10    except:
11        price = "N/A"
12    try:
13        link = card.find_element(By.CSS_SELECTOR, 'a[href*="/p/"]').get_attribute("href")
14    except:
15        link = "N/A"
16> This paragraph contains content that cannot be parsed and has been skipped.
17for p in products:
18    print(f'{p["title"]}{p["price"]}')

Target 关键的 data-test 选择器(2026 年验证):

数据字段选择器
商品卡片data-test="@web/site-top-of-funnel/ProductCardWrapper"
商品标题data-test="product-title"
当前价格data-test="current-price"
评分data-test="rating-value"
评价数量data-test="rating-count"

第五步:抓取商品评论(附加项)

进入单个商品页,向下滚动到评论区域,然后提取评论数据:

1from bs4 import BeautifulSoup
2driver.get("https://www.target.com/p/some-product/-/A-12345678")
3# 向下滚动,加载评论
4for _ in range(5):
5    driver.execute_script("window.scrollBy(0, 500);")
6    time.sleep(2)
7> This paragraph contains content that cannot be parsed and has been skipped.
8评论通过 Bazaarvoice 集成加载,支持分页(最多 51 页)、按最新排序,以及仅显示带图片的筛选。[ScrapeOps 的基准测试](https://scrapeops.io/)显示,使用 Selenium 抓取时,单条数据大约需要 5.1 秒。
9别忘了用完后关闭浏览器:
10```python
11driver.quit()

方法 3:通过 Redsky API 抓 Target.com

Target 前端会从内部 API redsky.target.com 拉取所有数据。你可以直接用 Python 调用它——不用解析 HTML,不用浏览器,也不用 JavaScript 渲染。返回的是干净的 JSON,包含 40 多个字段,覆盖价格、评分、评论、图片、库存、履约方式、规格和变体。对于批量商品数据来说,这毫无疑问是最快、最稳的方法。

第一步:用 Chrome DevTools 找到 Redsky API

很多教程会直接跳过这一步。下面是你自己定位 API 的方法:

  1. 在 Chrome 中打开任意 Target 商品页
  2. 打开 DevTools(F12)→ Network 标签页
  3. 过滤 Fetch/XHR
  4. 刷新页面
  5. 找到发往 redsky.target.comredsky.a]target.com 的请求
  6. 点开其中一个,查看 Request URLHeaders

你会看到类似这样的地址:

1https://redsky.target.com/redsky_aggregations/v1/web/pdp_fulfillment_v1?key=9f36aeafbe60771e321a7cc95a78140772ab3e96&tcin=12345678&store_id=2148&zip=55401

关键参数:

  • key —— API key(固定,不会频繁轮换;不同端点使用不同 key)
  • tcin —— Target.com Item Number,也就是 8 位商品 ID
  • store_id —— Target 门店编号
  • zip —— 用于履约数据的邮编

API key 可以直接从请求 URL 中提取,它本身就是查询参数的一部分。

第二步:直接用 Python 请求 Redsky API

1from curl_cffi import requests as cureq
2import json
3API_KEY = "9f36aeafbe60771e321a7cc95a78140772ab3e96"  # 从 DevTools 提取
4TCIN = "12345678"
5url = f"https://redsky.target.com/redsky_aggregations/v1/web/pdp_fulfillment_v1?key={API_KEY}&tcin={TCIN}&store_id=2148&zip=55401"
6> This paragraph contains content that cannot be parsed and has been skipped.
7resp = cureq.get(url, headers=headers, impersonate="chrome124")
8data = resp.json()
9# 从 JSON 中提取商品信息
10product = data.get("data", {}).get("product", {})
11title = product.get("item", {}).get("product_description", {}).get("title", "N/A")
12price = product.get("price", {}).get("formatted_current_price", "N/A")
13rating = product.get("ratings_and_reviews", {}).get("statistics", {}).get("rating", {}).get("average", "N/A")
14print(f"{title}{price} — Rating: {rating}")

不需要解析 HTML。返回结果结构清楚、干净、速度快。

第三步:通过 API 抓商品搜索结果

product_summary_with_fulfillment_v1 这个端点可以一次接受多个 TCIN:

1tcins = ["12345678", "23456789", "34567890"]
2tcin_str = ",".join(tcins)
3search_url = f"https://redsky.target.com/redsky_aggregations/v1/web/product_summary_with_fulfillment_v1?key={API_KEY}&tcins={tcin_str}&store_id=2148&zip=55401"
4resp = cureq.get(search_url, headers=headers, impersonate="chrome124")
5results = resp.json()
6for item in results.get("data", {}).get("product_summaries", []):
7    title = item.get("title", "N/A")
8    price = item.get("price", {}).get("formatted_current_price", "N/A")
9    print(f"{title}{price}")

要获取 TCIN,你可以从搜索结果 HTML 中提取(商品 URL 里会出现 /A-XXXXXXXX),也可以从嵌入的 __TGT_DATA__ JSON 里直接拿。

第四步:用并发请求提升规模

1from concurrent.futures import ThreadPoolExecutor
2import time, random
3def fetch_product(tcin):
4    url = f"https://redsky.target.com/redsky_aggregations/v1/web/pdp_fulfillment_v1?key={API_KEY}&tcin={tcin}&store_id=2148&zip=55401"
5    time.sleep(random.uniform(2, 5))
6    resp = cureq.get(url, headers=headers, impersonate="chrome124")
7    return resp.json()
8tcin_list = ["12345678", "23456789", "34567890", "45678901"]
9with ThreadPoolExecutor(max_workers=3) as executor:
10    results = list(executor.map(fetch_product, tcin_list))

并发别开太猛——建议 3–5 个线程,并加 2–5 秒随机延迟。Target 的限速大致在 左右。

关于 Redsky API 的几个重要提醒

在你把它做成生产级管道之前,有几件事要先知道:

  • API key 是固定的,但与端点相关。 不同的 Redsky 端点会用不同的 key。它们不常轮换,但 Target 随时可能修改。
  • 这是一个未公开文档的内部 API。 Target 工程团队已经 ,这会降低法律风险,但它并不是带 SLA 的正式公开 API。
  • 商品变体(颜色、尺码)通常各自对应唯一 TCIN。 你需要分别查询每个变体。
  • 少了 Sec-Fetch-* 头会直接被拦。 这是常见坑——一定要带上 Sec-Fetch-SiteSec-Fetch-ModeSec-Fetch-Dest

如何大规模抓取 Target.com 又不容易被封

这些做法适用于生产环境,不管你用哪种方法都该遵守。

轮换住宅代理,不要用数据中心代理

Target 的 Akamai 会直接识别数据中心 IP 段。想长期稳定抓取,住宅代理几乎是必需品。价格差异很大——,大批量时会降到每 GB $3–4 左右。

建议每 50–100 次请求切换一次 IP;如果你的代理池支持每次请求切换,那更好。

用 curl_cffi 伪装 TLS 指纹

这是提升成功率最明显的一项改动。它可以直接替代 requests

1from curl_cffi import requests as cureq
2# 标准 requests —— 在受保护网站上的成功率约 12%
3# resp = requests.get(url, headers=headers)
4# curl_cffi —— 成功率约 92%
5resp = cureq.get(url, headers=headers, impersonate="chrome124")

在 GitHub 上有 8,200+ 星,支持从 chrome99chrome146 的多个 Chrome 版本,也支持 Safari、Edge 和移动端变体。在同步模式下,它比 tls_client

设置合理的请求节奏和请求头

  • 随机延迟: 每次请求之间间隔 2–7 秒,不要固定不变
  • User-Agent 轮换: 维护 5–10 个真实浏览器 UA,并轮流使用
  • 会话预热: 先访问 target.com 首页,再进入商品页,以建立 cookie
  • 请求头一致性: 你的 Sec-Ch-Ua 必须和你声称的浏览器版本一致;Sec-Ch-Ua-Platform 也必须匹配操作系统。不一致会非常显眼。
  • 会话持久化: 在同一会话内保持 cookie。 使用 48 小时稳定会话,并配合轮换住宅代理。

不想写代码?用 Thunderbit 抓 Target.com 更省事

说真的,Target.com 确实是最难程序化抓取的零售网站之一。JavaScript 渲染、Akamai 的 TLS 指纹识别、数据中心代理检测、ChromeDriver 版本问题——各种环节都可能出岔子。如果你是在学习 Python,这些都很值得练手;但如果你是为了实际工作拿到 Target 商品数据,投入产出往往不太划算。

如果你只是想拿到数据,而不想做一整个工程项目, 会自动帮你处理这些难点。

Thunderbit 如何应对 Target.com 的难题

Thunderbit 的 AI 网页爬虫直接运行在你的浏览器里,因此天然支持 JavaScript 渲染——不需要 Selenium 安装、不需要无头浏览器配置,也不用折腾 ChromeDriver 版本。浏览器本身就是爬虫。

操作流程如下:

  1. 安装 ,然后打开 Target 的商品页或搜索页
  2. 点击 “AI Suggest Fields” —— Thunderbit 会识别页面并自动建议列名(商品标题、价格、评分、图片 URL 等)
  3. 点击 “Scrape” —— 数据会在几秒内直接从渲染后的页面提取出来

不用配置代理。不用伪装 TLS 指纹。也不会再出现 None

抓取 Target 商品列表和详情页

多页抓取是最实用的部分。你可以先抓 Target 搜索结果页拿到商品列表,再用 Subpage Scraping 自动访问每个商品 URL,把详情页数据补充到表格中——例如描述、完整评论、规格等——无需手写分页逻辑,也不用管理浏览器会话。

还能直接导出到 Excel、Google Sheets、Airtable 或 Notion。没有 csv.writer 的样板代码,也没有文件编码问题。

自动化定时抓取 Target.com

如果你需要持续监控价格或库存,Thunderbit 的 Scheduled Scraper 可以让你用自然语言描述计划,比如“每周一上午 9 点”。不用 cron、不要服务器、也不用在 VPS 上让 Python 脚本常驻运行。对做竞品价格监控的电商团队尤其有用——已经在使用自动化价格抓取,而价格情报的平均 ROI 高达

什么时候该用哪种方法抓 Target.com

给你一个快速决策表:

This paragraph contains content that cannot be parsed and has been skipped.

如果你要搭建生产级数据管道,方法 3(Redsky API)在速度和稳定性上都最好。如果你只是做一次性研究,或者团队里没人懂 Python,Thunderbit 能帮你省下很多小时。而如果你正在学习网页抓取,按方法 1 → 方法 2 → 方法 3 的顺序推进,会是非常自然、也很有收获的成长路径。

抓取 Target.com 时的法律与伦理注意事项

这个部分值得简单说一下。Target 的 robots.txt 里大约有 120 多个 Disallow 路径,但值得注意的是,它并没有阻止 /p/(商品页)或 /c/(分类页)——也就是说,商品页和分类页是明确允许爬取的。购物车、账户和结账页面则被限制访问。

不过,Target 的服务条款确实禁止自动化访问。但由于 Redsky API 被 (Target 工程团队已确认),通过 API 进行数据收集的法律风险会更低。

你需要知道的几个法律判例:

  • (第九巡回法院,2022):抓取公开可访问数据不违反 CFAA
  • (2024):Meta 败诉,法院认定抓取公开数据不构成 CFAA 违规

如果是大规模商业抓取,建议先咨询律师。若是市场研究、比价或个人项目,并且数据是公开可访问的,那么法律上通常更站得住脚。无论如何,都要尊重限速,不要给 Target 服务器造成压力。

结论与要点总结

Target.com 的难度评级名副其实。最朴素的 Requests + BeautifulSoup 方案会失败,是因为 Target 通过 JavaScript 渲染商品数据,而且 Akamai 会在你收到响应之前就先识别你的 TLS 握手指纹。好在用对方法后,提取数据其实很直接。

三种方法按可靠性排序:

  1. Redsky API —— 速度最快、最稳定,适合批量数据,返回干净的 JSON。缺点是需要先通过 DevTools 逆向出 API 端点。
  2. Selenium / Playwright —— 能处理 JavaScript 渲染,可以拿到页面上的所有内容。速度较慢,但信息最完整。
  3. Requests + BeautifulSoup —— 只能处理静态 HTML 和嵌入式 __TGT_DATA__ JSON。速度快,但数据不完整。

最值得做的技术优化:

  • curl_cffi 替代标准 requests,反爬绕过能力可提升
  • 必须使用住宅代理——数据中心 IP 会被立即标记
  • 每次请求都带上 Sec-Fetch-* 请求头——少了就可能直接被封
  • 先访问首页做会话预热,会显著提升成功率

如果你的场景里 Python 不值得折腾,可以自动处理 JavaScript 渲染、反爬和数据导出。试试 ,看看你是不是几分钟就能拿到需要的数据,而不是花上几个小时。

想了解更多抓取教程和数据提取技巧,可以看看 或我们的

常见问题

只用 Python Requests 和 BeautifulSoup 能抓 Target.com 吗?

部分可以。你能从商品页的 __TGT_DATA__ 脚本标签里提取商品标题、URL 和一些嵌入式 JSON 数据。但搜索结果页上的价格、评分、评论和库存都是 JavaScript 渲染的,静态 HTTP 请求拿不到。要完整数据,请用 Selenium/Playwright,或者直接调用 Redsky API。

为什么我的 Target.com 爬虫拿到的价格总是 None?

Target 会在初始页面加载后再通过 JavaScript 加载价格数据。你使用 requests.get() 时,拿到的只是 JavaScript 执行前的 HTML 外壳,商品数据还没注入到 DOM 里,所以价格元素根本不存在。你可以换成能渲染 JavaScript 的无头浏览器(Selenium 或 Playwright),也可以直接调用 Redsky API 获取 JSON 数据,或者使用像 这样的工具,从浏览器渲染后的页面中抓取。

抓取 Target.com 合法吗?

根据当前美国判例法,抓取公开可访问的数据通常是允许的(hiQ v. LinkedIn、Meta v. Bright Data)。Target 的 robots.txt 也允许抓取商品页和分类页。不过,Target 的服务条款禁止自动化访问,所以法律上存在一定灰色地带。用于市场研究、价格比较等公开数据场景时,通常较为稳妥。若涉及大规模商业运营,建议先咨询律师。

Target 的 Redsky API 是什么,怎么访问?

Redsky 是 Target 内部用于支撑前端商品数据的 API。它不是那种你注册后能拿到文档和独立 API key 的公开 API,而是 React 页面调用的后端接口。你可以通过打开 Chrome DevTools,切到 Network 标签页并筛选 XHR/Fetch 请求,查找发往 redsky.target.com 的请求来发现它。API key 会作为查询参数嵌在请求 URL 里。Target 工程团队已经确认,这个 API 是有意对前端公开的。

如何避免抓 Target.com 时被封?

最有效的一项改动,是用 curl_cffi 代替标准 Python requests 来伪装浏览器 TLS 指纹——仅这一项就能把成功率从 。除此之外,还要使用住宅代理(不要用数据中心代理)、轮换 User-Agent、每次请求间隔随机 2–7 秒、补齐所有 Sec-Fetch-* 请求头,并先访问首页预热会话。或者直接用像 这样的工具,让它自动处理反爬机制,无需手动配置。

了解更多

目录

试试 Thunderbit

只需 2 次点击即可抓取潜在客户和其他数据,由 AI 驱动。

获取 Thunderbit 免费使用
使用 AI 提取数据
轻松将数据转移到 Google Sheets、Airtable 或 Notion
Chrome Store Rating
PRODUCT HUNT#1 Product of the Week