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 handshake,甚至在任何 HTML 傳輸前,就把 Python 的 requests 標記掉。這部分我們等一下再深入說。
為什麼 Target.com 對 Python 抓取這麼難
Target 不只是「一個用了 JavaScript 的網站」而已。它其實是一套多層防禦系統——理解每一層,才知道該選哪種抓取方式。
由 JavaScript 渲染的商品資料
Target.com 是用 React 建置的。當你在真實瀏覽器中打開商品頁或搜尋頁時,流程大致如下:
- 伺服器先送出最小化的 HTML 外殼
- JavaScript bundle 載入並執行
- 前端呼叫 Target 內部的 Redsky API
- 商品資料(價格、評分、圖片、庫存)才渲染到 DOM 中
如果你跳過第 2–4 步——而這正是 requests.get() 做的事——你拿到的就只是空頁面。,結果顯示靜態 HTTP 請求大約只能抓到 Target 30% 左右的可用資料。剩下 70% 必須靠 JavaScript 執行或 API 存取。
搜尋結果頁更麻煩。初始 HTML 裡只會出現少數幾個商品,其他的要捲動頁面才會載入。
Target 的反機器人機制:不只是「用代理伺服器」這麼簡單
大多數抓取教學談到反機器人機制時,都只會含糊地說一句「換代理伺服器就好」。但 Target 的防護值得講得更精確一些。
TLS 指紋辨識(最重要的一層)。 在 HTTPS handshake 過程中,你的客戶端會送出一個「Client Hello」封包,裡面包含 TLS 版本、cipher suites、擴充資訊與橢圓曲線等細節。這些資訊會被雜湊成 JA3 指紋。Python 的 requests 會產生一個——8d9f7747675e24454cd9b7ed35c58707——反機器人資料庫會立刻把它標記出來。Chrome 會傳送 16 個按特定順序排列的 cipher suites,還帶有 GREASE 值;Python 則會以不同於瀏覽器的順序送出 60 多個。封鎖甚至會在任何 HTTP 內容交換之前就發生。
IP 信譽評分。 Akamai 會把 IP 分成不同信任等級。資料中心 IP 在中,會被賦予「顯著的負向信任分數,因為它們很可能被機器人使用。」住宅型 IP 則會拿到正向分數。針對 Target 來說,資料中心 IP 段通常會直接被標記。
JavaScript 指紋辨識。 Akamai 會注入 JavaScript,蒐集你的 JS 引擎規格、硬體能力、作業系統資料、字型、外掛,以及行為資料(打字速度、滑鼠移動、點擊時機)。這些資訊會生成 _abck cookie——一個有狀態的指紋 token。沒有有效的 _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 擷取商品標題與連結。
第 1 步:建立 Python 環境
先建立專案資料夾並安裝套件:
1mkdir target-scraper && cd target-scraper
2python -m venv venv
3source venv/bin/activate # On Windows: venv\Scripts\activate
4pip install requests beautifulsoup4 curl_cffi
這裡建議用 curl_cffi 取代標準 requests。它可以偽裝瀏覽器的 TLS 指紋,而這正是避免在 Target 被擋下來的最大關鍵。根據,curl_cffi 的反機器人繞過成功率可達 ,而標準 requests 只有 ——提升整整 15 倍。
第 2 步:抓取 Target 搜尋結果
Target 的搜尋網址格式很簡單: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你會拿到商品名稱和網址。價格呢?大多不會出現在這個 HTML 裡。這很正常。
10### 第 3 步:從商品頁擷取內嵌 JSON 資料
11單一商品頁會在 `__TGT_DATA__` script 標籤中嵌入更完整的資料:
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### 第 4 步:處理分頁
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)) # 禮貌一點
第 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)
你能拿到的資料: 商品標題、網址、描述與內嵌中繼資料。你不一定能穩定拿到的資料: 搜尋結果頁的動態價格與評分。如果你需要這些,就得用方法 2 或 3。
方法 2:用 Selenium 或 Playwright 抓 Target.com
Headless 瀏覽器可以渲染 JavaScript、載入動態內容,並模擬真實使用者行為。這個方法能抓到價格、評分和評論。
如果要比較 Selenium 和 Playwright:根據 ——2026 年是 ——而且基準測試顯示它快了 (20 頁只要 11 秒,Selenium 則要 28 秒)。我這裡先用 Selenium 示範,因為它的社群和教學更多;但如果你是從零開始,Playwright 其實更值得選。
第 1 步:安裝 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)
第 2 步:載入 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# 等待商品卡片渲染完成(explicit wait 比 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 毫秒輪詢一次,直到元素出現或逾時。
第 3 步:滾動頁面載入更多商品
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–300px,模擬真人操作。
第 4 步:從渲染後頁面擷取商品資料
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" |
第 5 步:抓商品評論(加碼)
進入單一商品頁,捲動到評論區,再把評論資料抓出來:
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 多個欄位,涵蓋價格、評分、評論、圖片、庫存、配送、規格和變體。若你要做大量商品資料抓取,這無疑是最快也最穩定的方法。
第 1 步:用 Chrome DevTools 找出 Redsky API
很多教學會直接跳過這一步。其實你可以自己找出 API:
- 在 Chrome 打開任一 Target 商品頁
- 開啟 DevTools(F12)→ Network 分頁
- 用 Fetch/XHR 篩選
- 重新載入頁面
- 找
redsky.target.com或redsky.a]target.com的請求 - 點進去看 Request URL 與 Headers
你會看到像這樣的網址:
1https://redsky.target.com/redsky_aggregations/v1/web/pdp_fulfillment_v1?key=9f36aeafbe60771e321a7cc95a78140772ab3e96&tcin=12345678&store_id=2148&zip=55401
關鍵參數如下:
key— API 金鑰(固定,不會一直輪替;不同端點會用不同 key)tcin— Target.com 商品編號(8 位數商品 ID)store_id— Target 門市位置zip— 取得配送資訊所需的郵遞區號
API key 就在 request URL 裡,不需要另外申請。
第 2 步:直接用 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,回應結構清楚、速度也快。
第 3 步:透過 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 取得。
第 4 步:用並行請求擴大規模
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 個 threads,加上 2 到 5 秒的隨機延遲。Target 的速率限制大約在每個 IP 每分鐘 。
關於 Redsky API 的重要注意事項
在你把它做成正式 production pipeline 前,先注意幾件事:
- API key 是固定的,但與端點綁定。 不同 Redsky 端點會用不同 key。雖然它們不常變,但 Target 隨時可能調整。
- 這是未正式文件化的內部 API。 Target 工程團隊曾,因此法律風險相對較低,但它仍不是有 SLA 的正式公開 API。
- 商品變體(顏色、尺寸)各自有不同 TCIN。 你必須逐一查詢每個變體。
- 缺少
Sec-Fetch-*headers 幾乎會立刻被擋。 這是很常見的坑——務必帶上Sec-Fetch-Site、Sec-Fetch-Mode和Sec-Fetch-Dest。
如何大規模抓 Target.com,又不那麼容易被封鎖
這些做法適用於生產級規模,不論你用哪一種方法。
使用住宅型代理,不要用資料中心代理
Target 的 Akamai 會直接辨識資料中心 IP。若要持續抓取,住宅型代理幾乎是必需品。價格落差很大——,,大量使用時可降到每 GB $3–4。
建議每 50–100 次請求換一次 IP;如果你的 proxy pool 支援每次請求都輪換,那更好。
用 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")
[curl_cffi](https://github.com/yifeikong/curl_cffi) 在 GitHub 上有 8,200+ 星,支援從 chrome99 到 chrome146 的 Chrome 版本,也支援 Safari、Edge 和行動版變體。同步模式下,它的速度比 tls_client 快 。
設定合理的請求節奏與標頭
- 隨機延遲: 每次請求間隔 2–7 秒,不要固定間隔(隨機性很重要)
- User-Agent 輪替: 準備 5–10 組真實瀏覽器的 User-Agent 文字並輪替使用
- Session 預熱: 先造訪
target.com首頁,再抓商品頁,先建立 cookies - 標頭一致性: 你的
Sec-Ch-Ua必須和你宣稱的瀏覽器版本一致,Sec-Ch-Ua-Platform也要符合你假裝的作業系統。不一致很容易被抓包 - Session 持續性: 同一 session 內維持 cookies。根據 ,搭配輪換住宅代理,可讓 session 穩定維持 48 小時。
不寫程式也能抓 Target.com:用 Thunderbit 直接處理
說真的,Target.com 是目前最難用程式自動抓取的零售網站之一。JavaScript 渲染、Akamai TLS 指紋辨識、資料中心代理偵測、ChromeDriver 版本問題——整個流程牽涉很多環節。如果你是想學 Python,這當然是很好的練習;但如果你是要真的拿 Target 商品資料來工作,投入與產出常常不太划算。
如果你只是想拿到資料,不想做工程專案, 可以幫你自動處理那些最麻煩的部分。
Thunderbit 如何處理 Target.com 的難題
Thunderbit 的 AI 網頁爬蟲直接在你的瀏覽器中執行,所以它自然就能渲染 JavaScript——不用設定 Selenium,不用配置 headless browser,也不用處理 ChromeDriver 版本。瀏覽器本身就是爬蟲。
流程如下:
- 安裝 ,然後前往 Target 商品頁或搜尋頁
- 點擊「AI Suggest Fields」——Thunderbit 會讀取頁面並建議欄位名稱(商品標題、價格、評分、圖片網址等)
- 點擊「Scrape」——資料會在幾秒內直接從渲染後的頁面擷取完成
不用設定代理。也不用偽裝 TLS 指紋。更不會拿到 None。
抓 Target 商品列表與詳細頁
多頁抓取才是真正精彩的地方。你可以先抓 Target 搜尋結果頁,取得商品清單,再用 Subpage Scraping 自動逐一進入每個商品網址,把詳細頁資料補進表格中——像是商品描述、完整評論、規格等,完全不用自己寫分頁程式,也不用管理瀏覽器 session。
還可以直接匯出到 Excel、Google Sheets、Airtable 或 Notion。不需要 csv.writer 的樣板程式,也不用煩惱編碼問題。
自動化定期抓取 Target.com
如果你需要長期監控價格或庫存,Thunderbit 的 Scheduled Scraper 可以讓你用自然語言描述排程(例如「每週一上午 9 點」)。不用 cron job、不用架伺服器,也不用在 VPS 上硬撐 Python 腳本。對於追蹤的電商團隊尤其實用——現在都在使用自動化價格抓取,而價格情報的平均投報率高達 。
用 Python 抓 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 handshake。不過只要選對方法,資料擷取其實沒那麼難。
三種方法的可靠度排序:
- Redsky API — 速度最快、批次資料最穩,回傳乾淨 JSON。缺點是得先透過 DevTools 逆向找 API 端點。
- Selenium / Playwright — 能處理 JavaScript 渲染,可抓到頁面上的所有內容。速度較慢,但資訊最完整。
- Requests + BeautifulSoup — 只能處理靜態 HTML 和內嵌的
__TGT_DATA__JSON。速度快,但資料不完整。
最有價值的技術優化:
- 用
curl_cffi取代標準requests,反機器人繞過效果可提升 - 必須使用住宅型代理——資料中心 IP 會立刻被標記
- 每次請求都要帶上
Sec-Fetch-*headers——少了就很容易瞬間被擋 - 先訪問首頁做 session 預熱,成功率會明顯提升
如果你的使用場景不值得花這些功夫, 可以自動處理 JavaScript 渲染、反機器人機制與資料匯出。你可以試試 ,看看能不能在幾分鐘內就拿到你要的資料,而不是花上好幾個小時。
想看更多抓取教學與資料擷取技巧,歡迎閱讀 或追蹤我們的 。
常見問題
我可以只用 Python Requests 和 BeautifulSoup 抓 Target.com 嗎?
可以,但只能部分做到。你可以從商品頁的 __TGT_DATA__ script 標籤中抓到商品標題、網址與部分內嵌 JSON 資料。但搜尋結果頁上的價格、評分、評論與庫存資訊都是由 JavaScript 渲染的,靜態 HTTP 請求看不到。若要完整資料,請用 Selenium/Playwright 或 Redsky API。
為什麼我的 Target.com 爬蟲在價格欄位總是回傳 None?
因為 Target 會在初始頁面載入後才用 JavaScript 載入價格資料。當你使用 requests.get() 時,拿到的是 JavaScript 執行之前的 HTML 外殼,商品資料還沒被注入 DOM,所以價格元素根本不存在。你可以改用能渲染 JavaScript 的 headless browser(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 會直接嵌在 request URL 的 query parameter 裡。Target 工程團隊已確認這個 API 是刻意設計成對外可見的。
要怎麼避免抓 Target.com 時被封鎖?
最有影響力的一項改變,是把標準 Python requests 換成 curl_cffi,用來偽裝瀏覽器的 TLS 指紋——這一項就能把成功率從 。除此之外:使用住宅型代理(不是資料中心代理)、輪替 User-Agent、每次請求間加上 2–7 秒隨機延遲、補齊所有 Sec-Fetch-* headers,並先訪問首頁做 session 預熱。或者,直接用像 這種會自動處理反機器人機制的工具,不需要任何設定。
延伸閱讀